From 4cc1f9d3c845f1f8781f0c021ce63ef222a1cc46 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 05:16:30 +0000 Subject: [PATCH 0001/1065] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E4=B8=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2035 18ba2127-5a84-46d4-baec-3457e417f034 --- _tests/AllTest.php | 24 + _tests/BaseTestCase.php | 36 + ...about\345\221\275\344\273\244\350\241\214" | 53 ++ _tests/bootstrap.php | 10 + _tests/component/AllComponentTest.php | 40 + .../component/cache/WindCacheFactoryTest.php | 42 + .../cache/strategy/WindFileCacheTest.php | 92 ++ _tests/component/collections/WindListTest.php | 161 ++++ .../component/collections/WindQueueTest.php | 94 ++ .../collections/WindSortedListTest.php | 146 +++ .../component/collections/WindStackTest.php | 88 ++ _tests/component/db/AllDBTest.php | 29 + .../db/WindConnectionManagerTest.php | 99 ++ .../db/drivers/mssql/WindMsSqlBuilderTest.php | 349 +++++++ .../db/drivers/mssql/WindMsSqlTest.php | 126 +++ .../db/drivers/mysql/WindMySqlBuilderTest.php | 354 +++++++ .../db/drivers/mysql/WindMySqlTest.php | 126 +++ _tests/component/form/AllFormTest.php | 23 + _tests/component/form/WindActionFormTest.php | 62 ++ _tests/component/form/WindFormFilterTest.php | 55 ++ _tests/component/format/AllFormatTest.php | 25 + _tests/component/log/AllLogTest.php | 23 + _tests/component/log/WindDebugTest.php | 91 ++ _tests/component/log/WindLoggerTest.php | 60 ++ _tests/component/mail/AllMailTest.php | 32 + _tests/component/mail/WindMailTest.php | 189 ++++ .../component/mail/protocol/WindImapTest.php | 256 +++++ .../component/mail/protocol/WindPop3Test.php | 102 ++ .../component/mail/protocol/WindSmtpTest.php | 58 ++ .../mail/protocol/WindSocketTest.php | 74 ++ .../component/mail/send/WindSmtpSendTest.php | 53 ++ _tests/component/parser/AllParserTest.php | 25 + _tests/component/parser/WindIniParserTest.php | 128 +++ .../parser/WindPropertiesParserTest.php | 127 +++ _tests/component/parser/WindXmlParserTest.php | 72 ++ .../component/security/WindSecurityTest.php | 221 +++++ _tests/component/utility/WindPackTest.php | 74 ++ _tests/component/utility/WindSecurityTest.php | 248 +++++ .../component/utility/WindStringGBKTest.php | 65 ++ .../component/utility/WindStringUTF8Test.php | 86 ++ .../component/utility/WindValidatorTest.php | 179 ++++ .../component/utility/date/WindDateTest.php | 171 ++++ .../utility/date/WindGeneralDateTest.php | 311 ++++++ .../component/validator/WindValidatorTest.php | 171 ++++ _tests/core/AllCoreTest.php | 52 + _tests/core/WindBaseTest.php | 121 +++ _tests/core/WindErrorHandleTest.php | 122 +++ _tests/core/WindErrorMessageTest.php | 95 ++ _tests/core/WindLayoutTest.php | 66 ++ _tests/core/WindMessageTest.php | 205 ++++ _tests/core/WindUrlManagerTest.php | 34 + _tests/core/config/AllConfigTest.php | 22 + _tests/core/config/WindSystemConfigTest.php | 154 +++ .../config/parser/WindConfigParserTest.php | 136 +++ _tests/core/exception/AllExceptionTest.php | 23 + _tests/core/exception/WindExceptionTest.php | 67 ++ .../core/exception/WindSqlExceptionTest.php | 35 + _tests/core/factory/AllFactoryTest.php | 27 + .../core/factory/WindClassDefinitionTest.php | 141 +++ _tests/core/factory/WindClassProxyTest.php | 100 ++ .../core/factory/WindComponentFactoryTest.php | 61 ++ _tests/core/factory/WindFactoryTest.php | 57 ++ _tests/core/filter/AllFilterTest.php | 21 + _tests/core/filter/WindFilterChainTest.php | 80 ++ _tests/core/request/WindHttpRequestTest.php | 476 ++++++++++ _tests/core/response/WindHttpResponseTest.php | 221 +++++ _tests/core/router/AllRouterTest.php | 20 + _tests/core/router/WindUrlBasedRouterTest.php | 117 +++ _tests/core/viewer/AllViewerTest.php | 23 + _tests/core/viewer/WindViewTest.php | 100 ++ _tests/core/viewer/WindViewerTest.php | 94 ++ _tests/core/web/AllWebTest.php | 21 + _tests/core/web/WindForwardTest.php | 101 ++ _tests/data/ForWindClassDefinition.php | 38 + _tests/data/ForWindClassProxy.php | 81 ++ _tests/data/ForWindFilter.php | 24 + _tests/data/TestForm.php | 81 ++ _tests/data/WindIniParserTest.ini | 31 + .../data/WindPropertiesParserTest.properties | 22 + _tests/data/WindXmlParserTest.xml | 51 + _tests/data/classes_config.xml | 19 + _tests/data/component_config.xml | 23 + _tests/data/config.php | 95 ++ _tests/data/db_config.php | 31 + _tests/data/formConfig.xml | 8 + _tests/data/layout.htm | 3 + _tests/data/pageLayout.htm | 1 + _tests/data/pageTemplate.htm | 1 + _tests/data/test_config.ini | 2 + _tests/data/test_config.php | 18 + _tests/data/test_config.properties | 3 + _tests/data/test_config.xml | 13 + _tests/readme | 87 ++ _tests/windTest.bat | 2 + _tests/windTest.sh | 18 + .../helloworld/controller/IndexController.php | 19 + demos/helloworld/index.php | 7 + docs/configtemplate/compiler_config.xml | 8 + docs/configtemplate/db_config.xml | 15 + docs/configtemplate/dbcache_config.xml | 16 + docs/configtemplate/filecache_config.xml | 14 + docs/configtemplate/ini/compiler_config.ini | 9 + docs/configtemplate/ini/db_config.ini | 10 + docs/configtemplate/ini/dbcache_config.ini | 17 + docs/configtemplate/ini/filecache_config.ini | 12 + docs/configtemplate/ini/memcache.ini | 21 + docs/configtemplate/ini/wind_config.ini | 31 + docs/configtemplate/memcache_config.xml | 21 + docs/configtemplate/php/compiler_config.php | 23 + docs/configtemplate/php/db_config.php | 23 + docs/configtemplate/php/dbcache_config.php | 25 + docs/configtemplate/php/filecache_config.php | 23 + docs/configtemplate/php/memcache.php | 23 + docs/configtemplate/php/wind_config.php | 69 ++ .../properties/db_config.properties | 10 + .../properties/dbcache_config.properties | 17 + .../properties/filecache_config.properties | 12 + .../properties/memcache.properties | 21 + .../properties/viewTemplateConfig.properties | 9 + .../properties/wind_config.properties | 31 + docs/configtemplate/wind_config.xml | 50 + wind/Wind.php | 10 + wind/WindBase.php | 430 +++++++++ wind/component/cache/AbstractWindCache.php | 237 +++++ wind/component/cache/IWindCacheDependency.php | 43 + .../cache/dependency/WindCacheDependency.php | 88 ++ .../dependency/WindSqlCacheDependency.php | 19 + wind/component/cache/operator/WindApc.php | 65 ++ .../cache/operator/WindEaccelerator.php | 118 +++ .../component/cache/operator/WindMemcache.php | 141 +++ .../component/cache/operator/WindWinCache.php | 88 ++ wind/component/cache/operator/WindXCache.php | 66 ++ .../cache/operator/WindZendCache.php | 55 ++ .../component/cache/strategy/WindCacheApc.php | 55 ++ wind/component/cache/strategy/WindCacheDb.php | 251 +++++ .../cache/strategy/WindCacheEaccelerator.php | 58 ++ .../cache/strategy/WindCacheFile.php | 187 ++++ .../component/cache/strategy/WindCacheMem.php | 114 +++ .../component/cache/strategy/WindCacheWin.php | 54 ++ .../cache/strategy/WindCacheXCache.php | 55 ++ .../cache/strategy/WindCacheZend.php | 58 ++ wind/component/collections/WindList.php | 280 ++++++ wind/component/collections/WindQueue.php | 134 +++ wind/component/collections/WindSortedList.php | 333 +++++++ wind/component/collections/WindStack.php | 125 +++ wind/component/dao/AbstractWindDao.php | 93 ++ wind/component/dao/AbstractWindDaoFactory.php | 141 +++ .../dao/listener/WindDaoCacheListener.php | 55 ++ wind/component/db/WindConnection.php | 231 +++++ wind/component/db/WindConnectionManager.php | 18 + wind/component/db/WindResultSet.php | 103 ++ wind/component/db/WindSqlStatement.php | 199 ++++ wind/component/db/drivers/mssql/WindMsSql.php | 159 ++++ .../db/drivers/mssql/WindMsSqlBuilder.php | 93 ++ wind/component/db/drivers/mysql/WindMySql.php | 207 ++++ .../db/drivers/mysql/WindMySqlBuilder.php | 99 ++ .../db/exception/WindDbException.php | 123 +++ .../db/mysql/WindMysqlPdoAdapter.php | 15 + wind/component/http/cookie/WindCookie.php | 94 ++ .../http/cookie/WindCookieObject.php | 185 ++++ .../http/session/AbstractWindUserSession.php | 57 ++ wind/component/http/session/WindDbSession.php | 42 + wind/component/http/session/WindSession.php | 370 ++++++++ .../http/transfer/AbstractWindHttp.php | 280 ++++++ wind/component/http/transfer/WindHttpCurl.php | 147 +++ .../http/transfer/WindHttpSocket.php | 166 ++++ .../http/transfer/WindHttpStream.php | 178 ++++ wind/component/log/WindDebug.php | 175 ++++ wind/component/log/WindLogger.php | 332 +++++++ wind/component/mail/WindMail.php | 898 ++++++++++++++++++ wind/component/mail/protocol/WindImap.php | 663 +++++++++++++ wind/component/mail/protocol/WindPop3.php | 260 +++++ wind/component/mail/protocol/WindSmtp.php | 211 ++++ wind/component/mail/protocol/WindSocket.php | 121 +++ wind/component/mail/sender/IWindSendMail.php | 15 + wind/component/mail/sender/WindPhpMail.php | 34 + wind/component/mail/sender/WindSendMail.php | 85 ++ wind/component/mail/sender/WindSmtpMail.php | 92 ++ wind/component/parser/WindIniParser.php | 147 +++ .../component/parser/WindPropertiesParser.php | 210 ++++ wind/component/parser/WindXmlParser.php | 106 +++ wind/component/upload/AbstractWindUpload.php | 23 + wind/component/upload/WindCurlUpload.php | 16 + wind/component/upload/WindFormUpload.php | 24 + wind/component/utility/WindArray.php | 83 ++ wind/component/utility/WindFile.php | 255 +++++ wind/component/utility/WindMimeTypes.php | 243 +++++ wind/component/utility/WindPack.php | 397 ++++++++ wind/component/utility/WindSecurity.php | 262 +++++ wind/component/utility/WindString.php | 234 +++++ wind/component/utility/WindUtility.php | 50 + wind/component/utility/WindValidator.php | 344 +++++++ wind/component/utility/date/WindDate.php | 272 ++++++ .../utility/date/WindGeneralDate.php | 248 +++++ wind/component/utility/json/WindDecoder.php | 235 +++++ wind/component/utility/json/WindEncoder.php | 202 ++++ wind/config/components_config.php | 26 + wind/config/components_config.xml | 82 ++ wind/core/AbstractWindServer.php | 159 ++++ wind/core/WindComponentModule.php | 101 ++ wind/core/WindEnableValidateModule.php | 125 +++ wind/core/WindHelper.php | 32 + wind/core/WindModule.php | 128 +++ wind/core/config/WindConfig.php | 151 +++ wind/core/config/WindSystemConfig.php | 213 +++++ wind/core/config/parser/IWindConfigParser.php | 27 + wind/core/config/parser/WindConfigParser.php | 206 ++++ wind/core/exception/WindActionException.php | 52 + wind/core/exception/WindCacheException.php | 19 + wind/core/exception/WindDaoException.php | 27 + wind/core/exception/WindException.php | 108 +++ wind/core/exception/WindFinalException.php | 14 + wind/core/exception/WindSqlException.php | 119 +++ wind/core/exception/WindViewException.php | 29 + wind/core/factory/IWindFactory.php | 39 + wind/core/factory/WindClassDefinition.php | 440 +++++++++ wind/core/factory/WindComponentDefinition.php | 156 +++ wind/core/factory/WindComponentFactory.php | 18 + wind/core/factory/WindFactory.php | 141 +++ wind/core/factory/proxy/IWindClassProxy.php | 53 ++ wind/core/factory/proxy/WindClassProxy.php | 257 +++++ wind/core/filter/WindFilter.php | 32 + wind/core/filter/WindFilterChain.php | 72 ++ wind/core/filter/WindHandlerInterceptor.php | 63 ++ .../filter/WindHandlerInterceptorChain.php | 77 ++ wind/core/request/IWindRequest.php | 25 + wind/core/request/WindHttpRequest.php | 638 +++++++++++++ wind/core/response/IWindResponse.php | 11 + wind/core/response/WindHttpResponse.php | 522 ++++++++++ wind/core/router/AbstractWindRouter.php | 134 +++ wind/core/router/WindUrlBasedRouter.php | 100 ++ .../viewer/AbstractWindTemplateCompiler.php | 126 +++ wind/core/viewer/AbstractWindViewTemplate.php | 114 +++ wind/core/viewer/IWindViewerResolver.php | 33 + wind/core/viewer/WindLayout.php | 67 ++ wind/core/viewer/WindView.php | 226 +++++ wind/core/viewer/WindViewerResolver.php | 139 +++ .../compiler/WindTemplateCompilerAction.php | 53 ++ .../WindTemplateCompilerComponent.php | 52 + .../compiler/WindTemplateCompilerEcho.php | 39 + .../compiler/WindTemplateCompilerInternal.php | 27 + .../compiler/WindTemplateCompilerPage.php | 87 ++ .../compiler/WindTemplateCompilerScript.php | 36 + .../compiler/WindTemplateCompilerTemplate.php | 55 ++ .../core/viewer/compiler/WindViewTemplate.php | 176 ++++ .../viewer/listener/WindViewCacheListener.php | 41 + wind/core/web/IWindApplication.php | 27 + wind/core/web/IWindErrorMessage.php | 36 + wind/core/web/WindAction.php | 274 ++++++ wind/core/web/WindController.php | 62 ++ wind/core/web/WindDispatcher.php | 126 +++ wind/core/web/WindErrorHandler.php | 154 +++ wind/core/web/WindErrorMessage.php | 92 ++ wind/core/web/WindFormController.php | 56 ++ wind/core/web/WindForward.php | 201 ++++ wind/core/web/WindFrontController.php | 172 ++++ wind/core/web/WindUrlHelper.php | 357 +++++++ wind/core/web/WindWebApplication.php | 177 ++++ wind/core/web/filter/WindLoggerFilter.php | 42 + wind/core/web/filter/WindUrlFilter.php | 33 + wind/core/web/listener/WindFormListener.php | 73 ++ wind/core/web/listener/WindLoggerListener.php | 119 +++ .../web/listener/WindValidateListener.php | 93 ++ wind/readme | 8 + 264 files changed, 28955 insertions(+) create mode 100644 _tests/AllTest.php create mode 100644 _tests/BaseTestCase.php create mode 100644 "_tests/about\345\221\275\344\273\244\350\241\214" create mode 100644 _tests/bootstrap.php create mode 100644 _tests/component/AllComponentTest.php create mode 100644 _tests/component/cache/WindCacheFactoryTest.php create mode 100644 _tests/component/cache/strategy/WindFileCacheTest.php create mode 100644 _tests/component/collections/WindListTest.php create mode 100644 _tests/component/collections/WindQueueTest.php create mode 100644 _tests/component/collections/WindSortedListTest.php create mode 100644 _tests/component/collections/WindStackTest.php create mode 100644 _tests/component/db/AllDBTest.php create mode 100644 _tests/component/db/WindConnectionManagerTest.php create mode 100644 _tests/component/db/drivers/mssql/WindMsSqlBuilderTest.php create mode 100644 _tests/component/db/drivers/mssql/WindMsSqlTest.php create mode 100644 _tests/component/db/drivers/mysql/WindMySqlBuilderTest.php create mode 100644 _tests/component/db/drivers/mysql/WindMySqlTest.php create mode 100644 _tests/component/form/AllFormTest.php create mode 100644 _tests/component/form/WindActionFormTest.php create mode 100644 _tests/component/form/WindFormFilterTest.php create mode 100644 _tests/component/format/AllFormatTest.php create mode 100644 _tests/component/log/AllLogTest.php create mode 100644 _tests/component/log/WindDebugTest.php create mode 100644 _tests/component/log/WindLoggerTest.php create mode 100644 _tests/component/mail/AllMailTest.php create mode 100644 _tests/component/mail/WindMailTest.php create mode 100644 _tests/component/mail/protocol/WindImapTest.php create mode 100644 _tests/component/mail/protocol/WindPop3Test.php create mode 100644 _tests/component/mail/protocol/WindSmtpTest.php create mode 100644 _tests/component/mail/protocol/WindSocketTest.php create mode 100644 _tests/component/mail/send/WindSmtpSendTest.php create mode 100644 _tests/component/parser/AllParserTest.php create mode 100644 _tests/component/parser/WindIniParserTest.php create mode 100644 _tests/component/parser/WindPropertiesParserTest.php create mode 100644 _tests/component/parser/WindXmlParserTest.php create mode 100644 _tests/component/security/WindSecurityTest.php create mode 100644 _tests/component/utility/WindPackTest.php create mode 100644 _tests/component/utility/WindSecurityTest.php create mode 100644 _tests/component/utility/WindStringGBKTest.php create mode 100644 _tests/component/utility/WindStringUTF8Test.php create mode 100644 _tests/component/utility/WindValidatorTest.php create mode 100644 _tests/component/utility/date/WindDateTest.php create mode 100644 _tests/component/utility/date/WindGeneralDateTest.php create mode 100644 _tests/component/validator/WindValidatorTest.php create mode 100644 _tests/core/AllCoreTest.php create mode 100644 _tests/core/WindBaseTest.php create mode 100644 _tests/core/WindErrorHandleTest.php create mode 100644 _tests/core/WindErrorMessageTest.php create mode 100644 _tests/core/WindLayoutTest.php create mode 100644 _tests/core/WindMessageTest.php create mode 100644 _tests/core/WindUrlManagerTest.php create mode 100644 _tests/core/config/AllConfigTest.php create mode 100644 _tests/core/config/WindSystemConfigTest.php create mode 100644 _tests/core/config/parser/WindConfigParserTest.php create mode 100644 _tests/core/exception/AllExceptionTest.php create mode 100644 _tests/core/exception/WindExceptionTest.php create mode 100644 _tests/core/exception/WindSqlExceptionTest.php create mode 100644 _tests/core/factory/AllFactoryTest.php create mode 100644 _tests/core/factory/WindClassDefinitionTest.php create mode 100644 _tests/core/factory/WindClassProxyTest.php create mode 100644 _tests/core/factory/WindComponentFactoryTest.php create mode 100644 _tests/core/factory/WindFactoryTest.php create mode 100644 _tests/core/filter/AllFilterTest.php create mode 100644 _tests/core/filter/WindFilterChainTest.php create mode 100644 _tests/core/request/WindHttpRequestTest.php create mode 100644 _tests/core/response/WindHttpResponseTest.php create mode 100644 _tests/core/router/AllRouterTest.php create mode 100644 _tests/core/router/WindUrlBasedRouterTest.php create mode 100644 _tests/core/viewer/AllViewerTest.php create mode 100644 _tests/core/viewer/WindViewTest.php create mode 100644 _tests/core/viewer/WindViewerTest.php create mode 100644 _tests/core/web/AllWebTest.php create mode 100644 _tests/core/web/WindForwardTest.php create mode 100644 _tests/data/ForWindClassDefinition.php create mode 100644 _tests/data/ForWindClassProxy.php create mode 100644 _tests/data/ForWindFilter.php create mode 100644 _tests/data/TestForm.php create mode 100644 _tests/data/WindIniParserTest.ini create mode 100644 _tests/data/WindPropertiesParserTest.properties create mode 100644 _tests/data/WindXmlParserTest.xml create mode 100644 _tests/data/classes_config.xml create mode 100644 _tests/data/component_config.xml create mode 100644 _tests/data/config.php create mode 100644 _tests/data/db_config.php create mode 100644 _tests/data/formConfig.xml create mode 100644 _tests/data/layout.htm create mode 100644 _tests/data/pageLayout.htm create mode 100644 _tests/data/pageTemplate.htm create mode 100644 _tests/data/test_config.ini create mode 100644 _tests/data/test_config.php create mode 100644 _tests/data/test_config.properties create mode 100644 _tests/data/test_config.xml create mode 100644 _tests/readme create mode 100644 _tests/windTest.bat create mode 100644 _tests/windTest.sh create mode 100644 demos/helloworld/controller/IndexController.php create mode 100644 demos/helloworld/index.php create mode 100644 docs/configtemplate/compiler_config.xml create mode 100644 docs/configtemplate/db_config.xml create mode 100644 docs/configtemplate/dbcache_config.xml create mode 100644 docs/configtemplate/filecache_config.xml create mode 100644 docs/configtemplate/ini/compiler_config.ini create mode 100644 docs/configtemplate/ini/db_config.ini create mode 100644 docs/configtemplate/ini/dbcache_config.ini create mode 100644 docs/configtemplate/ini/filecache_config.ini create mode 100644 docs/configtemplate/ini/memcache.ini create mode 100644 docs/configtemplate/ini/wind_config.ini create mode 100644 docs/configtemplate/memcache_config.xml create mode 100644 docs/configtemplate/php/compiler_config.php create mode 100644 docs/configtemplate/php/db_config.php create mode 100644 docs/configtemplate/php/dbcache_config.php create mode 100644 docs/configtemplate/php/filecache_config.php create mode 100644 docs/configtemplate/php/memcache.php create mode 100644 docs/configtemplate/php/wind_config.php create mode 100644 docs/configtemplate/properties/db_config.properties create mode 100644 docs/configtemplate/properties/dbcache_config.properties create mode 100644 docs/configtemplate/properties/filecache_config.properties create mode 100644 docs/configtemplate/properties/memcache.properties create mode 100644 docs/configtemplate/properties/viewTemplateConfig.properties create mode 100644 docs/configtemplate/properties/wind_config.properties create mode 100644 docs/configtemplate/wind_config.xml create mode 100644 wind/Wind.php create mode 100644 wind/WindBase.php create mode 100644 wind/component/cache/AbstractWindCache.php create mode 100644 wind/component/cache/IWindCacheDependency.php create mode 100644 wind/component/cache/dependency/WindCacheDependency.php create mode 100644 wind/component/cache/dependency/WindSqlCacheDependency.php create mode 100644 wind/component/cache/operator/WindApc.php create mode 100644 wind/component/cache/operator/WindEaccelerator.php create mode 100644 wind/component/cache/operator/WindMemcache.php create mode 100644 wind/component/cache/operator/WindWinCache.php create mode 100644 wind/component/cache/operator/WindXCache.php create mode 100644 wind/component/cache/operator/WindZendCache.php create mode 100644 wind/component/cache/strategy/WindCacheApc.php create mode 100644 wind/component/cache/strategy/WindCacheDb.php create mode 100644 wind/component/cache/strategy/WindCacheEaccelerator.php create mode 100644 wind/component/cache/strategy/WindCacheFile.php create mode 100644 wind/component/cache/strategy/WindCacheMem.php create mode 100644 wind/component/cache/strategy/WindCacheWin.php create mode 100644 wind/component/cache/strategy/WindCacheXCache.php create mode 100644 wind/component/cache/strategy/WindCacheZend.php create mode 100644 wind/component/collections/WindList.php create mode 100644 wind/component/collections/WindQueue.php create mode 100644 wind/component/collections/WindSortedList.php create mode 100644 wind/component/collections/WindStack.php create mode 100644 wind/component/dao/AbstractWindDao.php create mode 100644 wind/component/dao/AbstractWindDaoFactory.php create mode 100644 wind/component/dao/listener/WindDaoCacheListener.php create mode 100644 wind/component/db/WindConnection.php create mode 100644 wind/component/db/WindConnectionManager.php create mode 100644 wind/component/db/WindResultSet.php create mode 100644 wind/component/db/WindSqlStatement.php create mode 100644 wind/component/db/drivers/mssql/WindMsSql.php create mode 100644 wind/component/db/drivers/mssql/WindMsSqlBuilder.php create mode 100644 wind/component/db/drivers/mysql/WindMySql.php create mode 100644 wind/component/db/drivers/mysql/WindMySqlBuilder.php create mode 100644 wind/component/db/exception/WindDbException.php create mode 100644 wind/component/db/mysql/WindMysqlPdoAdapter.php create mode 100644 wind/component/http/cookie/WindCookie.php create mode 100644 wind/component/http/cookie/WindCookieObject.php create mode 100644 wind/component/http/session/AbstractWindUserSession.php create mode 100644 wind/component/http/session/WindDbSession.php create mode 100644 wind/component/http/session/WindSession.php create mode 100644 wind/component/http/transfer/AbstractWindHttp.php create mode 100644 wind/component/http/transfer/WindHttpCurl.php create mode 100644 wind/component/http/transfer/WindHttpSocket.php create mode 100644 wind/component/http/transfer/WindHttpStream.php create mode 100644 wind/component/log/WindDebug.php create mode 100644 wind/component/log/WindLogger.php create mode 100644 wind/component/mail/WindMail.php create mode 100644 wind/component/mail/protocol/WindImap.php create mode 100644 wind/component/mail/protocol/WindPop3.php create mode 100644 wind/component/mail/protocol/WindSmtp.php create mode 100644 wind/component/mail/protocol/WindSocket.php create mode 100644 wind/component/mail/sender/IWindSendMail.php create mode 100644 wind/component/mail/sender/WindPhpMail.php create mode 100644 wind/component/mail/sender/WindSendMail.php create mode 100644 wind/component/mail/sender/WindSmtpMail.php create mode 100644 wind/component/parser/WindIniParser.php create mode 100644 wind/component/parser/WindPropertiesParser.php create mode 100644 wind/component/parser/WindXmlParser.php create mode 100644 wind/component/upload/AbstractWindUpload.php create mode 100644 wind/component/upload/WindCurlUpload.php create mode 100644 wind/component/upload/WindFormUpload.php create mode 100644 wind/component/utility/WindArray.php create mode 100644 wind/component/utility/WindFile.php create mode 100644 wind/component/utility/WindMimeTypes.php create mode 100644 wind/component/utility/WindPack.php create mode 100644 wind/component/utility/WindSecurity.php create mode 100644 wind/component/utility/WindString.php create mode 100644 wind/component/utility/WindUtility.php create mode 100644 wind/component/utility/WindValidator.php create mode 100644 wind/component/utility/date/WindDate.php create mode 100644 wind/component/utility/date/WindGeneralDate.php create mode 100644 wind/component/utility/json/WindDecoder.php create mode 100644 wind/component/utility/json/WindEncoder.php create mode 100644 wind/config/components_config.php create mode 100644 wind/config/components_config.xml create mode 100644 wind/core/AbstractWindServer.php create mode 100644 wind/core/WindComponentModule.php create mode 100644 wind/core/WindEnableValidateModule.php create mode 100644 wind/core/WindHelper.php create mode 100644 wind/core/WindModule.php create mode 100644 wind/core/config/WindConfig.php create mode 100644 wind/core/config/WindSystemConfig.php create mode 100644 wind/core/config/parser/IWindConfigParser.php create mode 100644 wind/core/config/parser/WindConfigParser.php create mode 100644 wind/core/exception/WindActionException.php create mode 100644 wind/core/exception/WindCacheException.php create mode 100644 wind/core/exception/WindDaoException.php create mode 100644 wind/core/exception/WindException.php create mode 100644 wind/core/exception/WindFinalException.php create mode 100644 wind/core/exception/WindSqlException.php create mode 100644 wind/core/exception/WindViewException.php create mode 100644 wind/core/factory/IWindFactory.php create mode 100644 wind/core/factory/WindClassDefinition.php create mode 100644 wind/core/factory/WindComponentDefinition.php create mode 100644 wind/core/factory/WindComponentFactory.php create mode 100644 wind/core/factory/WindFactory.php create mode 100644 wind/core/factory/proxy/IWindClassProxy.php create mode 100644 wind/core/factory/proxy/WindClassProxy.php create mode 100644 wind/core/filter/WindFilter.php create mode 100644 wind/core/filter/WindFilterChain.php create mode 100644 wind/core/filter/WindHandlerInterceptor.php create mode 100644 wind/core/filter/WindHandlerInterceptorChain.php create mode 100644 wind/core/request/IWindRequest.php create mode 100644 wind/core/request/WindHttpRequest.php create mode 100644 wind/core/response/IWindResponse.php create mode 100644 wind/core/response/WindHttpResponse.php create mode 100644 wind/core/router/AbstractWindRouter.php create mode 100644 wind/core/router/WindUrlBasedRouter.php create mode 100644 wind/core/viewer/AbstractWindTemplateCompiler.php create mode 100644 wind/core/viewer/AbstractWindViewTemplate.php create mode 100644 wind/core/viewer/IWindViewerResolver.php create mode 100644 wind/core/viewer/WindLayout.php create mode 100644 wind/core/viewer/WindView.php create mode 100644 wind/core/viewer/WindViewerResolver.php create mode 100644 wind/core/viewer/compiler/WindTemplateCompilerAction.php create mode 100644 wind/core/viewer/compiler/WindTemplateCompilerComponent.php create mode 100644 wind/core/viewer/compiler/WindTemplateCompilerEcho.php create mode 100644 wind/core/viewer/compiler/WindTemplateCompilerInternal.php create mode 100644 wind/core/viewer/compiler/WindTemplateCompilerPage.php create mode 100644 wind/core/viewer/compiler/WindTemplateCompilerScript.php create mode 100644 wind/core/viewer/compiler/WindTemplateCompilerTemplate.php create mode 100644 wind/core/viewer/compiler/WindViewTemplate.php create mode 100644 wind/core/viewer/listener/WindViewCacheListener.php create mode 100644 wind/core/web/IWindApplication.php create mode 100644 wind/core/web/IWindErrorMessage.php create mode 100644 wind/core/web/WindAction.php create mode 100644 wind/core/web/WindController.php create mode 100644 wind/core/web/WindDispatcher.php create mode 100644 wind/core/web/WindErrorHandler.php create mode 100644 wind/core/web/WindErrorMessage.php create mode 100644 wind/core/web/WindFormController.php create mode 100644 wind/core/web/WindForward.php create mode 100644 wind/core/web/WindFrontController.php create mode 100644 wind/core/web/WindUrlHelper.php create mode 100644 wind/core/web/WindWebApplication.php create mode 100644 wind/core/web/filter/WindLoggerFilter.php create mode 100644 wind/core/web/filter/WindUrlFilter.php create mode 100644 wind/core/web/listener/WindFormListener.php create mode 100644 wind/core/web/listener/WindLoggerListener.php create mode 100644 wind/core/web/listener/WindValidateListener.php create mode 100644 wind/readme diff --git a/_tests/AllTest.php b/_tests/AllTest.php new file mode 100644 index 00000000..4282a508 --- /dev/null +++ b/_tests/AllTest.php @@ -0,0 +1,24 @@ + 2010-12-9 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once 'component/AllComponentTest.php'; +require_once 'core/AllCoreTest.php'; + +class AllTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllTest'); + $suite->addTest(AllComponentTest::suite()); + $suite->addTest(AllCoreTest::suite()); + return $suite; + } +} + diff --git a/_tests/BaseTestCase.php b/_tests/BaseTestCase.php new file mode 100644 index 00000000..58bf5b82 --- /dev/null +++ b/_tests/BaseTestCase.php @@ -0,0 +1,36 @@ +fail("Error type for arg1"); + $this->assertTrue(is_array($array2) && (count($array1) == count($array2))); + foreach ($array1 as $key => $value) { + $this->assertTrue(isset($array2[$key])); + if (is_array($value)) { + $this->assertArrayEquals($value, $array2[$key]); + } elseif (is_object($value)) { + $this->assertEquals(get_class($value), get_class($array2[$key])); + } else { + $this->assertEquals($value, $array2[$key]); + } + } + } +} \ No newline at end of file diff --git "a/_tests/about\345\221\275\344\273\244\350\241\214" "b/_tests/about\345\221\275\344\273\244\350\241\214" new file mode 100644 index 00000000..300986fe --- /dev/null +++ "b/_tests/about\345\221\275\344\273\244\350\241\214" @@ -0,0 +1,53 @@ +命令行下运行: +windTest AllTest + + +命令行下运行需要安装phpunit,目前最新版本为3.5 +安装: +1:安装pear:(如果已经安装跳过) + 命令行下进入php目录执行:go-pear + 一路yes / y + +2: 升级pear:(phpunit需要pear的版本在1.8以上,如果已经最新,跳过) + pear upgrade pear + (查看pear的版本信息:pear version) + +3: 安装phpunit: + 3.1: 添加phpunit的频道并初始化: + pear channel-discover pear.phpunit.de + 3.2: 获得phpunit并安装: + 采用全安装模式: + pear install --alldeps phpunit/PHPUnit + + 3.3:安装成功:查看phpunit命令 + phpunit + +需要获得覆盖率需要安装xdebug插件. +www.xdebug.org下载最新xdebug,修改为php_xdebug(可选)放在PHP/ext下 +配置php.ini: + +;xdebug配置 +[Xdebug] +zend_extension_ts="C:/wamp/php/ext/php_xdebug.dll" +;开启自动跟踪 +xdebug.auto_trace = On +;开启异常跟踪 +xdebug.show_exception_trace = On +;开启远程调试自动启动 +xdebug.remote_autostart = On +;开启远程调试 +xdebug.remote_enable = On +;收集变量 +xdebug.collect_vars = On +;收集返回值 +xdebug.collect_return = On +;收集参数 +xdebug.collect_params = On +;设置输出路径 +xdebug.trace_output_dir="D:/PHPAPP/Xdebug" +xdebug.profiler_output_dir="D:/PHPAPP/Xdebug" + +注意:xdebug和zend optimization冲突 +所以如果安装了zend optimization需要将该选项去掉(或是加;注释) +xdebug的加载模式需要是zend_extension_ts或是zend_extension +目前5.2.X需要采用zend_extension_ts加载,后续版本(5.3)才用zend_extension \ No newline at end of file diff --git a/_tests/bootstrap.php b/_tests/bootstrap.php new file mode 100644 index 00000000..58d9d5b4 --- /dev/null +++ b/_tests/bootstrap.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/_tests/component/AllComponentTest.php b/_tests/component/AllComponentTest.php new file mode 100644 index 00000000..f338fcc3 --- /dev/null +++ b/_tests/component/AllComponentTest.php @@ -0,0 +1,40 @@ + 2010-12-9 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +//require_once ('component/config/WindConfigParserTest.php'); +require_once ('component/db/AllDBTest.php'); +require_once ('component/form/AllFormTest.php'); +require_once ('component/format/AllFormatTest.php'); +require_once ('component/log/AllLogTest.php'); +require_once ('component/mail/AllMailTest.php'); +require_once ('component/parser/AllParserTest.php'); +require_once ('component/security/WindSecurityTest.php'); +require_once ('component/validator/WindValidatorTest.php'); +require_once('component/WindPackTest.php'); + +class AllComponentTest { + + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllComponentTest'); + //$suite->addTestSuite('WindConfigParserTest'); + $suite->addTest(ALLDBTest::suite()); + $suite->addTest(ALLFormTest::suite()); + $suite->addTest(ALLFormatTest::suite()); + $suite->addTest(AllLogTest::suite()); + $suite->addTest(AllMailTest::suite()); + $suite->addTest(AllParserTest::suite()); + + $suite->addTestSuite('WindSecurityTest'); + $suite->addTestSuite('WindValidatorTest'); + $suite->addTestSuite('WindPackTest'); + return $suite; + } +} diff --git a/_tests/component/cache/WindCacheFactoryTest.php b/_tests/component/cache/WindCacheFactoryTest.php new file mode 100644 index 00000000..2feef67a --- /dev/null +++ b/_tests/component/cache/WindCacheFactoryTest.php @@ -0,0 +1,42 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +class WindCacheFactoryTest extends BaseTestCase{ + /** + * @var WindCacheFactory + */ + private $cacheFactory = null; + public function init() { + require_once ('component/cache/windcachefactory.php'); + if ($this->cacheFactory == null) { + $this->cacheFactory = new WindCacheFactory(); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testDependencyFactory(){ + $dependency = $this->cacheFactory->dependencyFactory('WindCacheDependency'); + $this->assertThat($dependency,$this->isInstanceOf('WindCacheDependency')); + } + + public function testStrategyCacheFactory(){ + $cacheDir = dirname(dirname(dirname(__FILE__))).'/data/'; + $cache = $this->cacheFactory->storedFactory('WindFileCache',array('cachedir'=>$cacheDir)); + $this->assertThat($cache,$this->isInstanceOf('WindFileCache')); + } + +} \ No newline at end of file diff --git a/_tests/component/cache/strategy/WindFileCacheTest.php b/_tests/component/cache/strategy/WindFileCacheTest.php new file mode 100644 index 00000000..c961f2eb --- /dev/null +++ b/_tests/component/cache/strategy/WindFileCacheTest.php @@ -0,0 +1,92 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +class WindFileCacheTest extends BaseTestCase{ + /** + * @var WindFileCache + */ + private $fileCache = null; + public function init() { + $this->requireFile(); + if ($this->fileCache == null) { + $config[WindFileCache::CACHEDIR] = dirname(dirname(dirname(dirname(__FILE__)))).'/data/cache/'; + $this->fileCache = new WindFileCache(); + $this->fileCache->setConfig($config); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function requireFile() { + require_once ('component/cache/strategy/WindFileCache.php'); + } + + + public function testSet(){ + $this->assertTrue(false !== $this->fileCache->set('key','value')); + $this->assertEquals('value',$this->fileCache->get('key')); + $this->assertTrue(false !== $this->fileCache->set('key','newValue')); + $this->assertTrue(false !== $this->fileCache->delete('key')); + $this->assertTrue(false !== $this->fileCache->set('newkey','newValue',1)); + $this->assertEquals('newValue',$this->fileCache->get('newkey')); + } + + + public function testget(){ + $this->assertTrue(false !== $this->fileCache->set('php','value',1)); + $this->assertEquals('value',$this->fileCache->get('php')); + } + + public function testBatchget(){ + $this->assertTrue(false !== $this->fileCache->set('name','phpwind',1)); + $this->assertTrue(false !== $this->fileCache->set('age','100',1)); + $result = $this->fileCache->batchGet(array('name','age')); + $this->assertTrue(2 === count($result) && 'phpwind' === $result['name'] && '100' === $result['age']); + $this->assertTrue($this->fileCache->batchDelete(array('name','age'))); + } + + public function testDelete(){ + $this->assertTrue(false !== $this->fileCache->set('name','phpwind')); + $this->assertTrue($this->fileCache->delete('name')); + } + + public function testBatchDelete(){ + $this->assertTrue(false !== $this->fileCache->set('name','phpwind',1)); + $this->assertTrue(false !== $this->fileCache->set('age','100',1)); + $this->assertTrue($this->fileCache->batchDelete(array('name','age'))); + } + + public function testFlush(){ + $this->assertTrue(false !== $this->fileCache->set('one','ones')); + $this->assertTrue(false !== $this->fileCache->set('two','twos')); + $this->assertTrue(false !== $this->fileCache->set('three','threes')); + //$this->assertTrue($this->fileCache->flush()); + $this->assertTrue($this->fileCache->set('one','ones',1)); + } + + public function testMutiLevels(){ + $config[WindFileCache::CACHEDIR] = dirname(dirname(dirname(dirname(__FILE__)))).'/data/cache'; + $config[WindFileCache::LEVEL] = 2; + $fileCache = new WindFileCache($config); + $fileCache->setConfig($config); + $this->assertTrue(false !== $fileCache->set('school','alibaba',100)); + $this->assertTrue(false !== $fileCache->set('bbs','phpwind')); + $this->assertTrue(false !== $fileCache->set('colleage','beida')); + $this->assertEquals('alibaba',$fileCache->get('school')); + //$fileCache->flush(); + + } +} \ No newline at end of file diff --git a/_tests/component/collections/WindListTest.php b/_tests/component/collections/WindListTest.php new file mode 100644 index 00000000..57192478 --- /dev/null +++ b/_tests/component/collections/WindListTest.php @@ -0,0 +1,161 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 列表集合单元测试 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindListTest extends BaseTestCase { + /** + * @var WindList + */ + private $list = null; + public function init() { + $this->requireFile(); + if ($this->list == null) { + $this->list = new WindList(); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function requireFile(){ + require_once ('component/collections/WindList.php'); + } + + public function testAdd() { + $this->assertTrue($this->list->add('test')); + $this->assertEquals('test', $this->list->itemAt(0)); + } + + public function testInsertAt() { + $this->assertTrue($this->list->insertAt(0, 'test')); + $this->assertEquals('test', $this->list->itemAt(0)); + } + + public function testItemAt() { + $this->assertTrue($this->list->add('a')); + $this->assertTrue($this->list->add('b')); + $this->assertTrue($this->list->add('c')); + $this->assertEquals('c', $this->list->itemAt(2)); + + } + + public function testIndexOf() { + $this->assertTrue($this->list->add('a')); + $this->assertTrue($this->list->add('b')); + $this->assertTrue($this->list->add('c')); + $this->assertTrue(2 == $this->list->indexOf('c')); + } + + public function testContain() { + $this->assertTrue($this->list->add('one')); + $this->assertTrue($this->list->add('two')); + $this->assertTrue($this->list->add('three')); + $this->assertTrue($this->list->contain(('two'))); + } + + public function testContainAt() { + $this->assertTrue($this->list->add('one')); + $this->assertTrue($this->list->add('two')); + $this->assertTrue($this->list->add('three')); + $this->assertTrue($this->list->containAt(2)); + } + + public function testModify() { + $this->assertTrue($this->list->add('one')); + $this->assertTrue($this->list->add('two')); + $this->assertTrue($this->list->add('three')); + $this->assertTrue($this->list->modify(1, 'test')); + $this->assertEquals('test', $this->list->itemAt(1)); + $this->assertTrue(false === $this->list->contain('two')); + } + + public function testRemove() { + $this->assertTrue($this->list->add('one')); + $this->assertTrue($this->list->add('two')); + $this->assertEquals('two', $this->list->remove('two')); + $this->assertTrue(false === $this->list->contain('two')); + } + + public function testRemoveAt() { + $this->assertTrue($this->list->add('one')); + $this->assertTrue($this->list->add('two')); + $this->assertEquals('two', $this->list->removeAt(1)); + $this->assertTrue(false === $this->list->contain('two')); + } + + public function testMergeFromArray() { + $this->assertTrue($this->list->add('one')); + $this->assertTrue($this->list->add('two')); + $this->assertTrue($this->list->mergeFromArray(array('three'))); + $this->assertTrue($this->list->contain('three')); + } + public function testMergeFromList() { + $list = new WindList(); + $list->add('three'); + $this->assertTrue($this->list->add('one')); + $this->assertTrue($this->list->add('two')); + $this->assertTrue($this->list->mergeFromList($list)); + $this->assertTrue($this->list->contain('three')); + } + + public function testClear() { + $this->assertTrue($this->list->add('one')); + $this->assertTrue($this->list->add('two')); + $this->assertTrue($this->list->clear()); + $this->assertTrue(0 === $this->list->getCount()); + $list = $this->list->getList(); + $this->assertTrue(empty($list)); + } + + public function testFixedList(){ + $list = new WindList(array('abc')); + try{ + $list->add("haha"); + }catch(WindException $e){ + $this->assertTrue($list->getIsFixedSize()); + return true; + } + $this->fail("this list is fixed"); + } + + public function testReadOnly(){ + $list = new WindList(array("read"),true); + try{ + $list->modify(0,"haha"); + }catch(WindException $e){ + $this->assertTrue($list->getIsReadOnly()); + $this->assertTrue($list->getIsFixedSize()); + return true; + } + $this->fail("this list is readonly"); + } + + public function testIndexVisit(){ + $this->list[0] = 'phpwind'; + $this->list[1] = 'test'; + $this->assertEquals('phpwind',$this->list[0]); + $this->assertTrue(2 === count($this->list)); + if(isset($this->list[1])){ + unset($this->list[1]); + } + $this->assertTrue(1 === count($this->list)); + } +} \ No newline at end of file diff --git a/_tests/component/collections/WindQueueTest.php b/_tests/component/collections/WindQueueTest.php new file mode 100644 index 00000000..9b47b0ac --- /dev/null +++ b/_tests/component/collections/WindQueueTest.php @@ -0,0 +1,94 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindQueueTest extends BaseTestCase{ + /** + * @var WindQueue + */ + private $queue = null; + public function init() { + $this->requireFile(); + if ($this->queue == null) { + $this->queue = new WindQueue(); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function requireFile(){ + require_once ('component/collections/WindQueue.php'); + } + + public function testEnqueue(){ + $this->assertTrue(1 === $this->queue->enqueue("enqueue")); + $this->assertEquals('enqueue',$this->queue->peek()); + } + + public function testDequeue(){ + $this->assertTrue(1 === $this->queue->enqueue("enqueue")); + $this->assertTrue(2 === $this->queue->enqueue("dequeue")); + $this->assertEquals('enqueue',$this->queue->dequeue()); + $this->assertTrue(false === $this->queue->contain('enqueue')); + } + + public function testPeek(){ + $this->assertTrue(1 === $this->queue->enqueue("enqueue")); + $this->assertEquals('enqueue',$this->queue->peek()); + $this->assertTrue($this->queue->contain('enqueue')); + } + + + + public function testMergeFromArray() { + $this->assertTrue(1 === $this->queue->enqueue('one')); + $this->assertTrue(2 === $this->queue->enqueue('two')); + $this->assertTrue($this->queue->mergeFromArray(array('three'))); + $this->assertTrue($this->queue->contain('three')); + } + + public function testMergeFromQueue() { + $queue = new WindQueue(); + $queue->enqueue('three'); + $this->assertTrue(1 === $this->queue->enqueue('one')); + $this->assertTrue(2 === $this->queue->enqueue('two')); + $this->assertTrue($this->queue->mergeFromQueue($queue)); + $this->assertTrue($this->queue->contain('three')); + } + + public function testClear() { + $this->assertTrue(1 === $this->queue->enqueue('one')); + $this->assertTrue(2 === $this->queue->enqueue('two')); + $this->assertTrue($this->queue->clear()); + $this->assertTrue(0 === $this->queue->getCount()); + + } + + public function testClone(){ + $queue = clone($this->queue); + $this->assertTrue(($queue instanceof WindQueue) && $queue !== $this->queue); + } + + public function testCount(){ + $this->assertTrue(1 === $this->queue->enqueue('one')); + $this->assertEquals(1,count($this->queue)); + } +} \ No newline at end of file diff --git a/_tests/component/collections/WindSortedListTest.php b/_tests/component/collections/WindSortedListTest.php new file mode 100644 index 00000000..47318576 --- /dev/null +++ b/_tests/component/collections/WindSortedListTest.php @@ -0,0 +1,146 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +class WindListTest extends BaseTestCase { + /** + * @var WindSortedList + */ + private $sortedList = null; + public function init() { + $this->requireFile(); + if ($this->sortedList == null) { + $this->sortedList = new WindSortedList(); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function requireFile(){ + require_once ('component/collections/WindSortedList.php'); + } + + public function testAdd() { + $this->assertTrue($this->sortedList->add('key','value')); + $this->assertEquals('value', $this->sortedList->item('key')); + } + + public function testContains(){ + $this->assertTrue($this->sortedList->add('key','value')); + $this->assertTrue($this->sortedList->contains('key')); + $this->assertTrue($this->sortedList->containsIndex(0)); + $this->assertTrue($this->sortedList->containsValue('value')); + } + + public function testItem() { + $this->assertTrue($this->sortedList->add('a','11')); + $this->assertTrue($this->sortedList->add('b','22')); + $this->assertTrue($this->sortedList->add('c','33')); + $this->assertEquals('33', $this->sortedList->itemAt(2)); + $this->assertEquals('33', $this->sortedList->item('c')); + } + + public function testIndexOf() { + $this->assertTrue($this->sortedList->add('a','11')); + $this->assertTrue($this->sortedList->add('b','22')); + $this->assertTrue($this->sortedList->add('c','33')); + $this->assertTrue(2 == $this->sortedList->indexOfKey('c')); + $this->assertTrue(2 == $this->sortedList->indexOfValue('33')); + } + + public function testSetByIndex() { + $this->assertTrue($this->sortedList->add('a','one')); + $this->assertTrue($this->sortedList->add('b','two')); + $this->assertTrue($this->sortedList->setByIndex(1, 'test')); + $this->assertEquals('test', $this->sortedList->itemAt(1)); + $this->assertTrue(false === $this->sortedList->containsValue('two')); + $this->assertTrue($this->sortedList->containsKey('b')); + } + + public function testSetByKey(){ + $this->assertTrue($this->sortedList->add('a','one')); + $this->assertTrue($this->sortedList->add('b','two')); + $this->assertEquals('two',$this->sortedList->setByKey('b', 'test')); + $this->assertEquals('test', $this->sortedList->item('b')); + $this->assertTrue(false === $this->sortedList->containsValue('two')); + $this->assertTrue($this->sortedList->containsKey('b')); + } + + public function testRemove() { + $this->assertTrue($this->sortedList->add('a','one')); + $this->assertTrue($this->sortedList->add('b','two')); + $this->assertEquals('two', $this->sortedList->remove('b')); + $this->assertTrue(false === $this->sortedList->containsValue('two')); + $this->assertTrue(false === $this->sortedList->containsKey('b')); + } + + public function testRemoveAt() { + $this->assertTrue($this->sortedList->add('a','one')); + $this->assertTrue($this->sortedList->add('b','two')); + $this->assertEquals('two', $this->sortedList->removeAt(1)); + $this->assertTrue(false === $this->sortedList->containsValue('two')); + $this->assertTrue(false === $this->sortedList->containsKey('b')); + } + + public function testClone(){ + $sortedList = clone($this->sortedList); + $this->assertTrue(($sortedList instanceof WindSortedList) && $sortedList !== $this->sortedList); + } + + + + public function testClear() { + $this->assertTrue($this->sortedList->add('a','one')); + $this->assertTrue($this->sortedList->add('b','two')); + $this->assertTrue($this->sortedList->clear()); + $this->assertTrue(0 === $this->sortedList->getCount()); + } + + public function testFixedList(){ + $list = new WindSortedList(array('key','value')); + try{ + $list->add('keys',"haha"); + }catch(WindException $e){ + $this->assertTrue($list->getIsFixedSize()); + return true; + } + $this->fail("this sortedlist is fixed"); + } + + public function testReadOnly(){ + $list = new WindSortedList(array('key','value'),true); + try{ + $list->setByIndex(0,"haha"); + $list->setByKey('key',"haha"); + }catch(WindException $e){ + $this->assertTrue($list->getIsReadOnly()); + $this->assertTrue($list->getIsFixedSize()); + return true; + } + $this->fail("this list is readonly"); + } + + public function testIndexVisit(){ + $this->sortedList['version'] = 'phpwind 8.0'; + $this->sortedList['key'] = 'value'; + $this->assertEquals('phpwind 8.0',$this->sortedList['version']); + $this->assertEquals('phpwind 8.0',$this->sortedList[0]); + $this->assertTrue(2 === count($this->sortedList)); + if(isset($this->sortedList[1])){ + unset($this->sortedList[1]); + } + $this->assertTrue(1 === count($this->sortedList)); + } +} \ No newline at end of file diff --git a/_tests/component/collections/WindStackTest.php b/_tests/component/collections/WindStackTest.php new file mode 100644 index 00000000..a08b48f4 --- /dev/null +++ b/_tests/component/collections/WindStackTest.php @@ -0,0 +1,88 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +class WindQueueTest extends BaseTestCase{ + /** + * @var WindStack + */ + private $stack = null; + public function init() { + $this->requireFile(); + if ($this->stack == null) { + $this->stack = new WindStack(); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function requireFile(){ + require_once ('component/collections/WindStack.php'); + } + + public function testPush(){ + $this->assertTrue(1 === $this->stack->push("push")); + $this->assertEquals('push',$this->stack->peek()); + } + + public function testPop(){ + $this->assertTrue(1 === $this->stack->push("push")); + $this->assertTrue(2 === $this->stack->push("pop")); + $this->assertEquals('pop',$this->stack->pop()); + $this->assertTrue(false === $this->stack->contain('pop')); + } + + public function testPeek(){ + $this->assertTrue(1 === $this->stack->push("push")); + $this->assertEquals('push',$this->stack->peek()); + $this->assertTrue($this->stack->contain('push')); + } + + + + public function testMergeFromArray() { + $this->assertTrue(1 === $this->stack->push('one')); + $this->assertTrue(2 === $this->stack->push('two')); + $this->assertTrue($this->stack->mergeFromArray(array('three'))); + $this->assertTrue($this->stack->contain('three')); + } + + public function testMergeFromStack() { + $queue = new WindStack(); + $queue->push('three'); + $this->assertTrue(1 === $this->stack->push('one')); + $this->assertTrue(2 === $this->stack->push('two')); + $this->assertTrue($this->stack->mergeFromStack($queue)); + $this->assertTrue($this->stack->contain('three')); + } + + public function testClear() { + $this->assertTrue(1 === $this->stack->push('one')); + $this->assertTrue(2 === $this->stack->push('two')); + $this->assertTrue($this->stack->clear()); + $this->assertTrue(0 === $this->stack->getCount()); + + } + + public function testClone(){ + $stack = clone($this->stack); + $this->assertTrue(($stack instanceof WindStack) && $stack !== $this->stack); + } + + public function testCount(){ + $this->assertTrue(1 === $this->stack->push('one')); + $this->assertEquals(1,count($this->stack)); + } +} \ No newline at end of file diff --git a/_tests/component/db/AllDBTest.php b/_tests/component/db/AllDBTest.php new file mode 100644 index 00000000..3df51a99 --- /dev/null +++ b/_tests/component/db/AllDBTest.php @@ -0,0 +1,29 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('component/db/WindConnectionManagerTest.php'); +require_once ('component/db/drivers/mysql/WindMySqlBuilderTest.php'); +require_once ('component/db/drivers/mysql/WindMySqlTest.php'); +require_once ('component/db/drivers/mssql/WindMsSqlBuilderTest.php'); +require_once ('component/db/drivers/mssql/WindMsSqlTest.php'); + +class AllDBTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllDBTest'); + $suite->addTestSuite('WindMysqlBuilderTest'); + //$suite->addTestSuite('WindMySqlTest'); + $suite->addTestSuite('WindConnectionManagerTest'); + /*$suite->addTestSuite('WindMsSqlBuilderTest'); + $suite->addTestSuite('WindMsSqlTest');*/ + return $suite; + } +} \ No newline at end of file diff --git a/_tests/component/db/WindConnectionManagerTest.php b/_tests/component/db/WindConnectionManagerTest.php new file mode 100644 index 00000000..b66f9207 --- /dev/null +++ b/_tests/component/db/WindConnectionManagerTest.php @@ -0,0 +1,99 @@ + 2010-12-10 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +require_once ('component/db/drivers/IWindDbConfig.php'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindConnectionManagerTest extends BaseTestCase { + private $dbManager = null; + private $config = array(); + private function getDBConfig() { + return array( + 'connections' => array( + 'connection1' => array( + 'driver' => 'mysql', + 'type' => 'master', + 'host' => 'localhost', + 'user' => 'root', + 'password' => 'suqian0512h', + 'port' => '3306', + 'name' => 'phpwind_8', + ), + 'connection2' => array( + 'driver' => 'mysql', + 'type' => 'slave', + 'host' => 'localhost', + 'user' => 'root', + 'password' => 'suqian0512h', + 'port' => '3306', + 'name' => 'phpwind_8beta', + ), + ), + 'drivers' => array( + 'mysql' => array( + 'builder' => 'mySqlBuilder', + 'class' => 'WIND:component.db.drivers.mysql.WindMySql', + ), + 'mssql' => array( + 'builder' => 'msSqlBuilder', + 'class' => 'WIND:component.db.drivers.mssql.WindMsSql', + ), + ), + 'builders' => array( + 'mySqlBuilder' => array( + 'class' => 'WIND:component.db.drivers.mysql.WindMySqlBuilder', + ), + ), + ); + } + public function init() { + require_once ('component/db/WindConnectionManager.php'); + if ($this->dbManager == null) { + $this->dbManager = new WindConnectionManager(); + $windConfig = new WindConfig(new WindConfigParser()); + $windConfig->setConfig($this->getDBConfig()); + $this->dbManager->setConfig($windConfig); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public static function providerConnection() { + return array(array('', ''), array('connection1', ''), array('', IWindDbConfig::MASTER), + array('', IWindDbConfig::SLAVE)); + } + + /** + * @dataProvider providerConnection + */ + public function testGetConnection($identify, $type) { + $conn = $this->dbManager->getConnection($identify, $type); + $this->assertTrue(($conn instanceof AbstractWindDbAdapter)); + } + + public function testGetMasterConnection() { + $conn = $this->dbManager->getMasterConnection(); + $this->assertTrue(($conn instanceof AbstractWindDbAdapter)); + } + + public function testGetSlaveConnection() { + $conn = $this->dbManager->getSlaveConnection(); + $this->assertTrue(($conn instanceof AbstractWindDbAdapter)); + } + +} \ No newline at end of file diff --git a/_tests/component/db/drivers/mssql/WindMsSqlBuilderTest.php b/_tests/component/db/drivers/mssql/WindMsSqlBuilderTest.php new file mode 100644 index 00000000..3966155e --- /dev/null +++ b/_tests/component/db/drivers/mssql/WindMsSqlBuilderTest.php @@ -0,0 +1,349 @@ + 2010-12-10 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMsSqlBuilderTest extends BaseTestCase { + + private $config = ''; + private $adapter = null; + private $WindMsSqlBuilder = null; + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function init() { + require_once('component/db/base/IWindDbConfig.php'); + require_once('component/db/drivers/mssql/WindMsSqlBuilder.php'); + require_once('component/db/drivers/mssql/WindMsSql.php'); + if ($this->WindMsSqlBuilder == null) { + $this->config = C::getDataBaseConnection('use'); + $this->adapter = new WindMsSql($this->config); + $this->WindMsSqlBuilder = new WindMsSqlBuilder($this->adapter); + } + $this->WindMsSqlBuilder->reset(); + } + + public static function provider() { + return array(array('pw_posts', '', '', '', ''), array('pw_posts', 'a.uid=pw_posts.authorid', '', '', ''), + array('pw_posts', 'a.uid=b.authorid', 'b', '', ''), + array('pw_posts', 'a.uid=b.authorid', 'b', 'subject,pid', ''), + array('pw_posts', 'a.uid=b.authorid', 'b', 'b.subject,b.pid', ''), + array('pw_posts', 'a.uid=b.authorid', 'b', array('subject', 'pid'), 'phpwind_8')); + } + + public static function providerWhere() { + return array(array('username = "1"', '', ''), array(array('age <= ?', 'uid > ?'), array(3, 4), ''), + array(array('age = 3', 'uid >4'), '', ''), array('uid < ?', 1, true), + array('username = ? AND uid > ? ', array('"suqian"', 2), false)); + } + + public static function providerOrder() { + return array(array(array('dateline' => 'desc'), true), array('dateline', true), array('age', false), + array(array('dateline' => true, 'age' => false), true)); + } + + public static function providerLimit() { + return array(array(1, 0), array(1, 5)); + } + + public static function providerData() { + return array(array(array('a', 'b', 'c')), array(array(array('1a', '1b', '1c'), array('2a', '2b', '2c')))); + } + + public static function providerSet() { + return array(array('username = "1"', ''), array(array('age <= ?', 'uid > ?'), array(3, 4)), + array(array('age = 3', 'uid >4'), ''), array('uid < ?', 1), + array('username = ? , uid > ? ', array('"suqian"', 2))); + } + + public static function providerAffected() { + return array(array(true), array(false)); + } + + public static function providerPlaceHolder(){ + return array( + array("id= 1 AND name= 'suqian'",array()), + array(array('id= 1',"name= 'suqian'"),array()), + array(array('id=?','name=?'),array(1,'suqian')), + array(array('id'=>1,'name'=>'suqian'),array()), + array('id=? AND name=?',array(1,'suqian')), + array('id=:id AND name=:name',array(':name'=>'suqian',':id'=>1,)) + ); + } + + /** + * @dataProvider provider + */ + + public function testFrom($table, $joinWhere, $table_alias, $fields, $schema) { + + $builder = $this->WindMsSqlBuilder->from($table, $table_alias, $fields, $schema); + $from = $this->WindMsSqlBuilder->getSql(WindSqlBuilder::FROM); + $field = $fields ? $this->WindMsSqlBuilder->getSql(WindSqlBuilder::FIELD) : true; + $this->assertTrue($from && $field && ($builder instanceof WindSqlBuilder)); + } + + public function testDistinct() { + $builder = $this->WindMsSqlBuilder->distinct(true); + $distinct = $this->WindMsSqlBuilder->getSql(WindSqlBuilder::DISTINCT); + $this->assertEquals(WindSqlBuilder::SQL_DISTINCT, $distinct); + $this->assertTrue(($builder instanceof WindSqlBuilder)); + } + + public function testField() { + + $this->assertTrue($this->_field('username', 'uid')); + } + + public function testFieldWithArray() { + $this->assertTrue($this->_field(array('username', 'uid'))); + } + + public function testFieldWithParam() { + $this->assertTrue($this->_field('username', 'uid', 'age')); + } + + /** + * @dataProvider provider + */ + public function testJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join('join', $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testLeftJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::LEFT, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testRightJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::RIGHT, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testFullJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::FULL, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testInnerJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::INNER, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testCrossJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::CROSS, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider providerWhere + */ + public function testWhere($where, $value, $group) { + $this->assertTrue($this->_where(WindSqlBuilder::WHERE, $where, $value, $group, true)); + } + + /** + * @dataProvider providerWhere + */ + public function testOrWhere($where, $value, $group) { + $this->assertTrue($this->_where(WindSqlBuilder::WHERE, $where, $value, $group, false)); + } + + public function testGroup() { + $this->assertTrue($this->_field('dateline', 'uid')); + } + + public function testGroupWithArray() { + $this->assertTrue($this->_field(array('dateline', 'uid'))); + } + + public function testGroupWithParam() { + $this->assertTrue($this->_field('username', 'uid')); + } + + /** + * @dataProvider providerWhere + */ + public function testHaving() { + $this->assertTrue($this->_where(WindSqlBuilder::HAVING, $where, $value, $group, true)); + } + + /** + * @dataProvider providerWhere + */ + public function testOrHaving() { + $this->assertTrue($this->_where(WindSqlBuilder::HAVING, $where, $value, $group, false)); + } + + /** + * @dataProvider providerOrder + */ + public function testOrder($field, $type) { + $builder = $this->WindMsSqlBuilder->order($field, $type); + $order = $this->WindMsSqlBuilder->getSql(WindSqlBuilder::ORDER); + $this->assertTrue($order && ($builder instanceof WindSqlBuilder)); + } + + /** + *@dataProvider providerLimit + */ + public function testLimit($limit, $offset) { + $builder = $this->WindMsSqlBuilder->limit($limit, $offset); + $page = $this->WindMsSqlBuilder->getSql(WindSqlBuilder::LIMIT); + $this->assertTrue($page && ($builder instanceof WindSqlBuilder)); + } + + /** + *@dataProvider providerData + */ + public function testData($data) { + $builder = $this->WindMsSqlBuilder->data($data); + $data = $this->WindMsSqlBuilder->getSql(WindSqlBuilder::DATA); + $this->assertTrue($data && ($builder instanceof WindSqlBuilder)); + } + + /** + * @dataProvider providerSet + */ + public function testSet($field, $value) { + $builder = $this->WindMsSqlBuilder->set($field, $value); + $set = $this->WindMsSqlBuilder->getSql(WindSqlBuilder::SET); + $this->assertTrue($set && ($builder instanceof WindSqlBuilder)); + } + +public function testGetSelectSql() { + $sql = "SELECT a.username,b.title FROM pw_members AS a LEFT JOIN pw_posts AS b ON a.uid=b.authorid WHERE a.uid != 1 OR a.group > 0 GROUP BY a.age HAVING a.age != 4 ORDER BY dateline DESC "; + $assemblySql = $this->WindMsSqlBuilder->from ( 'pw_members', 'a', 'username' )->leftJoin ( 'pw_posts', 'a.uid=b.authorid', 'b', 'title' )->where ( 'a.uid != ?', 1 )->orWhere ( 'a.group > 0' )->group ( 'a.age' )->having ( array ('a.age != ?' ), array (4 ) )->order ( 'dateline', true )->getSelectSql (); + $this->assertEquals ( $this->trimSpace($sql), $this->trimSpace($assemblySql) ); + } + + public function testGetInsertSql() { + $sql = "INSERT pw_members ( name,age )VALUES ( 'a' , 'b' ) , ( 'c' , 'd' ) "; + $insertSql = $this->WindMsSqlBuilder->from ( 'pw_members' )->field ( 'name', 'age' )->data ( array (array ('a', 'b' ), array ('c', 'd' ) ) )->getInsertSql (); + $this->assertEquals ( $this->trimSpace($sql), $this->trimSpace($insertSql) ); + + } + + public function testGetUpdateSql() { + $sql = "UPDATE pw_members SET username= 'suqian' ,age= 3 WHERE uid = 11 "; + $updateSql = $this->WindMsSqlBuilder->from ( 'pw_members' )->set ( 'username=?,age=?', array ('suqian', 3 ) )->where ( 'uid = 11' )->getUpdateSql (); + $this->assertEquals ( $this->trimSpace($sql), $this->trimSpace($updateSql) ); + } + + public function testGetReplaceSql() { + $sql = "REPLACE pw_members ( name,age )VALUES ( 'a' , 'b' ) , ( 'c' , 'd' ) "; + $replaceSql = $this->WindMsSqlBuilder->from ( 'pw_members' )->field ( 'name', 'age' )->data ( array (array ('a', 'b' ), array ('c', 'd' ) ) )->getReplaceSql (); + //$this->assertEquals ( $this->trimSpace($sql), $this->trimSpace($replaceSql) ); + } + + public function testGetDeleteSql() { + $sql = "DELETE FROM pw_members AS a WHERE a.uid = 11 "; + $deleteSql = $this->WindMsSqlBuilder->from ( 'pw_members', 'a' )->where ( 'a.uid = ?', 11 )->getDeleteSql (); + $this->assertEquals ( $this->trimSpace($sql), $this->trimSpace($deleteSql) ); + } + + public function testGetAffectedSql() { + $sql = 'SELECT @@ROWCOUNT AS affectedRows'; + $affectedSql = $this->WindMsSqlBuilder->getAffectedSql (true); + $this->assertEquals ($this->trimSpace( $sql), $this->trimSpace($affectedSql) ); + } + + public function testGetLastInsertIdSql() { + $sql = 'SELECT @@IDENTITY AS insertId'; + $lastInsertSql = $this->WindMsSqlBuilder->getLastInsertIdSql (); + $this->assertEquals ( $this->trimSpace( $sql),$this->trimSpace( $lastInsertSql) ); + } + + public function testGetMetaTableSql() { + $sql = "SELECT name,object_id FROM phpwind.sys.all_objects WHERE type = 'U'"; + $metaTableSql = $this->WindMsSqlBuilder->getMetaTableSql ( 'phpwind' ); + $this->assertEquals ( $this->trimSpace( $sql),$this->trimSpace( $metaTableSql) ); + } + + public function testGetMetaColumnSql() { + $sql = "SELECT b.name Field,b.max_length,b.precision,b.scale,b.is_nullable,b.is_identity FROM sys.objects AS a INNER JOIN sys.all_columns AS b ON a.object_id = b.object_id INNER JOIN sys.types AS c ON b.system_type_id = c.system_type_id WHERE a.name = 'pw_members' "; + $metaColumSql = $this->WindMsSqlBuilder->getMetaColumnSql ( 'pw_members' ) ; + $this->assertEquals ( $this->trimSpace( $sql), $this->trimSpace($metaColumSql)); + } + + public function testSelect() { + $result = $this->WindMsSqlBuilder->from ( 'pw_members', 'a' )->from ( 'pw_posts', 'b' )->where ( 'a.uid=b.authorid' )->where ( 'b.tid >= ? and b.pid < ? and uid IN ?', array (2, 1000, array (1, 2, 3, 4, 5, 6, 7, 8 ) ) )->field ( 'username', 'uid', 'b.subject' )->select ()->getAllRow ( MYSQL_ASSOC ); + $this->assertTrue ( is_array ( $result ) ); + } + + public function testUpdate() { + $result = $this->WindMsSqlBuilder->from ( 'pw_posts' )->set ( 'subject=?,buy=?', array ('suqian', 3 ) )->where ( 'pid = 1' )->update (); + $this->assertTrue ( $result ); + } + + public function testDelete() { + $result = $this->WindMsSqlBuilder->from ( 'pw_posts' )->where ( 'pid = 2' )->delete (); + $this->assertTrue ( $result ); + } + + public function testInsert() { + $result = $this->WindMsSqlBuilder->from ( 'pw_actions' )->field ( 'images', 'descrip', 'name' )->data ( 'a', 'b', 'c' )->insert (); + $this->assertTrue ( $result ); + } + + /** + * @dataProvider providerPlaceHolder + */ + public function testPlaceHolder($where,$value){ + $sql="SELECT name,id,images FROM pw_actions WHERE id= 1 AND name='suqian'"; + $selectSql = $this->WindMsSqlBuilder->from('pw_actions')->field('name','id','images')->where($where,$value)->getSelectSql(); + $this->assertEquals ( $this->trimSpace($sql),$this->trimSpace($selectSql )); + } + + private function trimSpace($sql){ + return preg_replace("/[\t ]+/", '', $sql); + } + + private function _where($type, $where, $value, $group, $logic) { + $method = $logic ? $type : 'or' . ucfirst($type); + $builder = $this->WindMsSqlBuilder->$method($where, $value, $group); + $_where = $this->WindMsSqlBuilder->getSql($type); + return $_where && ($builder instanceof WindSqlBuilder); + } + private function _field($field) { + $params = func_num_args(); + $field = $params > 1 ? func_get_args() : func_get_arg(0); + $builder = $this->WindMsSqlBuilder->field($field); + $field = $this->WindMsSqlBuilder->getSql(WindSqlBuilder::FIELD); + return $field && ($builder instanceof WindSqlBuilder); + } + + private function _join($joinType, $table, $joinWhere, $table_alias, $fields, $schema) { + $joinMethod = 'join' == $joinType ? $joinType: $joinType . 'Join'; + $builder = $this->WindMsSqlBuilder->$joinMethod($table, $joinWhere, $table_alias, $fields, $schema); + $join = $this->WindMsSqlBuilder->getSql(WindSqlBuilder::JOIN); + $field = $fields ? $this->WindMsSqlBuilder->getSql(WindSqlBuilder::FIELD) : true; + return $join && $field && ($builder instanceof WindSqlBuilder); + } +} \ No newline at end of file diff --git a/_tests/component/db/drivers/mssql/WindMsSqlTest.php b/_tests/component/db/drivers/mssql/WindMsSqlTest.php new file mode 100644 index 00000000..dbd1425b --- /dev/null +++ b/_tests/component/db/drivers/mssql/WindMsSqlTest.php @@ -0,0 +1,126 @@ + 2010-12-10 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMsSqlTest extends BaseTestCase { + private $WindMsSql = null; + private $table = 'pw_actions'; + private $selectSql = 'SELECT images,descrip,name FROM pw_actions'; + private $insertSql = "INSERT pw_actions ( images,descrip,name )VALUES ( 'a' ,'b','c' ) "; + private $updateSql = "UPDATE pw_actions SET name= 'suqian' WHERE id = 1"; + private $deleteSql = "DELETE FROM pw_actions WHERE id = 2"; + private $config = array(); + + public function init() { + require_once('component/db/base/IWindDbConfig.php'); + require_once('component/db/drivers/mssql/WindMsSqlBuilder.php'); + require_once('component/db/drivers/mssql/WindMsSql.php'); + if ($this->WindMySql == null) { + $this->config = C::getDataBaseConnection('user'); + $this->WindMsSql = new WindMsSql($this->config); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testGetSqlBuilder() { + $this->assertTrue($this->WindMsSql->getSqlBuilder() instanceof WindMsSqlBuilder); + } + + public function testGetLastSql() { + $this->testQuery(); + $this->assertEquals($this->selectSql, $this->WindMsSql->getLastSql()); + } + + public function testQuery() { + $this->assertTrue($this->WindMsSql->query($this->selectSql)); + } + + public function testGetAffectedRows() { + $this->assertTrue(is_int($this->WindMsSql->getAffectedRows())); + } + + public function testGetLastInsertId() { + $this->assertTrue(is_int($this->WindMsSql->getLastInsertId())); + } + + public function testGetMetaTables() { + $this->assertTrue(is_array($this->WindMsSql->getMetaTables())); + } + + public function testGetMetaTablesBySchema() { + $this->assertTrue(is_array($this->WindMsSql->getMetaTables($this->config[IWindDbConfig::CONN_NAME]))); + } + + public function testGetMetaColumns() { + $this->assertTrue(is_array($this->WindMsSql->getMetaColumns($this->table))); + } + + public function testGetAllRow() { + $this->testQuery(); + $this->assertTrue(is_array($this->WindMsSql->getAllRow(MSSQL_ASSOC))); + } + + public function testGetRow() { + $this->testQuery(); + $this->assertTrue(is_array($this->WindMsSql->getRow(MSSQL_ASSOC))); + } + + public function testInsert() { + $this->assertTrue($this->WindMsSql->insert($this->insertSql)); + } + + public function testUpdate() { + $this->assertTrue($this->WindMsSql->update($this->updateSql)); + } + + public function testDelete() { + $this->assertTrue($this->WindMsSql->update($this->deleteSql)); + } + + public function testGetDriver() { + $this->assertEquals($this->config[IWindDbConfig::CONN_DRIVER], $this->WindMsSql->getDriver()); + } + + public function testGetSchema() { + $this->assertEquals($this->config[IWindDbConfig::CONN_NAME], $this->WindMsSql->getSchema()); + } + + public function testGetConfig() { + $config = $this->WindMsSql->getConfig(); + $this->assertEquals($this->config[IWindDbConfig::CONN_NAME], $config[IWindDbConfig::CONN_NAME]); + } + + public function testGetConnection() { + $this->assertTrue(is_resource($this->WindMsSql->getConnection())); + } + /* + public function testBeginTrans(){ + $this->assertTrue($this->WindMsSql->beginTrans()); + } + + public function testCommitTrans(){ + $this->assertTrue($this->WindMsSql->commitTrans()); + }*/ + + public function __destruct() { + $this->WindMsSql = null; + } +} \ No newline at end of file diff --git a/_tests/component/db/drivers/mysql/WindMySqlBuilderTest.php b/_tests/component/db/drivers/mysql/WindMySqlBuilderTest.php new file mode 100644 index 00000000..b2295ee5 --- /dev/null +++ b/_tests/component/db/drivers/mysql/WindMySqlBuilderTest.php @@ -0,0 +1,354 @@ + 2010-12-10 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMySqlBuilderTest extends BaseTestCase { + + private $config = ''; + private $adapter = null; + private $WindMySqlBuilder = null; + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + private function getDBConfig($parent, $name = '') { + $config = include T_P . '/data/db_config.php'; + return $config[$parent][$name]; + } + public function init() { + require_once('component/db/base/IWindDbConfig.php'); + require_once('component/db/drivers/mysql/WindMySqlBuilder.php'); + require_once('component/db/drivers/mysql/WindMySql.php'); + if ($this->WindMySqlBuilder == null) { + $this->config = $this->getDBConfig('connections', 'phpwind'); + $this->adapter = new WindMySql($this->config); + $this->WindMySqlBuilder = new WindMySqlBuilder($this->adapter); + } + $this->WindMySqlBuilder->reset(); + } + + public static function provider() { + return array(array('pw_posts', '', '', '', ''), array('pw_posts', 'a.uid=pw_posts.authorid', '', '', ''), + array('pw_posts', 'a.uid=b.authorid', 'b', '', ''), + array('pw_posts', 'a.uid=b.authorid', 'b', 'subject,pid', ''), + array('pw_posts', 'a.uid=b.authorid', 'b', 'b.subject,b.pid', ''), + array('pw_posts', 'a.uid=b.authorid', 'b', array('subject', 'pid'), 'phpwind_8')); + } + + public static function providerWhere() { + return array(array('username = "1"', '', ''), array(array('age <= ?', 'uid > ?'), array(3, 4), ''), + array(array('age = 3', 'uid >4'), '', ''), array('uid < ?', 1, ''), + array('username = ? AND uid > ? ', array('"suqian"', 2), '')); + } + + public static function providerOrder() { + return array(array(array('dateline' => 'desc'), true), array('dateline', true), array('age', false), + array(array('dateline' => true, 'age' => false), true)); + } + + public static function providerLimit() { + return array(array(1, 0), array(1, 5)); + } + + public static function providerData() { + return array(array(array('1', '2', '3')), array(array(array('1a', '1b', '1c'), array('2a', '2b', '2c'))), + array(array('username' => array(1, 2, 3), 'age' => array(4, 5, 6)))); + } + + public static function providerSet() { + return array(array('username = "1"', ''), array(array('age <= ?', 'uid > ?'), array(3, 4)), + array(array('age = 3', 'uid >4'), ''), array('uid < ?', 1), + array('username = ? , uid > ? ', array('"suqian"', 2))); + } + + public static function providerAffected() { + return array(array(true), array(false)); + } + + public static function providerPlaceHolder() { + return array(array("id= 1 AND name= 'suqian'", array()), array(array('id= 1', "name= 'suqian'"), array()), + array(array('id=?', 'name=?'), array(1, 'suqian')), array(array('id' => 1, 'name' => 'suqian'), array()), + array('id=? AND name=?', array(1, 'suqian')), + array('id=:id AND name=:name', array(':name' => 'suqian', ':id' => 1))); + } + + /** + * @dataProvider provider + */ + public function testFrom($table, $joinWhere, $table_alias, $fields, $schema) { + $builder = $this->WindMySqlBuilder->from($table, $table_alias, $fields, $schema); + $from = $this->WindMySqlBuilder->getSql(WindSqlBuilder::FROM); + $field = $fields ? $this->WindMySqlBuilder->getSql(WindSqlBuilder::FIELD) : true; + $this->assertTrue($from && $field && ($builder instanceof WindSqlBuilder)); + } + + public function testDistinct() { + $builder = $this->WindMySqlBuilder->distinct(true); + $distinct = $this->WindMySqlBuilder->getSql(WindSqlBuilder::DISTINCT); + $this->assertEquals(WindSqlBuilder::SQL_DISTINCT, $distinct); + $this->assertTrue(($builder instanceof WindSqlBuilder)); + } + + public function testField() { + $this->assertTrue($this->_field('username', 'uid')); + } + + public function testFieldWithArray() { + $this->assertTrue($this->_field(array('username', 'uid'))); + } + + public function testFieldWithParam() { + $this->assertTrue($this->_field('username', 'uid', 'age')); + } + + /** + * @dataProvider provider + */ + public function testJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join('join', $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testLeftJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::LEFT, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testRightJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::RIGHT, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testFullJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::FULL, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testInnerJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::INNER, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider provider + */ + public function testCrossJoin($table, $joinWhere, $table_alias, $fields, $schema) { + $this->assertTrue($this->_join(WindSqlBuilder::CROSS, $table, $joinWhere, $table_alias, $fields, $schema)); + } + + /** + * @dataProvider providerWhere + */ + public function testWhere($where, $value, $group) { + $this->assertTrue($this->_where(WindSqlBuilder::WHERE, $where, $value, $group, true)); + } + + /** + * @dataProvider providerWhere + */ + public function testOrWhere($where, $value, $group) { + $this->assertTrue($this->_where(WindSqlBuilder::WHERE, $where, $value, $group, false)); + } + + public function testGroup() { + $this->assertTrue($this->_field('dateline', 'uid')); + } + + public function testGroupWithArray() { + $this->assertTrue($this->_field(array('dateline', 'uid'))); + } + + public function testGroupWithParam() { + $this->assertTrue($this->_field('username', 'uid')); + } + + /** + * @dataProvider providerWhere + */ + public function testHaving($where, $value, $group) { + $this->assertTrue($this->_where(WindSqlBuilder::HAVING, $where, $value, $group, true)); + } + + /** + * @dataProvider providerWhere + */ + public function testOrHaving($where, $value, $group) { + $this->assertTrue($this->_where(WindSqlBuilder::HAVING, $where, $value, $group, false)); + } + + /** + * @dataProvider providerOrder + */ + public function testOrder($field, $type) { + $builder = $this->WindMySqlBuilder->order($field, $type); + $order = $this->WindMySqlBuilder->getSql(WindSqlBuilder::ORDER); + $this->assertTrue($order && ($builder instanceof WindSqlBuilder)); + } + + /** + *@dataProvider providerLimit + */ + public function testLimit($limit, $offset) { + $builder = $this->WindMySqlBuilder->limit($limit, $offset); + $page = $this->WindMySqlBuilder->getSql(WindSqlBuilder::LIMIT); + $this->assertTrue($page && ($builder instanceof WindSqlBuilder)); + } + + /** + *@dataProvider providerData + */ + public function testData($data) { + $builder = $this->WindMySqlBuilder->data($data); + $data = $this->WindMySqlBuilder->getSql(WindSqlBuilder::DATA); + $this->assertTrue($data && ($builder instanceof WindSqlBuilder)); + } + + /** + * @dataProvider providerSet + */ + public function testSet($field, $value) { + $builder = $this->WindMySqlBuilder->set($field, $value); + $set = $this->WindMySqlBuilder->getSql(WindSqlBuilder::SET); + $this->assertTrue($set && ($builder instanceof WindSqlBuilder)); + } + + public function testGetSelectSql() { + $sql = "SELECT a.username,b.title FROM pw_members AS a LEFT JOIN pw_posts AS b ON a.uid=b.authorid WHERE a.uid != 1 OR a.group > 0 GROUP BY a.age HAVING a.age != 4 ORDER BY dateline DESC "; + $assemblySql = $this->WindMySqlBuilder->from('pw_members', 'a', 'username')->leftJoin('pw_posts', 'a.uid=b.authorid', 'b', 'title')->where('a.uid != ?', 1)->orWhere('a.group > 0')->group('a.age')->having(array( + 'a.age != ?'), array(4))->order('dateline', true)->getSelectSql(); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($assemblySql)); + } + + public function testGetInsertSql() { + $sql = "INSERT pw_members ( name,age )VALUES ( 'a' , 'b' ) , ( 'c' , 'd' ) "; + $insertSql = $this->WindMySqlBuilder->from('pw_members')->field('name', 'age')->data(array(array('a', 'b'), + array('c', 'd')))->getInsertSql(); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($insertSql)); + + } + + public function testGetUpdateSql() { + $sql = "UPDATE pw_members SET username= 'suqian' ,age= 3 WHERE uid = 11 "; + $updateSql = $this->WindMySqlBuilder->from('pw_members')->set('username=?,age=?', array('suqian', 3))->where('uid = 11')->getUpdateSql(); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($updateSql)); + } + + public function testGetReplaceSql() { + $sql = "REPLACE pw_members ( name,age )VALUES ( 'a' , 'b' ) , ( 'c' , 'd' ) "; + $replaceSql = $this->WindMySqlBuilder->from('pw_members')->field('name', 'age')->data(array(array('a', 'b'), + array('c', 'd')))->getReplaceSql(); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($replaceSql)); + } + + public function testGetDeleteSql() { + $sql = "DELETE FROM pw_members AS a WHERE a.uid = 11 "; + $deleteSql = $this->WindMySqlBuilder->from('pw_members', 'a')->where('a.uid = ?', 11)->getDeleteSql(); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($deleteSql)); + } + + /** + * @dataProvider providerAffected + */ + public function testGetAffectedSql($ifquery) { + $sql = 'SELECT ' . ($ifquery ? 'FOUND_ROWS()' : 'ROW_COUNT()') . ' AS afftectedRows'; + $affectedSql = $this->WindMySqlBuilder->getAffectedSql($ifquery); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($affectedSql)); + } + + public function testGetLastInsertIdSql() { + $sql = 'SELECT LAST_INSERT_ID() AS insertId'; + $lastInsertSql = $this->WindMySqlBuilder->getLastInsertIdSql(); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($lastInsertSql)); + } + + public function testGetMetaTableSql() { + $sql = 'SHOW TABLES FROM phpwind'; + $metaTableSql = $this->WindMySqlBuilder->getMetaTableSql('phpwind'); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($metaTableSql)); + } + + public function testGetMetaColumnSql() { + $sql = 'SHOW COLUMNS FROM pw_members'; + $metaColumSql = $this->WindMySqlBuilder->getMetaColumnSql('pw_members'); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($metaColumSql)); + } + + public function testSelect() { + $result = $this->WindMySqlBuilder->from('pw_members', 'a')->from('pw_posts', 'b')->where('a.uid=b.authorid')->where('b.tid >= ? and b.pid < ? and uid IN ?', array( + 2, 1000, array(1, 2, 3, 4, 5, 6, 7, 8)))->field('username', 'uid', 'b.subject')->select()->getAllRow(MYSQL_ASSOC); + $this->assertTrue(is_array($result)); + } + + public function testUpdate() { + $result = $this->WindMySqlBuilder->from('pw_posts')->set('subject=?,buy=?', array('suqian', 3))->where('pid = 1')->update(); + $this->assertTrue($result); + } + + public function testDelete() { + $result = $this->WindMySqlBuilder->from('pw_posts')->where('pid = 2')->delete(); + $this->assertTrue($result); + } + + public function testInsert() { + $result = $this->WindMySqlBuilder->from('pw_actions')->field('images', 'descrip', 'name')->data('a', 'b', 'c')->insert(); + $this->assertTrue($result); + } + + /** + * @dataProvider providerPlaceHolder + */ + public function testPlaceHolder($where, $value) { + $sql = "SELECT name,id,images FROM pw_actions WHERE id= 1 AND name='suqian'"; + $selectSql = $this->WindMySqlBuilder->from('pw_actions')->field('name', 'id', 'images')->where($where, $value)->getSelectSql(); + $this->assertEquals($this->trimSpace($sql), $this->trimSpace($selectSql)); + } + + private function trimSpace($sql) { + return preg_replace("/[\t ]+/", '', $sql); + } + + private function _where($type, $where, $value, $group, $logic) { + $method = $logic ? $type : 'or' . ucfirst($type); + $builder = $this->WindMySqlBuilder->$method($where, $value, $group); + $_where = $this->WindMySqlBuilder->getSql($type); + return $_where && ($builder instanceof WindSqlBuilder); + } + + private function _field($field) { + $params = func_num_args(); + $field = $params > 1 ? func_get_args() : func_get_arg(0); + $builder = $this->WindMySqlBuilder->field($field); + $field = $this->WindMySqlBuilder->getSql(WindSqlBuilder::FIELD); + return $field && ($builder instanceof WindSqlBuilder); + } + + private function _join($joinType, $table, $joinWhere, $table_alias, $fields, $schema) { + $joinMethod = 'join' == $joinType ? $joinType : $joinType . 'Join'; + $builder = $this->WindMySqlBuilder->$joinMethod($table, $joinWhere, $table_alias, $fields, $schema); + $join = $this->WindMySqlBuilder->getSql(WindSqlBuilder::JOIN); + $field = $fields ? $this->WindMySqlBuilder->getSql(WindSqlBuilder::FIELD) : true; + return $join && $field && ($builder instanceof WindSqlBuilder); + } +} \ No newline at end of file diff --git a/_tests/component/db/drivers/mysql/WindMySqlTest.php b/_tests/component/db/drivers/mysql/WindMySqlTest.php new file mode 100644 index 00000000..49c103b7 --- /dev/null +++ b/_tests/component/db/drivers/mysql/WindMySqlTest.php @@ -0,0 +1,126 @@ + 2010-12-10 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMySqlTest extends BaseTestCase { + private $WindMySql = null; + private $table = 'pw_actions'; + private $selectSql = 'SELECT images,descrip,name FROM pw_actions'; + private $insertSql = "INSERT pw_actions ( images,descrip,name )VALUES ( 'a' ,'b','c' ) "; + private $updateSql = "UPDATE pw_actions SET name= 'suqian' WHERE id = 1"; + private $deleteSql = "DELETE FROM pw_actions WHERE id = 2"; + private $config = array(); + + private function getDBConfig($parent, $name = '') { + $config = include T_P . '/data/db_config.php'; + return $config[$parent][$name]; + } + + public function init() { + require_once('component/db/base/IWindDbConfig.php'); + require_once('component/db/drivers/mysql/WindMySqlBuilder.php'); + require_once('component/db/drivers/mysql/WindMySql.php'); + if ($this->WindMySql == null) { + $this->config = $this->getDBConfig('connections', 'phpwind'); + $this->WindMySql = new WindMySql($this->config); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testGetSqlBuilder() { + $this->assertTrue($this->WindMySql->getSqlBuilder() instanceof WindMySqlBuilder); + } + + public function testGetLastSql() { + $this->testQuery(); + $this->assertEquals($this->selectSql, $this->WindMySql->getLastSql()); + } + + public function testQuery() { + $this->assertTrue($this->WindMySql->query($this->selectSql)); + } + + public function testGetAffectedRows() { + $this->assertTrue(is_int($this->WindMySql->getAffectedRows())); + } + + public function testGetLastInsertId() { + $this->assertTrue(is_int($this->WindMySql->getLastInsertId())); + } + + public function testGetMetaTables() { + $this->assertTrue(is_array($this->WindMySql->getMetaTables())); + } + + public function testGetMetaTablesBySchema() { + $this->assertTrue(is_array($this->WindMySql->getMetaTables($this->config[IWindDbConfig::CONN_NAME]))); + } + + public function testGetMetaColumns() { + $this->assertTrue(is_array($this->WindMySql->getMetaColumns($this->table))); + } + + public function testGetAllRow() { + $this->testQuery(); + $this->assertTrue(is_array($this->WindMySql->getAllRow(MYSQL_ASSOC))); + } + + public function testGetRow() { + $this->testQuery(); + $this->assertTrue(is_array($this->WindMySql->getRow(MYSQL_ASSOC))); + } + + public function testInsert() { + $this->assertTrue($this->WindMySql->insert($this->insertSql)); + } + + public function testUpdate() { + $this->assertTrue($this->WindMySql->update($this->updateSql)); + } + + public function testDelete() { + $this->assertTrue($this->WindMySql->update($this->deleteSql)); + } + + public function testGetDriver() { + $this->assertEquals($this->config[IWindDbConfig::CONN_DRIVER], $this->WindMySql->getDriver()); + } + + public function testGetSchema() { + $this->assertEquals($this->config[IWindDbConfig::CONN_NAME], $this->WindMySql->getSchema()); + } + + public function testGetConfig() { + $config = $this->WindMySql->getConfig(); + $this->assertEquals($this->config[IWindDbConfig::CONN_NAME], $config[IWindDbConfig::CONN_NAME]); + } + + public function testGetConnection() { + $this->assertTrue(is_resource($this->WindMySql->getConnection())); + } + + public function testTransAction(){ + $this->assertTrue($this->WindMySql->beginTrans()); + //$this->assertTrue($this->WindMySql->commitTrans()); + } + + +} \ No newline at end of file diff --git a/_tests/component/form/AllFormTest.php b/_tests/component/form/AllFormTest.php new file mode 100644 index 00000000..9a82a7ec --- /dev/null +++ b/_tests/component/form/AllFormTest.php @@ -0,0 +1,23 @@ + 2011-1-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('component/form/WindActionFormTest.php'); +//require_once ('component/form/WindFormFilterTest.php'); + +class AllFormTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllFormTest'); + $suite->addTestSuite('WindActionFormTest'); + //$suite->addTestSuite('WindFormFilterTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/component/form/WindActionFormTest.php b/_tests/component/form/WindActionFormTest.php new file mode 100644 index 00000000..1b20fdef --- /dev/null +++ b/_tests/component/form/WindActionFormTest.php @@ -0,0 +1,62 @@ + 2010-12-9 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +class WindActionFormTest extends BaseTestCase { + private $obj; + public function setUp() { + parent::setUp(); + require_once('data/TestForm.php'); + $this->obj = new TestForm(); + } + public function tearDown() { + parent::tearDown(); + } + public function testGetIsValidation() { + $this->assertTrue($this->obj->getIsValidation()); + } + public function testSetProperties() { + $array = array('name' => 'php', 'password' => 'phpwind.net', 'address' => 'china', '_isValidate' => true, + 'site' => 'www.phpwind.net'); + $this->obj->setProperties($array); + $this->assertTrue($this->obj->getIsValidation()); + $this->assertEquals('php', $this->obj->getName()); + $this->assertEquals('phpwind.net', $this->obj->getPassword()); + $this->assertEquals('china', $this->obj->getAddress()); + } + + public function testValidationAndGetError() { + $error = $this->obj->getError(); + $this->assertTrue(is_array($error) && count($error) == 0); + $this->obj->validation(); + $error = $this->obj->getError(); + $this->assertTrue(is_array($error) && ('name too short' == $error['nameError']) && count($error) == 1); + } + public function testAddError() { + $this->assertFalse($this->obj->addError('')); + $array = array('name' => 'php', 'password' => 'phpwind.net', 'address' => 'china', '_isValidate' => true, + 'site' => 'www.phpwind.net'); + $this->obj->addError($array); + $error = $this->obj->getError(); + $this->assertTrue(is_array($error) && count($error) == 5); + $this->assertTrue('php' == $error['name'] && 'phpwind.net' == $error['password']); + $this->obj->addError('ppp'); + $this->assertEquals('ppp', $this->obj->getError(0)); + } + + public function testGetErrorAction() { + list($action, $actionClass) = $this->obj->getErrorAction(); + $this->assertTrue($action == 'showError' && $actionClass = 'error'); + $this->obj->setErrorAction('controller.ErrorController'); + list($action, $actionClass) = $this->obj->getErrorAction(); + $this->assertTrue($actionClass == 'controller.ErrorController' && $action = 'run'); + } + public function testSetIsValidation() { + $this->obj->setIsValidation(false); + $this->assertFalse($this->obj->getIsValidation()); + } +} + diff --git a/_tests/component/form/WindFormFilterTest.php b/_tests/component/form/WindFormFilterTest.php new file mode 100644 index 00000000..8cc1cf93 --- /dev/null +++ b/_tests/component/form/WindFormFilterTest.php @@ -0,0 +1,55 @@ + 2010-12-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * WindFormFilter单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ + +class WindFormFilterTest extends BaseTestCase { + private $obj; + private $request; + private $response; + + public function setUp() { + parent::setUp(); + require_once ('component/form/WindFormFilter.php'); + require_once ('component/form/WindActionForm.php'); + require_once ('core/request/WindHttpRequest.php'); + require_once ('core/response/WindHttpResponse.php'); + require_once ('core/config/WindSystemConfig.php'); + $array = array('extensionConfig' => array('formConfig' => 'TEST:data.formConfig')); + $systemConfig = new WindSystemConfig($array, 'testApp'); + $_GET['name'] = 'phpwind'; + $_GET['address'] = 'hz'; + $_GET['nick'] = 'xiaxia'; + $_GET['formName'] = 'TestForm'; + $this->request = new WindHttpRequest(); + $this->response = $this->request->getResponse(); + $dispatcher = new WindWebDispatcher($this->request, $this->response); + $dispatcher->module = 'default'; + $this->response->setDispatcher($dispatcher); + Wind::register(dirname(dirname(dirname(__FILE__))) . D_S, 'TEST'); + $this->obj = new WindFormFilter(); + } + public function tearDown() { + parent::setUp(); + $this->obj = null; + $this->request = null; + $this->response = null; + } + public function testDoBeforeProcess() { + $this->obj->doBeforeProcess($this->request, $this->response); + $formObj = $this->response->getData('TestForm'); + $this->assertTrue($formObj instanceof WindActionForm); + } +} diff --git a/_tests/component/format/AllFormatTest.php b/_tests/component/format/AllFormatTest.php new file mode 100644 index 00000000..c2650cd1 --- /dev/null +++ b/_tests/component/format/AllFormatTest.php @@ -0,0 +1,25 @@ + 2011-1-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('component/format/WindDateTest.php'); +require_once ('component/format/WindStringGBKTest.php'); +require_once ('component/format/WindStringUTF8Test.php'); + +class AllFormatTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllFormatTest'); + $suite->addTestSuite('WindDateTest'); + $suite->addTestSuite('WindStringGBKTest'); + $suite->addTestSuite('WindStringUTF8Test'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/component/log/AllLogTest.php b/_tests/component/log/AllLogTest.php new file mode 100644 index 00000000..2cdf5e27 --- /dev/null +++ b/_tests/component/log/AllLogTest.php @@ -0,0 +1,23 @@ + 2011-1-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('component/log/WindDebugTest.php'); +require_once ('component/log/WindLoggerTest.php'); + +class AllLogTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllLogTest'); + $suite->addTestSuite('WindDebugTest'); + $suite->addTestSuite('WindLoggerTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/component/log/WindDebugTest.php b/_tests/component/log/WindDebugTest.php new file mode 100644 index 00000000..76551303 --- /dev/null +++ b/_tests/component/log/WindDebugTest.php @@ -0,0 +1,91 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindDebugTest extends BaseTestCase { + + public function init() { + require_once ('component/Log/WindDebug.php'); + } + + public function setUp() { + parent::setUp(); + date_default_timezone_set('UTC'); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testGetMemUsage(){ + $this->assertTrue(is_float(WindDebug::getMemUsage())); + } + + public function testGetExecTime(){ + $this->assertTrue(is_float(WindDebug::getExecTime())); + } + + public function testGetMemUsageOfp2p(){ + WindDebug::setBreakPoint('start'); + for($i=0;$i<10;$i++){ + $i++; + } + WindDebug::setBreakPoint('end'); + $mem = WindDebug::getMemUsageOfp2p('start','end'); + $this->assertTrue(is_float($mem)); + } + + public function testGetExecTimeOfp2p(){ + WindDebug::setBreakPoint('start'); + for($i=0;$i<10;$i++){ + $i++; + } + WindDebug::setBreakPoint('end'); + $time = WindDebug::getExecTimeOfp2p('start','end'); + $this->assertTrue(is_float($time)); + } + + public function testTrace(){ + $this->assertTrue(is_array(WindDebug::trace())); + } + + public function testDebug(){ + $this->assertTrue(is_string(WindDebug::debug("suqian"))); + } + + public function testDebugWithBreakPoint(){ + WindDebug::setBreakPoint('start'); + for($i=0;$i<10;$i++){ + $i++; + } + WindDebug::setBreakPoint('end'); + $this->assertTrue(is_string(WindDebug::debug("suqian",array(),'start','end'))); + } + + public function testRemoveBreakPoint(){ + WindDebug::setBreakPoint('break'); + $break = WindDebug::getBreakPoint('break'); + $this->assertTrue(is_array($break)); + WindDebug::removeBreakPoint('break'); + $break = WindDebug::getBreakPoint('break'); + $this->assertTrue(empty($break)); + + } + + public function testGetIncludeFiles(){ + $includeFiles = WindDebug::loadFiles(); + $this->assertTrue(is_array($includeFiles)); + } +} \ No newline at end of file diff --git a/_tests/component/log/WindLoggerTest.php b/_tests/component/log/WindLoggerTest.php new file mode 100644 index 00000000..734b4d80 --- /dev/null +++ b/_tests/component/log/WindLoggerTest.php @@ -0,0 +1,60 @@ + + * @author xiaoxia xu + * @version $Id$ 2011-1-21 + * @package + */ +define('LOG_PATH', COMPILE_PATH . '/log/'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ 2011-1-21 + * @package + */ +class WindLoggerTest extends BaseTestCase { + private $logger = null; + public function init() { + require_once ('component/Log/WindLogger.php'); + $this->logger = new WindLogger(); + } + + public function setUp() { + parent::setUp(); + date_default_timezone_set('PRC'); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public static function provider() { + return array( + array('i am info!', 0), + array('i am trace!', 1), + array('debug is here!', 2), + array('sorry, there is a error', 3), + array('haha'), + ); + } + + /** + * @dataProvider provider + */ + public function testLog($msg, $type = 0) { + $this->logger->log($msg, $type); + $this->assertTrue($this->logger->flush()); + } + + public function testFlush() { + $this->logger->info('hello i am testing!'); + $this->logger->trace('Statck trace:'); + $this->logger->debug('Debug Echo '); + $this->logger->error('Error access'); + $this->assertTrue($this->logger->flush()); + } + public function testClearFiles() { + $this->assertTrue($this->logger->clearFiles()); + } +} \ No newline at end of file diff --git a/_tests/component/mail/AllMailTest.php b/_tests/component/mail/AllMailTest.php new file mode 100644 index 00000000..f70f3cd0 --- /dev/null +++ b/_tests/component/mail/AllMailTest.php @@ -0,0 +1,32 @@ + 2011-1-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('component/mail/protocol/WindImapTest.php'); +require_once ('component/mail/protocol/WindPop3Test.php'); +require_once ('component/mail/protocol/WindSmtpTest.php'); +require_once ('component/mail/protocol/WindSocketTest.php'); + +require_once ('component/mail/send/WindSmtpSendTest.php'); +require_once ('component/mail/WindMailTest.php'); + +class AllMailTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllMailTest'); + //$suite->addTestSuite('WindImapTest'); + //$suite->addTestSuite('WindPop3Test'); + //$suite->addTestSuite('WindSmtpTest'); + $suite->addTestSuite('WindSocketTest'); + //$suite->addTestSuite('WindSmtpSendTest'); + $suite->addTestSuite('WindMailTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/component/mail/WindMailTest.php b/_tests/component/mail/WindMailTest.php new file mode 100644 index 00000000..859f7c44 --- /dev/null +++ b/_tests/component/mail/WindMailTest.php @@ -0,0 +1,189 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMailTest extends BaseTestCase { + private $mail = null; + + public function init() { + require_once ('component/mail/WindMail.php'); + if (null === $this->mail) { + $this->mail = new WindMail(); + } + } + + public function setUp() { + parent::setUp(); + date_default_timezone_set('UTC'); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + public static function providerMail() { + return array(array('635927818@qq.com', 'suqian'), array('635927818@qq.com', 1)); + } + + /** + * @dataProvider providerMail + */ + public function testTo($mail, $name) { + $this->mail->setTo($mail, $name); + $to = $this->mail->getTo(); + $this->assertArrayHasKey($name, $to); + $this->assertTrue($mail == $to[$name]); + } + /** + * @dataProvider providerMail + */ + public function testCc($mail, $name) { + $this->mail->setCc($mail, $name); + $cc = $this->mail->getCc(); + $this->assertArrayHasKey($name, $cc); + $this->assertTrue($mail == $cc[$name]); + } + + /** + * @dataProvider providerMail + */ + public function testBcc($mail, $name) { + $this->mail->setBcc($mail, $name); + $bcc = $this->mail->getBCc(); + $this->assertArrayHasKey($name, $bcc); + $this->assertTrue($mail == $bcc[$name]); + } + + public function testFrom() { + $this->mail->setFrom('635927818@qq.com'); + $from = $this->mail->getFrom(); + $this->assertTrue('635927818@qq.com' == $from); + } + + public function testSubject() { + $this->mail->setSubject('subject'); + $this->mail->setSubject('reSubject'); + $subject = $this->mail->getSubject(); + $this->assertTrue('reSubject' == $subject); + } + + public function testChineseDate() { + $this->mail->setDate(); + $date = $this->mail->getMailHeader(WindMail::DATE); + $this->assertTrue(WindGeneralDate::getChinaDate() == $date[0]); + } + + public function testRFCDate() { + $this->mail->setDate(null, false); + $date = $this->mail->getMailHeader(WindMail::DATE); + $this->assertTrue(WindGeneralDate::getRFCDate() == $date[0]); + } + + public function testMessageId() { + $this->mail->setMessageId(null, false); + $messageId = $this->mail->getMailHeader(WindMail::MESSAGEID); + $this->assertTrue(is_array($messageId) && is_string($messageId[0])); + } + + public function testBodyHtml() { + $this->mail->setBodyHtml('test suqian go'); + $html = $this->mail->getBodyHtml(); + $this->assertTrue('test suqian go' == $html); + } + + public function testBodyText() { + $this->mail->setBodyText('test suqian go'); + $text = $this->mail->getBodyText(); + $this->assertTrue('test suqian go' == $text); + } + + public function testContentTypeWithText() { + $this->mail->setBodyText('test suqian go'); + $this->mail->setContentType(); + $contentType = $this->mail->getMailHeader(WindMail::CONTENTTYPE); + $this->assertTrue(is_string($contentType[0])); + } + + public function testContentTypeWithHtml() { + $this->mail->setBodyHtml('test phpwind go'); + $this->mail->setContentType(); + $contentType = $this->mail->getMailHeader(WindMail::CONTENTTYPE); + $this->assertTrue(is_string($contentType[0])); + } + + public function testContentTypeWithTextAndHtml() { + $this->mail->setBodyHtml('test phpwind go'); + $this->mail->setBodyText('test suqian go'); + $this->mail->setContentType(); + $contentType = $this->mail->getMailHeader(WindMail::CONTENTTYPE); + $this->assertTrue(is_string($contentType[0])); + } + + public function testContentTypeWithEmbed() { + $this->mail->setBodyHtml('test phpwind go'); + $this->mail->setAttachment('./maze.png', 'image/png', WindMail::DIS_INLINE, WindMail::ENCODE_QP); + $this->mail->setEmbed(true); + $this->mail->setContentType(); + $contentType = $this->mail->getMailHeader(WindMail::CONTENTTYPE); + $this->assertTrue(is_string($contentType[0])); + } + + public function testContentTypeWithAttach() { + $this->mail->setBodyHtml('test phpwind go'); + $this->mail->setAttachment('./maze.png', 'image/png', WindMail::DIS_INLINE, WindMail::ENCODE_QP); + $this->mail->setEmbed(false); + $this->mail->setCharset('gbk'); + $this->mail->setContentType(); + $contentType = $this->mail->getMailHeader(WindMail::CONTENTTYPE); + $this->assertTrue(is_string($contentType[0])); + } + + public function testGetRecipients() { + $mail = self::providerMail(); + $this->mail->setCc($mail[0][0], $mail[0][1]); + $this->mail->setTo($mail[1][0], $mail[1][1]); + $recipients = $this->mail->getRecipients(); + $this->assertTrue(is_array($recipients) && count($mail) == count($recipients)); + } + + public function testSend() { + $this->mail->clearAll(); + $this->mail->setFrom('635927818@qq.com'); + $this->mail->setTo('635927818@qq.com'); + $this->mail->setTo('aoxue.1988.su.qian@163.com'); + $this->mail->setCc('weihu@aliyun-inc.com'); + $this->mail->setBcc('594524924@qq.com', 'ha'); + $this->mail->setSubject("test mail "); + $this->mail->setDate(); + $this->mail->setBodyHtml("test itaaa"); + $this->mail->setContentEncode(WindMail::ENCODE_BASE64); + $this->mail->setAttachment(__FILE__, 'application/x-httpd-php', WindMail::DIS_INLINE, WindMail::ENCODE_QP); + $header = $this->mail->createHeader(); + $body = $this->mail->createBody(); + $this->assertTrue(is_string($header) && is_string($body)); + $config = array('host'=>'smtp.qq.com','port'=>25,'name'=>'qq.com','auth'=>true,'user'=>'635927818@qq.com','password'=>''); + $this->mail->send(WindMail::SEND_SMTP,$config); + } + + public function testEncodeHeader(){ + $string = 'test encode header中国'; + $base64 = '=?gbk?B?dGVzdCBlbmNvZGUgaGVhZGVy5Lit5Zu9?==?gbk?B??='; + $qp = '=?gbk?Q?test=20encode=20header=E4=B8=AD=E5=9B=BD?='; + $encode = $this->mail->encodeHeader($string,WindMail::ENCODE_BASE64); + $this->assertTrue($base64 == strtr(trim($encode),array("\n"=>'',' '=>''))); + $encode = $this->mail->encodeHeader($string,WindMail::ENCODE_QP); + $this->assertTrue($qp == trim($encode)); + } + +} \ No newline at end of file diff --git a/_tests/component/mail/protocol/WindImapTest.php b/_tests/component/mail/protocol/WindImapTest.php new file mode 100644 index 00000000..114e6fb0 --- /dev/null +++ b/_tests/component/mail/protocol/WindImapTest.php @@ -0,0 +1,256 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * WindImap单元测试 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindImapTest extends BaseTestCase { + private $imap = null; + + public function init() { + require_once ('component/mail/protocol/WindImap.php'); + if (null === $this->imap) { + $this->imap = new WindImap('imap.163.com', 143); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + /** + * @dataProvider providerLogin + */ + public function testOpen(){ + $this->assertContains('OK',$this->imap->open()); + } + /** + *@dataProvider providerLogin + */ + public function testLogin($username,$password){ + $this->assertContains('OK',$this->imap->open()); + $this->assertContains('OK',$this->imap->login($username,$password)); + } + + public function testCreate(){ + $this->login(); + $this->assertContains('OK',$this->imap->create('test')); + } + + public function testDelete(){ + $this->login(); + $this->assertContains('OK',$this->imap->delete('test')); + } + + public function testRename(){ + $this->login(); + $this->assertContains('OK',$this->imap->create('test')); + $this->assertContains('OK',$this->imap->rename('test','tests')); + $this->assertContains('OK',$this->imap->delete('tests')); + } + + /** + * @dataProvider providerList + */ + public function testFolderOfmail($base,$template){ + $this->login(); + $this->assertContains('OK',$this->imap->folderOfMail($base,$template)); + } + + public function testSelect(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + } + + /** + * @dataProvider providerFetchs + */ + public function testFetch($mail,$fetch){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->fetch($mail,$fetch)); + } + + public function testFetchHeader(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->fetchHeader(1)); + } + /** + * @dataProvider providerHeaderFields + */ + public function testFetchHeaderFields($mail,$fields){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->fetchHeaderFields($mail,$fields)); + } + + /** + * @dataProvider providerHeaderFields + */ + public function testFetchHeaderNotFields($mail,$fields){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->fetchHeaderNotFields($mail,$fields)); + } + + public function testFetchText(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->fetchText(1)); + } + + public function testFetchSection(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->fetchBySection(1,WindImap::HEADER)); + } + + public function testFetchPartialOfSection(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->fetchPartialOfSection(1,2,10)); + } + + + public function testStore(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->store(1)); + } + + public function testStripStore(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->stripStore(1)); + } + + public function testExamine(){ + $this->login(); + $this->assertContains('OK',$this->imap->examine('inbox')); + } + + public function testExpunge(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->expunge()); + } + + public function testSubscribe(){ + $this->login(); + $this->assertContains('OK',$this->imap->subscribe('new')); + } + + public function testUnsubscribe(){ + $this->login(); + $this->assertContains('OK',$this->imap->unsubscribe('new')); + } + /** + * @dataProvider providerList + */ + public function testLsub($base,$template){ + $this->login(); + $this->assertContains('OK',$this->imap->folderOfMail($base,$template)); + } + /** + * @dataProvider providerStatus + */ + public function testStatus($mailbox,$status){ + $this->login(); + $this->assertContains('OK',$this->imap->status($mailbox,$status)); + } + /** + * @dataProvider providerSearch + */ + public function testSearch($criteria,$value){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->search($criteria,$value)); + } + + + public function testCapability(){ + $this->login(); + $this->assertContains('OK',$this->imap->capability()); + } + + public function testCopy(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->copy(1,'phpwind')); + + } + + public function testClose(){ + $this->login(); + $this->assertContains('OK',$this->imap->select('inbox')); + $this->assertContains('OK',$this->imap->check()); + $this->assertContains('OK',$this->imap->close('inbox')); + + } + + public function testLogOut(){ + //$this->login(); + //$this->assertContains('OK',$this->imap->logout()); + } + public function login() { + $this->imap->open(); + $login = self::providerLogin(); + $this->imap->login($login[0][0], $login[0][1]); + } + + public static function providerSearch(){ + return array( + array('KEYWORD','test'), + array('SUBJECT','a'), + array('ALL',null) + ); + } + public static function providerStatus(){ + return array( + array('inbox','MESSAGES'), + array('inbox',array('MESSAGES','RECENT')) + ); + } + public static function providerHeaderFields(){ + return array( + array(1,'Subject'), + array(1,array('Subject,Date')), + array(1,array('Subject,Date,Content-Type')) + ); + } + + public static function providerFetchs(){ + return array( + array(1,'ALL'), + array('1:2','BODY'), + array(1,'BODYSTRUCTUR'), + array(1,'FULL'), + array(1,'FAST') + ); + } + + + public static function providerList(){ + return array( + array('/','*') + ); + } + public static function providerLogin() { + return array(array('aoxue.1988.su.qian@163.com', '')); + } +} \ No newline at end of file diff --git a/_tests/component/mail/protocol/WindPop3Test.php b/_tests/component/mail/protocol/WindPop3Test.php new file mode 100644 index 00000000..19a99d57 --- /dev/null +++ b/_tests/component/mail/protocol/WindPop3Test.php @@ -0,0 +1,102 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +class WindPop3Test extends BaseTestCase { + private $pop3 = null; + + public function init() { + require_once ('component/mail/protocol/WindPop3.php'); + if (null === $this->pop3) { + $this->pop3 = new WindPop3('pop.qq.com', 110); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testOpen(){ + $this->assertTrue(is_string($this->pop3->open())); + } + + /** + * @dataProvider providerLogin + */ + public function testLogin($username,$passwrod){ + $this->pop3->open(); + $this->assertContains('OK',$this->pop3->login($username,$passwrod)); + } + + public function testStat(){ + $this->login(); + $this->assertTrue(is_array($this->pop3->stat())); + } + + public function testUidl(){ + $this->login(); + $this->assertTrue(is_array($this->pop3->uidl())); + $this->assertTrue(is_array($this->pop3->uidl(1))); + } + + public function testGetList(){ + $this->login(); + $this->assertTrue(is_array($this->pop3->getList())); + $this->assertTrue(is_array($this->pop3->getList(1))); + } + + public function testRetr(){ + $this->login(); + $str = $this->pop3->retr(1); + $this->assertTrue(is_string($str)); + $str = $this->pop3->getMailContent($str); + $this->assertTrue(is_array($str) && count($str) === 2); + + } + + public function testDele(){ + $this->login(); + $this->assertContains('OK',$this->pop3->dele(1)); + //$this->assertContains('Bye',$this->pop3->quit()); + } + + public function testRset(){ + $this->login(); + $this->assertContains('OK',$this->pop3->dele(1)); + $this->assertContains('OK',$this->pop3->rset(1)); + } + + public function testTop(){ + $this->login(); + $this->assertTrue(is_string($this->pop3->top(1))); + $this->assertTrue(is_string($this->pop3->top(1,2))); + $this->assertContains('OK',$this->pop3->noop()); + //$this->assertContains('Bye',$this->pop3->quit()); + + } + + + + public function login(){ + $this->pop3->open(); + $login = self::providerLogin(); + $this->pop3->login($login[0][0],$login[0][1]); + } + + + public static function providerLogin(){ + return array( + array('635927818@qq.com','') + ); + } +} \ No newline at end of file diff --git a/_tests/component/mail/protocol/WindSmtpTest.php b/_tests/component/mail/protocol/WindSmtpTest.php new file mode 100644 index 00000000..f72f3ad7 --- /dev/null +++ b/_tests/component/mail/protocol/WindSmtpTest.php @@ -0,0 +1,58 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +class WindSmtpTest extends BaseTestCase { + private $smtp = null; + + public function init() { + require_once ('component/mail/protocol/WindSmtp.php'); + if (null === $this->smtp) { + $this->smtp = new WindSmtp('smtp.qq.com', 25); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + /** + * 根据测试填写上自己的测试邮箱 + */ + public static function provider() { + return array(array('qq.com', '961412979@qq.com', '', '961412979@qq.com', '961412979@qq.com')); + } + /** + * @dataProvider provider + */ + public function testSend($ehlo, $loginMail, $loginPwd, $from, $to) { + $this->smtp->open(); + $this->smtp->ehlo($ehlo); + $this->smtp->authLogin($loginMail, $loginPwd); + $this->smtp->mailFrom($from); + $this->smtp->rcptTo($to); + //$smtp->rcptTo('1752585926@qq.com testa'); + $data = "From: {$from}\n"; + $data .= "To: {$to}\n"; + $data .= "Cc: {$to},afafa 402289603@qq.com\n"; + $data .= "Date: Mon, 25 Oct 2004 14:24:27 +0800\n"; + $data .= "Subject: test mail\n\n"; + $data .= "Hi,test2\nThis is a test mail,you don't reply it.only test sendmail is not incorrect + "; + $this->smtp->data($data); + $this->smtp->noop(); + $this->smtp->close(); + $this->assertTrue(true); + } + +} \ No newline at end of file diff --git a/_tests/component/mail/protocol/WindSocketTest.php b/_tests/component/mail/protocol/WindSocketTest.php new file mode 100644 index 00000000..f31b687a --- /dev/null +++ b/_tests/component/mail/protocol/WindSocketTest.php @@ -0,0 +1,74 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSocketTest extends BaseTestCase { + private $socket = null; + + public function init() { + require_once ('component/mail/protocol/WindSocket.php'); + if (null === $this->socket) { + $url = 'www.phpwind.net'; + $this->socket = new WindSocket($url, 80); + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testOpen() { + $this->assertTrue(!is_resource($this->socket->getSocket())); + $this->socket->open(); + $this->assertTrue(is_resource($this->socket->getSocket())); + } + + public function testClose() { + $this->socket->open(); + $this->assertTrue($this->socket->close()); + } + + public function testRequest() { + $this->assertTrue(0 < (int) ($this->request())); + } + + public function testResponse() { + $this->request(); + $this->assertTrue(0 < strlen($this->socket->response())); + } + + public function testResponseLine() { + $this->request(); + $this->assertTrue(0 < strlen($this->socket->responseLine())); + } + + public function testSetSocketTimeOut() { + $this->socket->open(); + $this->assertTrue($this->socket->setSocketTimeOut(8)); + } + + public function request() { + $this->socket->open(); + $request = "GET http://www.phpwind.net HTTP/1.1\n"; + $request .= "Host: www.phpwind.net\n"; + $request .= "Connection: Close\n"; + $request .= "\n"; + return $this->socket->request($request); + } +} \ No newline at end of file diff --git a/_tests/component/mail/send/WindSmtpSendTest.php b/_tests/component/mail/send/WindSmtpSendTest.php new file mode 100644 index 00000000..5c654d55 --- /dev/null +++ b/_tests/component/mail/send/WindSmtpSendTest.php @@ -0,0 +1,53 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +class WindSmtpSendTest extends BaseTestCase { + /* @var $sender WindSmtpMail*/ + private $sender = null; + /** + * @var $mail WindMail + */ + private $mail = null; + + public function init() { + require_once ('component/mail/WindMail.php'); + require_once ('component/mail/sender/WindSmtpMail.php'); + if (null === $this->sender) { + $config = array('host'=>'smtp.qq.com','port'=>25,'name'=>'qq.com','auth'=>true,'user'=>'635927818@qq.com','password'=>''); + + $this->sender = new WindSmtpMail($config); + $this->mail = new WindMail(); + } + } + + public function setUp() { + parent::setUp(); + date_default_timezone_set('UTC'); + $this->init(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testSend(){ + $this->mail->clearAll(); + $this->mail->setFrom('635927818@qq.com'); + $this->mail->setTo('635927818@qq.com'); + $this->mail->setCc('635927818@qq.com'); + $this->mail->setBcc('635927818@qq.com', 'ha'); + $this->mail->setSubject("test mail "); + $this->mail->setDate(); + $this->mail->setBodyHtml("test itaaa"); + $this->mail->setContentEncode(WindMail::ENCODE_BASE64); + $this->mail->setAttachment(__FILE__, 'application/x-httpd-php', WindMail::DIS_INLINE, WindMail::ENCODE_QP); + $this->sender->send($this->mail); + + } +} \ No newline at end of file diff --git a/_tests/component/parser/AllParserTest.php b/_tests/component/parser/AllParserTest.php new file mode 100644 index 00000000..2d4d7989 --- /dev/null +++ b/_tests/component/parser/AllParserTest.php @@ -0,0 +1,25 @@ + 2011-1-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +include('component/parser/WindIniParserTest.php'); +include('component/parser/WindPropertiesParserTest.php'); +include('component/parser/WindXmlParserTest.php'); + +class AllParserTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllParserTest'); + $suite->addTestSuite('WindIniParserTest'); + $suite->addTestSuite('WindPropertiesParserTest'); + $suite->addTestSuite('WindXmlParserTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/component/parser/WindIniParserTest.php b/_tests/component/parser/WindIniParserTest.php new file mode 100644 index 00000000..52259c67 --- /dev/null +++ b/_tests/component/parser/WindIniParserTest.php @@ -0,0 +1,128 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +require_once('component/parser/WindIniParser.php'); + +/** + * WindIniParser单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindIniParserTest extends BaseTestCase { + private $parser; + private $path; + public function __construct() { + $this->parser = new WindIniParser(); + $this->path = dirname(dirname(dirname(__FILE__))); + } + + private function checkArray($array, $num, $member = array(), $flag = false) { + $this->assertTrue(is_array($array)); + $this->assertEquals($num, count($array)); + if (!$member) return; + if (!$flag) { + foreach ((array)$member as $key) { + $this->assertTrue(isset($array[$key])); + } + } else { + foreach ((array)$member as $key => $value) { + $this->assertTrue(isset($array[$key])); + $this->assertTrue($array[$key] == $value); + } + } + + } + public function testParser() { + $data = $this->parser->parse($this->path . '/data/WindIniParserTest.ini'); + $this->checkArray($data, 6, array('people', 'xxx', 'xjx', 'student')); + $this->assertTrue($data['name'] == 'test'); + $this->checkArray($data['people'], 3, array('name', 'sex', 'job')); + $this->checkArray($data['xxx'], 3, array('name', 'school', 'sex')); + $this->checkArray($data['xjx'], 3, array('address' => 'china', 'sex' => '0', 'job' => 'java'), true); + $this->checkArray($data['student'], 4, array('name', 'school', 'home')); + $this->checkArray($data['student']['home'], 1, array('address')); + $this->checkArray($data['student']['home']['address'], 3, array('country' => 'china', + 'city' => 'jinh', 'town' => 'changs'), true); + } + + public function testParserWithNull() { + $data = $this->parser->parse(''); + $this->checkArray($data, 0); + } + + public function testBuildWithEmpty() { + $p = ''; + $this->assertEquals('', $this->parser->buildData($p)); + //$this->checkArray($this->parser->buildData(array()), 0); + } + public function testBuildWithObject() { + $data = $this->parser->buildData($this->parser); + $this->assertTrue(is_object($data)); + } + + public function testToArrayWithEmpty() { + $value = $this->parser->toArray('', ''); + $this->assertTrue(is_array($value) && (count($value) === 0)); + } + + public function testToArrayWithFirstValue() { + $value = $this->parser->toArray('key', ''); + $this->assertTrue(is_array($value) && (count($value) === 1) && empty($value['key'])); + } + + public function testToArrayWithSecondValue() { + $value = $this->parser->toArray('', 'key'); + $this->assertTrue(is_array($value) && (count($value) === 1) && ($value[''] == 'key')); + } + + public function testToArray() { + $value = $this->parser->toArray('key1.key2.key3.key4', 'value'); + $this->assertTrue(is_array($value) && ($value['key1']['key2']['key3']['key4'] === 'value')); + } + + public function testFormatDataFromStringWithString() { + $data = array(); + $value = $this->parser->formatDataFromString('key', 'value', $data); + $this->assertTrue(is_array($value) && (count($value) == 1) && ($value['key'] == 'value')); + } + public function testFormatDataFromStringWithNoData() { + $data = array(); + $value = $this->parser->formatDataFromString('key1.key2.key3', 'value', $data); + $this->assertTrue(is_array($value) && (count($value) == 1) && ($value['key1']['key2']['key3'] == 'value')); + } + public function testFormatDataFromStringWithSameKeyData() { + $data = array('key1' => 'xxx'); + $value = $this->parser->formatDataFromString('key1.key2.key3', 'value', $data); + $this->assertTrue(is_array($value) && (count($value) == 1) && ($value['key1']['key2']['key3'] == 'value')); + } + public function testFormatDataFromString() { + $data = array('name' => 'xxx'); + $value = $this->parser->formatDataFromString('key1.key2.key3', 'value', $data); + $this->assertTrue(is_array($value) && (count($value) == 2)); + $this->assertTrue($value['key1']['key2']['key3'] == 'value'); + $this->assertTrue($value['name'] == 'xxx'); + } + public function testFormatDataArray() { + $data = array('name' => 'xxx'); + $param = array('key1.key2' => 'value1', 'key2.key3' => 'value2', 'key3' => 'value3'); + $value = $this->parser->formatDataArray($param, $data); + $this->assertTrue(is_array($value) && (count($value) == 4)); + $this->assertTrue($value['key1']['key2'] == 'value1'); + $this->assertTrue($value['name'] == 'xxx'); + $this->assertTrue($value['key2']['key3'] == 'value2'); + $this->assertTrue($value['key3'] == 'value3'); + } + public function testFormatDataArrayWithEmpty() { + $data = array(); + $param = array(); + $value = $this->parser->formatDataArray($param, $data); + $this->assertTrue(is_array($value) && (count($value) == 0)); + } +} \ No newline at end of file diff --git a/_tests/component/parser/WindPropertiesParserTest.php b/_tests/component/parser/WindPropertiesParserTest.php new file mode 100644 index 00000000..20053af0 --- /dev/null +++ b/_tests/component/parser/WindPropertiesParserTest.php @@ -0,0 +1,127 @@ + 2010-12-22 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once('component/parser/WindPropertiesParser.php'); + +/** + * WindProperties单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindPropertiesParserTest extends BaseTestCase { + private $parser; + private $path; + public function __construct() { + $this->parser = new WindPropertiesParser(); + $this->path = dirname(dirname(dirname(__FILE__))); + } + private function checkArray($array, $num, $member = array(), $flag = false) { + $this->assertTrue(is_array($array)); + $this->assertEquals($num, count($array)); + if (!$member) return; + if (!$flag) { + foreach ((array)$member as $key) { + $this->assertTrue(isset($array[$key])); + } + } else { + foreach ((array)$member as $key => $value) { + $this->assertTrue(isset($array[$key])); + $this->assertTrue($array[$key] == $value); + } + } + } + public function testParser() { + $data = $this->parser->parse($this->path . '/data/WindPropertiesParserTest.properties'); + $this->checkArray($data, 6, array('student', 'xxx', 'name', 'your', 'xjx', 'people')); + $this->assertTrue($data['name'] == 'test'); + $this->checkArray($data['people'], 3, array('name', 'sex', 'job')); + $this->checkArray($data['xxx'], 3, array('name', 'school', 'sex')); + $this->assertEquals('i', $data['student']['your']['name']['second']['value']); + $this->checkArray($data['your']['name']['second'], 3, array('name' => 'am', + 'key' => 'your', 'attribute' => 'friend'), true); + $this->checkArray($data['xjx'], 4, array('namexjx' => 'ddd', 'address' => 'china', 'sex' => '0'), true); + $this->assertEquals('java', $data['xjx']['job']['name']); + } + + public function testParserWithNull() { + $data = $this->parser->parse(''); + $this->checkArray($data, 0); + } + + public function testBuildWithEmpty() { + $p = ''; + $this->assertEquals('', $this->parser->buildData($p)); + //$this->checkArray($this->parser->buildData(array()), 0); + } + public function testBuildWithObject() { + $data = $this->parser->buildData($this->parser); + $this->assertTrue(is_object($data)); + } + + public function testToArrayWithEmpty() { + $value = $this->parser->toArray('', ''); + $this->assertTrue(is_array($value) && (count($value) === 0)); + } + + public function testToArrayWithFirstValue() { + $value = $this->parser->toArray('key', ''); + $this->assertTrue(is_array($value) && (count($value) === 1) && empty($value['key'])); + } + + public function testToArrayWithSecondValue() { + $value = $this->parser->toArray('', 'key'); + $this->assertTrue(is_array($value) && (count($value) === 1) && ($value[''] == 'key')); + } + + public function testToArray() { + $value = $this->parser->toArray('key1.key2.key3.key4', 'value'); + $this->assertTrue(is_array($value) && ($value['key1']['key2']['key3']['key4'] === 'value')); + } + + public function testFormatDataFromStringWithString() { + $data = array(); + $value = $this->parser->formatDataFromString('key', 'value', $data); + $this->assertTrue(is_array($value) && (count($value) == 1) && ($value['key'] == 'value')); + } + public function testFormatDataFromStringWithNoData() { + $data = array(); + $value = $this->parser->formatDataFromString('key1.key2.key3', 'value', $data); + $this->assertTrue(is_array($value) && (count($value) == 1) && ($value['key1']['key2']['key3'] == 'value')); + } + public function testFormatDataFromStringWithSameKeyData() { + $data = array('key1' => 'xxx'); + $value = $this->parser->formatDataFromString('key1.key2.key3', 'value', $data); + $this->assertTrue(is_array($value) && (count($value) == 1) && ($value['key1']['key2']['key3'] == 'value')); + } + public function testFormatDataFromString() { + $data = array('name' => 'xxx'); + $value = $this->parser->formatDataFromString('key1.key2.key3', 'value', $data); + $this->assertTrue(is_array($value) && (count($value) == 2)); + $this->assertTrue($value['key1']['key2']['key3'] == 'value'); + $this->assertTrue($value['name'] == 'xxx'); + } + public function testFormatDataArray() { + $data = array('name' => 'xxx'); + $param = array('key1.key2' => 'value1', 'key2.key3' => 'value2', 'key3' => 'value3'); + $value = $this->parser->formatDataArray($param, $data); + $this->assertTrue(is_array($value) && (count($value) == 4)); + $this->assertTrue($value['key1']['key2'] == 'value1'); + $this->assertTrue($value['name'] == 'xxx'); + $this->assertTrue($value['key2']['key3'] == 'value2'); + $this->assertTrue($value['key3'] == 'value3'); + } + public function testFormatDataArrayWithEmpty() { + $data = array(); + $param = array(); + $value = $this->parser->formatDataArray($param, $data); + $this->assertTrue(is_array($value) && (count($value) == 0)); + } +} \ No newline at end of file diff --git a/_tests/component/parser/WindXmlParserTest.php b/_tests/component/parser/WindXmlParserTest.php new file mode 100644 index 00000000..b831c833 --- /dev/null +++ b/_tests/component/parser/WindXmlParserTest.php @@ -0,0 +1,72 @@ + 2010-12-22 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once('component/parser/WindXmlParser.php'); + +/** + * WindXMLParser单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindXmlParserTest extends BaseTestCase { + private $parser; + private $path; + public function __construct() { + $this->parser = new WindXmlParser('UTF-8'); + $this->path = dirname(dirname(dirname(__FILE__))); + } + private function checkArray($array, $num, $member = array(), $flag = false) { + $this->assertTrue(is_array($array)); + $this->assertEquals($num, count($array)); + if (!$member) return; + if (!$flag) { + foreach ((array)$member as $key) { + $this->assertTrue(isset($array[$key])); + } + } else { + foreach ((array)$member as $key => $value) { + $this->assertTrue(isset($array[$key])); + $this->assertTrue($array[$key] == $value); + } + } + } + + public function testParse() { + $data = $this->parser->parse($this->path . '/data/WindXmlParserTest.xml'); + $this->checkArray($data, 5, array('tag', 'php', 'java', 'book', 'C++')); + $this->checkArray($data['php'], 2, array('price' => '20', 'pages' => 200), true); + $this->checkArray($data['java'], 3, array('name' => 'C#', 'price' => 30), true); + $this->checkArray($data['java']['pages'], 2, array('150', 'pp' => 'ddd'), true); + $this->checkArray($data['C++'], 5, array('author' => 'ddd', 'name' => 'C++', 'price' => 0.0002, 'isSaled' => 'true'), true); + $this->checkArray($data['C++']['list'], 3); + $this->checkArray($data['book'], 5); + $this->checkArray($data['tag'], 2); + } + + public function testWindConfigParse() { + $data = $this->parser->parse(WIND_PATH . 'wind_config.xml'); + } + + public function testTestParse() { + $data = $this->parser->parse($this->path . '/data/test.xml'); + } + + public function testParseWithEmpty() { + $tmp = $this->parser->parse(''); + $this->assertTrue(is_array($tmp) && (count($tmp) == 0)); + } + + public function testGetChildsWithError() { + $tests = array('key' => 'value'); + $data = $this->parser->getChilds($tests, 'key'); + $this->assertTrue(is_array($data) && count($data) == 0); + } +} \ No newline at end of file diff --git a/_tests/component/security/WindSecurityTest.php b/_tests/component/security/WindSecurityTest.php new file mode 100644 index 00000000..d6836768 --- /dev/null +++ b/_tests/component/security/WindSecurityTest.php @@ -0,0 +1,221 @@ + 2011-1-11 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once('component/utility/WindSecurity.php'); + +class WindSecurityTest extends BaseTestCase { + public function setUp() { + parent::setUp(); + } + public function tearDown() { + parent::tearDown(); + } + public static function htmlData() { + return array( + array('5>4', '5>4'), + array('3<13', '3<13'), + array('D&G', 'D&G'), + array('i say:"hello!"', 'i say:"hello!"'), + array("my name is A'B", 'my name is A'B'), + array('', ''), + array("Test", '<a href='test'>Test</a>'), + // array(array('cin>>a'), array('cin>>a')), + array(111, 111), + ); + } + + public static function tagsData() { + return array( + array('

Test paragraph.

Other text', '', 'Test paragraph. Other text'), + array('

Test paragraph.

Other text', '

', '

Test paragraph.

Other text'), + array('

Test paragraph.


', '', 'Test paragraph.'), + array('

Test paragraph.


', '
', 'Test paragraph.
'), + // array(array('Me'), '', array('Me')), + array(121334, '', 121334), + ); + } + + public static function addSlashesData() { + return array( + array('Is your name O\'reilly?', 'Is your name O\\\'reilly?'), + array('Is your name \\ssss', 'Is your name \\\\ssss'), + array(11111, 11111), + array('', ''), + ); + } + + public static function addSlashesDataArray() { + return array( + array(array(), array()), + array(array("Is your name \\ssss"), array("Is your name \\\\ssss")), + array(array(array('Is your name O\'reilly?')), array(array('Is your name O\\\'reilly?'))), + array(array(11111), array(11111)), + array(array(''), array('')), + ); + } + + /** + * @dataProvider htmlData + */ + public function testEscapeHTML($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::escapeHTML($source)); + } else { + $this->assertEquals($result, WindSecurity::escapeHTML($source)); + } + } + + /** + * @dataProvider tagsData + */ + public function testStripTags($source, $option = '', $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::stripTags($source, $option)); + } else { + $this->assertEquals($result, WindSecurity::stripTags($source, $option)); + } + } + + public function testAddSlashesFromGPC() { + $_GET['t1'] = 'Is your name O"reilly?'; + $r1 = "Is your name O\"reilly?"; + $_GET['t2'] = 'Is your name \ssss'; + $r2 = 'Is your name \\ssss'; + $this->assertEquals($r1, WindSecurity::addSlashesForInput($_GET['t1'])); + $this->assertEquals($r2, WindSecurity::addSlashesForInput($_GET['t2'])); + } + + /** + * @dataProvider addSlashesData + */ + public function testAddSlashesFromDF($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::addSlashesForOutput($source)); + } else { + $this->assertEquals($result, WindSecurity::addSlashesForOutput($source)); + } + } + + /** + * @dataProvider addSlashesData + */ + public function testAddSlashesFromString($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::addSlashes($source)); + } else { + $this->assertEquals($result, WindSecurity::addSlashes($source)); + } + } + + /** + * @dataProvider addSlashesDataArray + */ + public function testAddSlashesFromArray($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::addSlashesFromArray($source)); + } else { + $this->assertEquals($result, WindSecurity::addSlashesFromArray($source)); + } + } + + /** + * @dataProvider addSlashesData + */ + public function testStripSlashesWithString($result, $source) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::stripSlashes($source)); + } else { + $this->assertEquals($result, WindSecurity::stripSlashes($source)); + } + } + + /** + * @dataProvider addSlashesDataArray + */ + public function testStripSlashesWithArray($result, $source) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::stripSlashes($source)); + } else { + $this->assertEquals($result, WindSecurity::stripSlashes($source)); + } + } + + public function testEscapePath() { + $path ='D:/path/php/test.php'; + $this->assertEquals($path, WindSecurity::escapePath($path, true)); + $path = '../path/test.php'; + $this->assertEquals($path, WindSecurity::escapePath($path, false)); + $path = '..://\0/path/test.php'; + } + + public static function dirData() { + return array( + array('D://ppp//test/', 'D:/ppp/test'), + array('/var/p/test/*=$p', '/var/p/test/*p'), + array('/\'%/var&/p/test`/;\'', '/var/p/test'), + array('', ''), + ); + } + /** + * @dataProvider dirData + */ + public function testEscapeDir($resource, $result) { + $this->assertEquals($result, WindSecurity::escapeDir($resource)); + } + + public static function stringData() { + return array( + array('abcdefgh', 'abcdefgh'), + array("\0abdc%00efgh\r %3C0z;\t", "abdcefgh  <&#48z; "), + array("$#666efg;&#pp;", "$#666efg;&#pp;"), + ); + } + + /** + * @dataProvider stringData + */ + public function testEscapeString($source, $result) { + $this->assertEquals($result, WindSecurity::escapeString($source)); + } + + public static function escapeData() { + return array( + array('111', '111'), + array(111, 111), + array("\0abdc%00efgh\r %3C0z;\t", "abdcefgh  <&#48z; "), + array(array('abcdefgh', "\0abdc%00efgh\r %3C0z;\t", "$#666efg;&#pp;"), + array('abcdefgh', "abdcefgh  <&#48z; ", "$#666efg;&#pp;")), + ); + } + /** + * @dataProvider escapeData + */ + public function testEscapeChar($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::escapeChar($source)); + } else { + $this->assertEquals($result, WindSecurity::escapeChar($source)); + } + } + + public static function quoteData() { + return array( + array("Hello world. (can you hear me?)", 'Hello world\. \(can you hear me\?\)'), + array("Hello world+ [can you hear me?]", 'Hello world\+ \[can you hear me\?\]'), + array("Yes. $ I can hear you!", 'Yes\. \$ I can hear you!'), + array("WelCome!^", 'WelCome!\^'), + ); + } + /** + * . \ + * ? [ ^ ] ( $ ) + * @dataProvider quoteData + */ + public function testQuotemeta($source, $value) { + $this->assertEquals($value, WindSecurity::quotemeta($source)); + } +} \ No newline at end of file diff --git a/_tests/component/utility/WindPackTest.php b/_tests/component/utility/WindPackTest.php new file mode 100644 index 00000000..4fe6de16 --- /dev/null +++ b/_tests/component/utility/WindPackTest.php @@ -0,0 +1,74 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +require_once ('component/utility/WindPack.php'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPackTest extends BaseTestCase { + private $pack = null; + private $path = ''; + + public function init() { + if (null === $this->pack) { + $this->pack = new WindPack(); + $this->path = dirname(dirname(dirname(__FILE__))).'/'; + } + } + + public function setUp() { + parent::setUp(); + $this->init(); + } + + public static function providerPachMethod(){ + return array( + array(WindPack::STRIP_SELF,true), + array(WindPack::STRIP_PHP,true), + array(WindPack::STRIP_TOKEN,true), + array(WindPack::STRIP_SELF,false), + array(WindPack::STRIP_PHP,false), + array(WindPack::STRIP_TOKEN,false), + ); + } + /** + * @dataProvider providerPachMethod + */ + public function testPackFromList($packMethod,$compress){ + $fileList = array(__FILE__=>__FILE__); + $dst = $this->path."data/compile/file_{$packMethod}_{$compress}.php"; + $result = $this->pack->packFromFileList($fileList, $dst, $packMethod, $compress); + $this->assertTrue($result && is_file($dst)); + } + /** + * @dataProvider providerPachMethod + */ + public function testPackFromDir($packMethod,$compress){ + $dir = $this->path.'component/utility/date'; + $dst = $this->path."data/compile/dir_{$packMethod}_{$compress}.php"; + $result = $this->pack->packFromDir($dir, $dst, $packMethod, $compress); + $this->assertTrue($result && is_file($dst)); + } + + public function testPackFromFileByCallBack(){ + $fileList = array(__FILE__=>__FILE__); + $dst = $this->path."data/compile/file_callback_pack.php"; + $this->pack->setContentInjectionCallBack(array($this, 'callback')); + $result = $this->pack->packFromFileList($fileList, $dst, WindPack::STRIP_PHP, true); + $this->assertTrue($result && is_file($dst)); + + } + + public function callBack(){ + return 'echo 2222;'; + } + + +} \ No newline at end of file diff --git a/_tests/component/utility/WindSecurityTest.php b/_tests/component/utility/WindSecurityTest.php new file mode 100644 index 00000000..847b72ab --- /dev/null +++ b/_tests/component/utility/WindSecurityTest.php @@ -0,0 +1,248 @@ + 2011-1-11 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once('component/utility/WindSecurity.php'); + +class WindSecurityTest extends BaseTestCase { + public function setUp() { + parent::setUp(); + } + public function tearDown() { + parent::tearDown(); + } + public static function htmlData() { + return array( + array('5>4', '5>4'), + array('3<13', '3<13'), + array('D&G', 'D&G'), + array('i say:"hello!"', 'i say:"hello!"'), + array("my name is A'B", 'my name is A'B'), + array('', ''), + array("Test", '<a href='test'>Test</a>'), + // array(array('cin>>a'), array('cin>>a')), + array(111, 111), + ); + } + + public static function tagsData() { + return array( + array('

Test paragraph.

Other text', '', 'Test paragraph. Other text'), + array('

Test paragraph.

Other text', '

', '

Test paragraph.

Other text'), + array('

Test paragraph.


', '', 'Test paragraph.'), + array('

Test paragraph.


', '
', 'Test paragraph.
'), + // array(array('Me'), '', array('Me')), + array(121334, '', 121334), + ); + } + + public static function addSlashesData() { + return array( + array('Is your name O\'reilly?', 'Is your name O\\\'reilly?'), + array('Is your name \\ssss', 'Is your name \\\\ssss'), + array(11111, 11111), + array('', ''), + ); + } + + public static function addSlashesDataArray() { + return array( + array(array(), array()), + array("Is your name \\ssss", "Is your name \\\\ssss"), + array(array("Is your name \\ssss"), array("Is your name \\\\ssss")), + array(array(array('Is your name O\'reilly?')), array(array('Is your name O\\\'reilly?'))), + array(array(11111), array(11111)), + array(array(''), array('')), + ); + } + + /** + * @dataProvider htmlData + */ + public function testEscapeHTML($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::escapeHTML($source)); + } else { + $this->assertEquals($result, WindSecurity::escapeHTML($source)); + } + } + + /** + * @dataProvider tagsData + */ + public function testStripTags($source, $option = '', $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::stripTags($source, $option)); + } else { + $this->assertEquals($result, WindSecurity::stripTags($source, $option)); + } + } + + public function testAddSlashesForInput() { + $_GET['t1'] = 'Is your name O"reilly?'; + $r1 = "Is your name O\"reilly?"; + $_GET['t2'] = 'Is your name \ssss'; + $r2 = 'Is your name \\ssss'; + $this->assertEquals($r1, WindSecurity::addSlashesForInput($_GET['t1'])); + $this->assertEquals($r2, WindSecurity::addSlashesForInput($_GET['t2'])); + } + + /** + * @dataProvider addSlashesData + */ + public function testAddSlashesForOutput($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::addSlashesForOutput($source)); + } else { + $this->assertEquals($result, WindSecurity::addSlashesForOutput($source)); + } + } + + /** + * @dataProvider addSlashesData + */ + public function testAddSlashesFromString($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::addSlashes($source)); + } else { + $this->assertEquals($result, WindSecurity::addSlashes($source)); + } + } + + /** + * @dataProvider addSlashesDataArray + */ + public function testAddSlashesWithArray($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::addSlashes($source)); + } else { + $this->assertEquals($result, WindSecurity::addSlashes($source)); + } + } + + /** + * @dataProvider addSlashesData + */ + public function testStripSlashesWithString($result, $source) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::stripSlashes($source)); + } else { + $this->assertEquals($result, WindSecurity::stripSlashes($source)); + } + } + + /** + * @dataProvider addSlashesDataArray + */ + public function testStripSlashesWithArray($result, $source) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::stripSlashes($source)); + } else { + $this->assertEquals($result, WindSecurity::stripSlashes($source)); + } + } + + public function testEscapePath() { + $path ='D:/path/php/test.php'; + $this->assertEquals($path, WindSecurity::escapePath($path, true)); + $path = '../path/test.php'; + $this->assertEquals($path, WindSecurity::escapePath($path, false)); + $path = '..://\0/path/test.php'; + } + + public static function dirData() { + return array( + array('D://ppp//test/', 'D:/ppp/test'), + array('/var/p/test/*=$p', '/var/p/test/*p'), + array('/\'%/var&/p/test`/;\'', '/var/p/test'), + array('', ''), + ); + } + /** + * @dataProvider dirData + */ + public function testEscapeDir($resource, $result) { + $this->assertEquals($result, WindSecurity::escapeDir($resource)); + } + + public static function stringData() { + return array( + array('abcdefgh', 'abcdefgh'), + array("\0abdc%00efgh\r %3C0z;\t", "abdcefgh  <&#48z; "), + array("$#666efg;&#pp;", "$#666efg;&#pp;"), + ); + } + + /** + * @dataProvider stringData + */ + public function testEscapeString($source, $result) { + $this->assertEquals($result, WindSecurity::escapeString($source)); + } + + public static function escapeData() { + return array( + array('111', '111'), + array(111, 111), + array("\0abdc%00efgh\r %3C0z;\t", "abdcefgh  <&#48z; "), + array(array('abcdefgh', "\0abdc%00efgh\r %3C0z;\t", "$#666efg;&#pp;"), + array('abcdefgh', "abdcefgh  <&#48z; ", "$#666efg;&#pp;")), + ); + } + /** + * @dataProvider escapeData + */ + public function testEscapeChar($source, $result) { + if (is_array($source)) { + $this->assertArrayEquals($result, WindSecurity::escapeChar($source)); + } else { + $this->assertEquals($result, WindSecurity::escapeChar($source)); + } + } + + public static function quoteData() { + return array( + array("Hello world. (can you hear me?)", 'Hello world\. \(can you hear me\?\)'), + array("Hello world+ [can you hear me?]", 'Hello world\+ \[can you hear me\?\]'), + array("Yes. $ I can hear you!", 'Yes\. \$ I can hear you!'), + array("WelCome!^", 'WelCome!\^'), + ); + } + /** + * . \ + * ? [ ^ ] ( $ ) + * @dataProvider quoteData + */ + public function testQuotemeta($source, $value) { + $this->assertEquals($value, WindSecurity::quotemeta($source)); + } + + + public function testCheckInputValueWithArray(){ + $result ="'" . addslashes(serialize(array('1,2,3','haha'))). "'"; + $this->assertEquals($result, WindSecurity::checkInputValue(array('1,2,3','haha'))); + } + + public function testCheckInputValueWithObject(){ + $result ="'" . addslashes(serialize(new stdClass())). "'"; + $this->assertEquals($result, WindSecurity::checkInputValue(new stdClass())); + } + + /** + *@dataProvider providerCheckValue + */ + public function testCheckInputValueWithGeneral($result,$source){ + $this->assertEquals($result, WindSecurity::checkInputValue($source)); + } + + public static function providerCheckValue(){ + return array( + array("'a'",'a'), + array(2,2), + array("'\\'a'","'a"), + ); + } +} \ No newline at end of file diff --git a/_tests/component/utility/WindStringGBKTest.php b/_tests/component/utility/WindStringGBKTest.php new file mode 100644 index 00000000..1c532cea --- /dev/null +++ b/_tests/component/utility/WindStringGBKTest.php @@ -0,0 +1,65 @@ + 2011-1-12 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + + +require_once('component/utility/WindString.php'); + +class WindStringGBKTest extends BaseTestCase { + public function setUp() { + header('content-type:text/html; charset=gbk'); + parent::setUp(); + } + public function tearDown() { + parent::tearDown(); + } + public static function providerString() { + return array( + array('pp', 'ppp', 1, 2), + array('�Ұ���', '�Ұ��й�!', 0, 3, 'gbk'), + array('���й�!...', '�Ұ��й�!', 1, 5, 'gbk', true), + array('���й�!', '�Ұ��й�!', 1, 5, 'gbk'), + ); + } + + public static function providerStringLen() { + return array( + array('ppp', 3), + array('p����', 3), + array('����', 2), + ); + } + + /** + * @dataProvider providerString + */ + public function testsubstr($rt, $string, $start, $length, $charset = WindString::GBK, $falg = false) { + $this->assertEquals($rt, WindString::substr($string, $start, $length, $charset, $falg)); + } + + /** + * @dataProvider providerString + */ + public function testGbk_substr($rt, $string, $start, $length, $charset = WindString::GBK, $falg = false) { + $this->assertEquals($rt, WindString::gbk_substr($string, $start, $length, $falg)); + } + + + /** + * @dataProvider providerStringLen + */ + public function testStrlen($str, $leng) { + $this->assertEquals($leng, WindString::strlen($str, WindString::GBK)); + } + + /** + * @dataProvider providerStringLen + */ + public function testGbk_strlen($string, $length) { + $this->assertEquals($length, WindString::gbk_strlen($string)); + } +} \ No newline at end of file diff --git a/_tests/component/utility/WindStringUTF8Test.php b/_tests/component/utility/WindStringUTF8Test.php new file mode 100644 index 00000000..ca5dd2d9 --- /dev/null +++ b/_tests/component/utility/WindStringUTF8Test.php @@ -0,0 +1,86 @@ + 2011-1-6 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +require_once('component/utility/WindString.php'); + +class WindStringUTF8Test extends BaseTestCase { + public function setUp() { + parent::setUp(); + } + public function tearDown() { + parent::tearDown(); + } + public static function providerString() { + return array( + array('pp', 'ppp', 1, 2), + array('我爱中', '我爱中国!', 0, 3, 'utf8'), + array('爱中国!...', '我爱中国!', 1, 5, 'utf8', true), + array('爱中国!', '我爱中国!', 1, 5, 'utf8'), + ); + } + + public static function providerStringLen() { + return array( + array('ppp', 3), + array('p国中', 3), + array('万岁', 2), + ); + } + + /** + * @dataProvider providerString + */ + public function testsubstr($rt, $string, $start, $length, $charset = WindString::UTF8, $falg = false) { + $this->assertEquals($rt, WindString::substr($string, $start, $length, $charset, $falg)); + } + + /** + * @dataProvider providerString + */ + public function testUtf8_substr($rt, $string, $start, $length, $charset = WindString::UTF8, $falg = false) { + $this->assertEquals($rt, WindString::utf8_substr($string, $start, $length, $falg)); + } + + /** + * @dataProvider providerStringLen + */ + public function testStrlen($str, $leng) { + $this->assertEquals($leng, WindString::strlen($str, WindString::UTF8)); + } + + /** + * @dataProvider providerStringLen + */ + public function testUtf8_strlen($string, $length) { + $this->assertEquals($length, WindString::utf8_strlen($string)); + } + + public static function exportData() { + return array( + array("i'am phpwind\\", "'i\'am phpwind\\\\'"), + array(true, 'true'), + array(false, 'false'), + array(NULL, 'NULL'), + array(12345.22, "'12345.22'"), + array('12342.44', "'12342.44'"), + array(new WindString(), 'NULL'), + ); + } + /** + * @dataProvider exportData + */ + public function testVarExportForString($source, $result) { + $this->assertEquals($result, WindString::varToString($source)); + } + + public function testVarExportForArray() { + $arr = array('key' => 'value', 'name' => 'phpwind'); + $string = "array(\r\n\t'key' => 'value,\r\n\t'name' => 'phpwind',\r\n)"; + WindString::varToString($arr); + // $this->assertEquals($string, WindString::varExport($arr));//text比较 + } +} \ No newline at end of file diff --git a/_tests/component/utility/WindValidatorTest.php b/_tests/component/utility/WindValidatorTest.php new file mode 100644 index 00000000..0699d188 --- /dev/null +++ b/_tests/component/utility/WindValidatorTest.php @@ -0,0 +1,179 @@ + 2010-12-22 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once('component/utility/WindValidator.php'); + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindValidatorTest extends BaseTestCase{ + private $validate = null; + + public function init(){ + if(null === $this->validate){ + $this->validate = new WindValidator(); + } + } + + public function setUp(){ + parent::setUp(); + $this->init(); + } + + public static function providerIdCard(){ + return array( + array('422801198805124022'), + array('422801198805124'), + array('42280119880512402X') + ); + } + + public static function providerUrl(){ + return array( + array("http://www.baidu.com"), + array("http://www.baidu.com:80/a"), + array("http://www.baidu.com/a/b.php?uid=2&c=a"), + array("https://www.baidu.com/") + ); + } + + + public function testHasEmail(){ + $this->assertTrue($this->validate->hasEmail("中国aoxue.1988.su.qian@163.com") > 0); + } + + public function testIsEmail(){ + $this->assertTrue($this->validate->isEmail("aoxue.1988.su.qian@163.com")); + } + /** + * @dataProvider providerIdCard + */ + public function testHasIdCard($idCard){ + $this->assertTrue($this->validate->hasIdCard($idCard) > 0); + } + + /** + * @dataProvider providerIdCard + */ + public function testIsIdCard($idCard){ + $this->assertTrue($this->validate->isIdCard($idCard)); + } + + /** + * @dataProvider providerUrl + */ + public function testHasUrl($url){ + $this->assertTrue($this->validate->hasUrl($url) > 0); + } + + /** + * @dataProvider providerUrl + */ + public function testIsUrl($url){ + $this->assertTrue($this->validate->isUrl($url)); + } + + public function testHasChinese(){ + $this->assertTrue($this->validate->hasChinese("afa中国") > 0); + } + + public function testIsChinese(){ + $this->assertTrue($this->validate->isChinese("中国")); + } + + public function testHasIpv4(){ + $this->assertTrue($this->validate->hasIpv4("198.168.2.4") > 0); + } + + public function testIsIpv4(){ + $this->assertTrue($this->validate->isIpv4("192.168.1.104")); + } + + /** + * @dataProvider providerIpv6 + */ + public function testHasIpv6($ipv6){ + $this->assertTrue($this->validate->hasIpv6($ipv6) > 0); + } + + /** + * @dataProvider providerIpv6 + */ + public function testIsIpv6($ipv6){ + $this->assertTrue($this->validate->isIpv6($ipv6)); + } + + + public function testHasHTML(){ + $this->assertTrue($this->validate->hasHTML("afafasdfa") > 0); + } + + public function testIsHTML(){ + $this->assertTrue($this->validate->isHTML("asdfa")); + } + + public function testHasScript(){ + $this->assertTrue($this->validate->hasScript("afaf") > 0); + } + + public function testIsScript(){ + $this->assertTrue($this->validate->isScript("")); + } + + public function testIsNegative(){ + $this->assertTrue($this->validate->isNegative("-1") && !$this->validate->isNegative("1") && !$this->validate->isNegative("0")); + } + + public function testIsPositive(){ + $this->assertTrue($this->validate->isPositive("1") && !$this->validate->isPositive("-1") && !$this->validate->isPositive("0")); + } + + public function testIsNonNegative(){ + $this->assertTrue($this->validate->isNonNegative("0") && $this->validate->isNonNegative("1") && !$this->validate->isNonNegative("-1")); + } + + + + public function testIsArray(){ + $this->assertTrue($this->validate->isArray(array("")) && !$this->validate->isArray("a")); + } + + public function testInArray(){ + $this->assertTrue($this->validate->inArray('ab',array("ab",'cc')) && !$this->validate->inArray("a",array()) && !$this->validate->inArray(0,array('0'),true)); + } + + public function testIsEmpty(){ + $this->assertTrue($this->validate->isEmpty("") && $this->validate->isEmpty(0) && $this->validate->isEmpty(array()) && $this->validate->isEmpty(false)); + } + + public function testIsRequired(){ + $this->assertTrue(!$this->validate->isRequired("")); + } + + public function testIsLegalLength(){ + $this->assertTrue($this->validate->isLegalLength("3333",3)); + } + + public function testHasHtmlMatch(){ + $this->assertTrue($this->validate->hasHTML("afafasdfa",$matchs,true) > 0 && is_array($matchs)); + } + + public static function providerIpv6(){ + return array( + array('3255:0304::FE4A:174F:5577:289C:0014'), + array('3255::0014'), + array('3255:304::FE4A:174F:5577:289C:0014'), + array('0:0:0:0:0:0:10.0.0.1'), + array('::10.0.0.1'), + ); + } + +} \ No newline at end of file diff --git a/_tests/component/utility/date/WindDateTest.php b/_tests/component/utility/date/WindDateTest.php new file mode 100644 index 00000000..0f03b36d --- /dev/null +++ b/_tests/component/utility/date/WindDateTest.php @@ -0,0 +1,171 @@ + 2011-1-4 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +require_once('component/utility/date/WindDate.php'); + +WindDate::setTimezone('UTC'); +class WindDateTest extends BaseTestCase { + private $monthDays = array('1' => '31', '2' => '28', '3' => '31', '4' => '30', '5' => '31', + '6' => '30','7' => '31', '8' => '31', '9' => '30', '10' => '31', '11' => '30', + '12' => '31'); + public function setUp() { + parent::setUp(); + } + public function tearDown() { + parent::tearDown(); + } + + public static function providerDateDiff() { + return array( + array('y', '2009-1-1', '2010-1-3', 1), + array('m', '2009-1-1', '2010-1-3', 12), + array('w', '2009-1-1', '2010-1-1', 52), + array('d', '2010-1-1', '2010-1-5', 4), + array('h', '2010-1-1 12:20:0', '2010-1-1 13:40:0', 1), + array('n', '2010-1-1 12:20:0', '2010-1-1 13:40:0', 80), + array('s', '2010-1-1 12:20:0', '2010-1-1 13:40:0', 80 * 60), + array('s', '2010-1-1 12:20:0', '2010-1-1 13:40:0', 80 * 60), + array('DDD', '2010-1-1 12:20:0', '2010-1-1 13:40:0', 80 * 60), + ); + } + + public static function providerDateAdd() { + return array( + array('y', 1, '2009-1-1', 'Y-m-d', '2010-01-01'), + array('q', 1, '2009-1-1', 'Y-m-d', '2009-04-01'), + array('m', 1, '2009-1-1', 'Y-m-d', '2009-02-01'), + array('w', 1, '2009-1-1', 'Y-m-d', '2009-01-08'), + array('d', 4, '2009-1-29', 'Y-m-d', '2009-02-02'), + array('h', 4, '2009-1-29 0:0:0', 'Y-m-d H:i', '2009-01-29 04:00'), + array('n', 55, '2009-1-29 4:0:0', 'Y-m-d H:i', '2009-01-29 04:55'), + array('s', 5, '2009-1-29 4:55:55', 'Y-m-d H:i:s', '2009-01-29 04:56:00'), + array('sdd', 1, '2009-1-29 23:59:59', 'Y-m-d H:i:s', '2009-01-30 00:00:00'), + ); + } + + public static function providerGetDaysInMonthOfYear() { + return array( + array('1991'), + array('1992'), + array('1993'), + array('1994'), + array('1995'), + ); + } + + public static function providerSDaysInMonth() { + return array( + array(1, '1991'), + array(2, '1992'), + array(2, '1993'), + array(12, '1994'), + array(13, '1995'), + ); + } + + private function checkLeap($year) { + if ($year % 4 == 0 && $year % 100 != 0 || $year % 400 == 0) { + return 1; + } + return 0; + } + + + public function testTimeZone() { + $timeZone = WindDate::getTimeZone(); + WindDate::setTimezone('Asia/Shanghai'); + $this->assertEquals('Asia/Shanghai', WindDate::getTimeZone()); + } + + public function testFormat() { + $this->assertEquals(date('Y-m-d'), WindDate::format('Y-m-d')); + $this->assertEquals('2005-05-12', WindDate::format('Y-m-d', strtotime('2005-5-12'))); + } + + public function testDatePart() { + $this->assertEquals(date('y/m/d H', strtotime('2005')), WindDate::datePart('y/m/d H', '2005')); + } + /** + * @dataProvider providerDateDiff + */ + public function testDateDiff($style, $start, $end, $rt) { + $this->assertEquals($rt, WindDate::dateDiff($style, $start, $end)); + } + /** + * @dataProvider providerDateAdd + */ + public function testDateAdd($style, $value, $date, $format, $rt) { + $this->assertEquals($rt, WindDate::dateAdd($style, $value, $date, $format)); + } + + private function checkArray($rightArr, $waitForCheckArr) { + $this->assertEquals(count($rightArr), count($waitForCheckArr)); + + } + /** + * @dataProvider providerGetDaysInMonthOfYear + */ + public function testGetRealDaysInMonthsOfYear($year) { + if ($this->checkLeap($year)) { + $this->monthDays[2] = 29; + } else { + $this->monthDays[2] = 28; + } + $array = WindDate::getRealDaysInMonthsOfYear($year); + $this->assertEquals(count($this->monthDays), count($array)); + $this->assertEquals($this->monthDays[2], $array[1]); + } + + /** + * @dataProvider providerSDaysInMonth + */ + public function testGetDaysInMonth($month, $year) { + if ($this->checkLeap($year)) { + $this->monthDays[2] = 29; + } else { + $this->monthDays[2] = 28; + } + $day = (1 > $month || 12 < $month) ? 0 : $this->monthDays[$month]; + $this->assertEquals($day, WindDate::getDaysInMonth($month, $year)); + } + + /** + * @dataProvider providerGetDaysInMonthOfYear + */ + public function testGetDaysInYear($year) { + $days = $this->checkLeap($year) ? 366 : 365; + $this->assertEquals($days, WindDate::getDaysInYear($year)); + } + + public function testGetUTCDate() { + $t = time(); + WindDate::setTimeZone('UTC'); + $this->assertEquals(date('D, d M y H:i:s e', $t), WindDate::getUTCDate($t)); + $this->assertTrue(strrpos(WindDate::getUTCDate($t), 'UTC') != false); + } + + public function testGetLastDate(){ + $time = time(); + $this->assertEquals('10秒前',array_shift(WindDate::getLastDate($time-10))); + $this->assertEquals('2分钟前',array_shift(WindDate::getLastDate($time-61))); + $this->assertEquals('2小时前',array_shift(WindDate::getLastDate($time-3601))); + $this->assertEquals('昨天 '.WindDate::format('H:i',$time),array_shift(WindDate::getLastDate($time-86401))); + $this->assertEquals('前天 '.WindDate::format('H:i',$time),array_shift(WindDate::getLastDate($time-172801))); + $this->assertEquals(WindDate::format('m-d',$time-350000),array_shift(WindDate::getLastDate($time-350000))); + $this->assertEquals(WindDate::format('Y-m-d',$time-11350000),array_shift(WindDate::getLastDate($time-11350000))); + $this->assertEquals(WindDate::format('Y-m-d H:i',$time),array_pop(WindDate::getLastDate($time-10,null,'Y-m-d H:i'))); + } + + public function testGetMicroTime(){ + $microtTime = microtime(); + $this->assertEquals(array_sum(explode(' ', $microtTime)),WindDate::getMicroTime(null,$microtTime)); + } + + public function testGetChinaDate(){ + $this->assertEquals('2011年3月9日(星期三) 中午12:07',WindDate::getChinaDate('1299672440')); + } +} \ No newline at end of file diff --git a/_tests/component/utility/date/WindGeneralDateTest.php b/_tests/component/utility/date/WindGeneralDateTest.php new file mode 100644 index 00000000..1a962a0e --- /dev/null +++ b/_tests/component/utility/date/WindGeneralDateTest.php @@ -0,0 +1,311 @@ + 2010-11-7 +*@link http://www.phpwind.com +*@copyright Copyright © 2003-2110 phpwind.com +*@license +*/ + + +require_once('component/utility/date/WindGeneralDate.php'); +require_once('component/utility/date/WindDate.php'); + +WindDate::setTimezone('UTC'); +class WindGeneralDateTest extends BaseTestCase { + private $monthDays = array('1' => '31', '2' => '28', '3' => '31', '4' => '30', '5' => '31', + '6' => '30','7' => '31', '8' => '31', '9' => '30', '10' => '31', '11' => '30', + '12' => '31'); + private $t; + public function setUp() { + parent::setUp(); + $this->t = new WindGeneralDate(); + } + public function tearDown() { + parent::tearDown(); + } + public static function providerDate() { + return array( + array('2010', 1, 31, 0, 0, 0), + array(2011, 1, 1, 12, 10, 1), + array(1990), + array(1996, 2, 0, 1, 0, 0), + array(), + ); + } + public static function providerDateOfWeek() { + return array( + array('2010', 1, 31, 0, 0, 0, 1), + array(2011, 1, 1, 12, 10, 1, 7), + array(2011, 1, 4, 0, 0, 0, 3), + array(1996, 2, 4, 1, 0, 0, 1), + array(2007, 1, 31, 1, 0, 0, 4), + ); + } + public static function providerWeekOfYear() { + return array( + array('2010', 1, 31, 0, 0, 0, date('W', strtotime('2010-1-31'))), + array(2011, 1, 1, 12, 10, 1, date('W', strtotime('2011-1-1'))), + array(2011, 1, 4, 0, 0, 0, date('W', strtotime('2011-1-4'))), + array(1996, 2, 4, 1, 0, 0, date('W', strtotime('1996-2-4'))), + array(2007, 1, 31, 1, 0, 0, date('W', strtotime('2007-1-31'))), + ); + } + public static function providerGetYear() { + return array( + array('2010', 1, 31, 0, 0, 0, true, date('Y', strtotime('2010-1-31'))), + array(2011, 1, 1, 12, 10, 1, true, date('Y', strtotime('2011-1-1'))), + array(2011, 1, 4, 0, 0, 0, false, date('y', strtotime('2011-1-4'))), + array(1996, 2, 4, 1, 0, 0, true, date('Y', strtotime('1996-2-4'))), + array(2007, 1, 31, 1, 0, 0, false, date('y', strtotime('2007-1-31'))), + ); + } + public static function providerGetMonth() { + return array( + array('2010', 1, 31, 0, 0, 0, 0, date('m', strtotime('2010-1-31'))), + array(2011, 1, 1, 12, 10, 1, 1, date('n', strtotime('2011-1-1'))), + array(2011, 1, 4, 0, 0, 0, 2, date('M', strtotime('2011-1-4'))), + array(1996, 2, 4, 1, 0, 0, 2, date('M', strtotime('1996-2-4'))), + array(2007, 1, 31, 1, 0, 0, 1, date('n', strtotime('2007-1-31'))), + array(0, 0, 0, 1, 0, 0, 3, date('m', time())), + ); + } + + public static function providerGetDay() { + return array( + array('2010', 1, 31, 0, 0, 0, 0, date('d', strtotime('2010-1-31'))), + array(2011, 1, 1, 12, 10, 1, 1, date('j', strtotime('2011-1-1'))), + array(2011, 1, 4, 0, 0, 0, 2, date('jS', strtotime('2011-1-4'))), + array(1996, 2, 4, 1, 0, 0, 2, date('jS', strtotime('1996-2-4'))), + array(2007, 1, 31, 1, 0, 0, 1, date('j', strtotime('2007-1-31'))), + array(0, 0, 0, 1, 0, 0, 3, date('j', time())), + ); + } + + public static function providerGetWeek() { + return array( + array('2010', 1, 31, 0, 0, 0, 0, date('w', strtotime('2010-1-31'))), + array(2011, 1, 1, 12, 10, 1, 1, date('w', strtotime('2011-1-1'))), + array(2011, 1, 4, 0, 0, 0, 2, date('D', strtotime('2011-1-4'))), + array(1996, 2, 4, 1, 0, 0, 2, date('D', strtotime('1996-2-4'))), + array(2007, 1, 31, 1, 0, 0, 1, date('w', strtotime('2007-1-31'))), + array(0, 0, 0, 1, 0, 0, 3, date('N', time())), + ); + } + + public static function providerGetHours() { + return array( + array('2010', 1, 31, 0, 0, 0, 0, true, date('H', strtotime('2010-1-31'))), + array('2010', 1, 31, 0, 0, 0, 0, false, date('h', strtotime('2010-1-31'))), + array(2011, 1, 1, 12, 10, 1, 1, false, date('g', strtotime('2011-1-1 12:10:1'))), + array(2007, 1, 31, 1, 0, 0, 1, true, date('G', strtotime('2007-1-31 1:0:0'))), + array(1996, 2, 4, 1, 0, 0, 2, true, date('H', strtotime('1996-2-4 1:0:0'))), + array(0, 0, 0, 0, 0, 0, 3, false, date('H', time())), + ); + } + public static function providerGetMinutes() { + return array( + array('2010', 1, 31, 0, 0, 0, date('i', strtotime('2010-1-31 0:0:0'))), + array(2011, 1, 1, 12, 10, 1, date('i', strtotime('2011-1-1 12:10:1'))), + array(2007, 1, 31, 1, 0, 0, date('i', strtotime('2007-1-31 1:0:0'))), + array(2011, 1, 4, 12, 59, 59, date('i', strtotime('2011-1-4 12:59:59'))), + array(1996, 2, 4, 1, 0, 0, date('i', strtotime('1996-2-4 1:0:0'))), + ); + } + + public static function providerGetSeconds() { + return array( + array('2010', 1, 31, 0, 0, 0, date('s', strtotime('2010-1-31 0:0:0'))), + array(2011, 1, 1, 12, 10, 1, date('s', strtotime('2011-1-1 12:10:1'))), + array(2007, 1, 31, 1, 0, 0, date('s', strtotime('2007-1-31 1:0:0'))), + array(2011, 1, 4, 12, 59, 59, date('s', strtotime('2011-1-4 12:59:59'))), + array(1996, 2, 4, 1, 0, 0, date('s', strtotime('1996-2-4 1:0:0'))), + array(0, 0, 0, 0, 0, 6, date('s', strtotime(date('Y-m-d H:i') . ':6'))), + ); + } + + public static function providergetTimeStamp() { + return array( + array(strtotime('2010-1-31 0:0:0')), + array(strtotime('2011-1-1 12:10:1')), + array(strtotime('2007-1-31 1:0:0')), + array(strtotime('2011-1-4 12:59:59')), + array('1996-2-4 1:0:0', false), + array('32423'), + ); + } + + private function checkLeap($year) { + if ($year % 4 == 0 && $year % 100 != 0 || $year % 400 == 0) { + return 1; + } + return 0; + } + private function checkMonthDay ($year, $month) { + $this->checkLeap($year) && $this->monthDays[2] = 29; + $r = $this->monthDays[$month]; + $this->monthDays[2] = 28; + return $r; + } + private function getDaysOfYear($year, $month, $day) { + $this->checkLeap($year) && $this->monthDays[2] = 29; + $sum = 0; + for ($key = 1; $key < $month; $key ++) { + $sum += $this->monthDays[$key]; + } + $sum += $day; + $this->monthDays[2] = 28; + return $sum; + } + + /** + * @dataProvider providerDate + */ + public function testIsLeapYear($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + if ($year == null) $year = date('Y'); + $this->assertTrue($t->isLeapYear() == $this->checkLeap($year)); + } + + /** + * @dataProvider providerDate + */ + public function testGetDaysInMonth($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + if ($year == null) $year = date('Y'); + !$month && ((!$year) ? $month = date('m', time()) : $month = 1); + $this->assertEquals($this->checkMonthDay($year, $month), $t->getDaysInMonth()); + } + + /** + * @dataProvider providerDate + */ + public function testGetDaysInYear($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + if ($year == null) $year = date('Y'); + $days = $this->checkLeap($year) ? 366 : 365; + $this->assertEquals($days, $t->getDaysInYear()); + } + + /** + * @dataProvider providerDate + */ + public function testGetDayOfYear($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + !$month && ((!$year) ? $month = date('m', time()) : $month = 1); + !$day && ((!$year) ? $day = date('d', time()) : $day = 1); + !$year && $year = date('Y', time()); + $this->assertEquals($this->getDaysOfYear($year, $month, $day), $t->getDayOfYear()); + } + + /** + * @dataProvider providerDate + */ + public function testGetDayOfMonth($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + !$day && ((!$year) ? $day = date('d', time()) : $day = 1); + $this->assertEquals($day, $t->GetDayOfMonth()); + } + + /** + * @dataProvider providerDateOfWeek + */ + public function testGetDayOfWeek($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $days) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + $this->assertEquals($days, $t->getDayOfWeek()); + } + + /** + * @dataProvider providerWeekOfYear + */ + public function testGetWeekOfYear($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $days) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + $this->assertEquals($days, $t->getWeekOfYear()); + } + + /** + * @dataProvider providerGetYear + */ + public function testGetYear($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $flag, $years) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + $this->assertEquals($years, $t->getYear($flag)); + } + + /** + * @dataProvider providerGetMonth + */ + public function testGetMonth($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $flag, $rt) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + $this->assertEquals($rt, $t->getMonth($flag)); + } + + /** + * @dataProvider providerGetDay + */ + public function testGetDay($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $flag, $rt) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + $this->assertEquals($rt, $t->getDay($flag)); + } + + /** + * @dataProvider providerGetWeek + */ + public function testGetWeek($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $flag, $rt) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + $this->assertEquals($rt, $t->getWeek($flag)); + } + + /** + * @dataProvider providerGetHours + */ + public function testGetHours($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $form, $flag, $rt) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + if($flag){ + $this->assertEquals($rt, $t->get24Hours($form)); + }else{ + $this->assertEquals($rt, $t->get12Hours($form)); + } + } + + /** + * @dataProvider providerGetMinutes + */ + public function testGetMinutes($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $rt) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + $this->assertEquals($rt, $t->getMinutes()); + } + + /** + * @dataProvider providerGetSeconds + */ + public function testGetSeconds($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null, $rt) { + $t = new WindGeneralDate($year, $month, $day, $hours, $minutes, $second); + $this->assertEquals($rt, $t->getSeconds()); + } + + public function testGetLocalTimeZone() { + $t = new WindGeneralDate(); + $t->getLocalTimeZone(); + } + + /** + * @dataProvider providergetTimeStamp + */ + public function testGetUnixTimeStamp($time, $flag = true) { + $this->t->setTime($time); + !$flag && $time = strtotime($time); + strtotime($time) && $this->assertEquals($time, $this->t->getUnixTimeStamp()); + } + + public function testGetNow() { + $t2 = $this->t->getNow(); + $this->assertTrue($t2 instanceof WindGeneralDate); + } + + public function testToString() { + $t = new WindGeneralDate(); + $this->assertEquals(date('Y-m-d H:i'), $t->toString('Y-m-d H:i')); + $this->assertEquals(date('Y-m-d H:i'), date('Y-m-d H:i', strtotime($t))); + } + + +} \ No newline at end of file diff --git a/_tests/component/validator/WindValidatorTest.php b/_tests/component/validator/WindValidatorTest.php new file mode 100644 index 00000000..77e90171 --- /dev/null +++ b/_tests/component/validator/WindValidatorTest.php @@ -0,0 +1,171 @@ + 2010-12-22 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once('component/utility/WindValidator.php'); + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindValidatorTest extends BaseTestCase{ + private $validate = null; + + public function init(){ + if(null === $this->validate){ + $this->validate = new WindValidator(); + } + } + + public function setUp(){ + parent::setUp(); + $this->init(); + } + + public static function providerIdCard(){ + return array( + array('422801198805124022'), + array('422801198805124'), + array('42280119880512402X') + ); + } + + public static function providerUrl(){ + return array( + array("http://www.baidu.com"), + array("http://www.baidu.com:80/a"), + array("http://www.baidu.com/a/b.php?uid=2&c=a"), + array("https://www.baidu.com/") + ); + } + + + public function testHasEmail(){ + $this->assertTrue($this->validate->hasEmail("中国aoxue.1988.su.qian@163.com") > 0); + } + + public function testIsEmail(){ + $this->assertTrue($this->validate->isEmail("aoxue.1988.su.qian@163.com")); + } + /** + * @dataProvider providerIdCard + */ + public function testHasIdCard($idCard){ + $this->assertTrue($this->validate->hasIdCard($idCard) > 0); + } + + /** + * @dataProvider providerIdCard + */ + public function testIsIdCard($idCard){ + $this->assertTrue($this->validate->isIdCard($idCard)); + } + + /** + * @dataProvider providerUrl + */ + public function testHasUrl($url){ + $this->assertTrue($this->validate->hasUrl($url) > 0); + } + + /** + * @dataProvider providerUrl + */ + public function testIsUrl($url){ + $this->assertTrue($this->validate->isUrl($url)); + } + + public function testHasChinese(){ + $this->assertTrue($this->validate->hasChinese("afa中国") > 0); + } + + public function testIsChinese(){ + $this->assertTrue($this->validate->isChinese("中国")); + } + + public function testHasIpv4(){ + $this->assertTrue($this->validate->hasIpv4("198.168.2.4") > 0); + } + + public function testIsIpv4(){ + $this->assertTrue($this->validate->isIpv4("192.168.1.104")); + } + + /** + * @dataProvider providerIpv6 + */ + public function testHasIpv6($ipv6){ + $this->assertTrue($this->validate->hasIpv6($ipv6) > 0); + } + + /** + * @dataProvider providerIpv6 + */ + public function testIsIpv6($ipv6){ + $this->assertTrue($this->validate->isIpv6($ipv6)); + } + + + public function testHasHTML(){ + $this->assertTrue($this->validate->hasHTML("afafasdfa") > 0); + } + + public function testIsHTML(){ + $this->assertTrue($this->validate->isHTML("asdfa")); + } + + public function testHasScript(){ + $this->assertTrue($this->validate->hasScript("afaf") > 0); + } + + public function testIsScript(){ + $this->assertTrue($this->validate->isScript("")); + } + + public function testIsNegative(){ + $this->assertTrue($this->validate->isNegative("-1") && !$this->validate->isNegative("1") && !$this->validate->isNegative("0")); + } + + public function testIsPositive(){ + $this->assertTrue($this->validate->isPositive("1") && !$this->validate->isPositive("-1") && !$this->validate->isPositive("0")); + } + + public function testIsNonNegative(){ + $this->assertTrue($this->validate->isNonNegative("0") && $this->validate->isNonNegative("1") && !$this->validate->isNonNegative("-1")); + } + + + + public function testIsArray(){ + $this->assertTrue($this->validate->isArray(array("")) && !$this->validate->isArray("a")); + } + + public function testIsEmpty(){ + $this->assertTrue($this->validate->isEmpty("") && $this->validate->isEmpty(0) && $this->validate->isEmpty(array()) && $this->validate->isEmpty(false)); + } + + public function testIsLegalLength(){ + $this->assertTrue($this->validate->isLegalLength("3333",3)); + } + + public function testHasHtmlMatch(){ + $this->assertTrue($this->validate->hasHTML("afafasdfa",$matchs,true) > 0 && is_array($matchs)); + } + + public static function providerIpv6(){ + return array( + array('3255:0304::FE4A:174F:5577:289C:0014'), + array('3255::0014'), + array('3255:304::FE4A:174F:5577:289C:0014'), + array('0:0:0:0:0:0:10.0.0.1'), + array('::10.0.0.1'), + ); + } + +} \ No newline at end of file diff --git a/_tests/core/AllCoreTest.php b/_tests/core/AllCoreTest.php new file mode 100644 index 00000000..93fd819a --- /dev/null +++ b/_tests/core/AllCoreTest.php @@ -0,0 +1,52 @@ + 2010-11-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('core/config/AllConfigTest.php'); +require_once ('core/exception/AllExceptionTest.php'); +require_once ('core/factory/AllFactoryTest.php'); +require_once ('core/filter/AllFilterTest.php'); +require_once ('core/request/WindHttpRequestTest.php'); +require_once ('core/response/WindHttpResponseTest.php'); +require_once ('core/router/AllRouterTest.php'); +require_once ('core/viewer/AllViewerTest.php'); +require_once ('core/web/AllWebTest.php'); + +require_once ('core/WindBaseTest.php'); +require_once ('core/WindErrorHandleTest.php'); +require_once ('core/WindErrorMessageTest.php'); +require_once ('core/WindLayoutTest.php'); +require_once ('core/WindMessageTest.php'); +require_once ('core/WindUrlManagerTest.php'); + +class AllCoreTest { + + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllCoreTest'); + $suite->addTest(AllConfigTest::suite()); + $suite->addTest(AllExceptionTest::suite()); + $suite->addTest(AllFactoryTest::suite()); + $suite->addTestSuite(AllFilterTest::suite()); + $suite->addTestSuite('WindHttpRequestTest'); + $suite->addTestSuite('WindHttpResponseTest'); + $suite->addTest(AllRouterTest::suite()); + //$suite->addTest(AllViewerTest::suite()); + //$suite->addTest(AllWebTest::suite()); + + $suite->addTestSuite('LTest'); + $suite->addTestSuite('WTest'); + //$suite->addTestSuite('WindErrorHandleTest'); + //$suite->addTestSuite('WindErrorMessageTest'); + //$suite->addTestSuite('WindMessageTest'); + //$suite->addTestSuite('WindUrlManagerTest'); + return $suite; + } +} diff --git a/_tests/core/WindBaseTest.php b/_tests/core/WindBaseTest.php new file mode 100644 index 00000000..0f5ed317 --- /dev/null +++ b/_tests/core/WindBaseTest.php @@ -0,0 +1,121 @@ + 2010-12-28 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +require_once ('WindBase.php'); +class LTest extends BaseTestCase { + + public function setUp() { + parent::setUP(); + } + + public function tearDown() { + parent::tearDown(); + } + + /** + * @dataProvider providerRealPath + */ + public function testGetRealPath($value, $args) { + if (is_array($args)) { + list($filename, $ext) = $args; + } else { + $filename = $args; + $ext = ''; + } + $this->assertEquals($value, Wind::getRealPath($filename, $ext)); + } + + public function testRegisterWithEmpty() { + define('P_P', dirname(__FILE__) . D_S); + Wind::register(P_P, '', false); + $this->assertFalse($this->checkIncludePath(P_P)); + Wind::register(P_P, ''); + $this->assertTrue($this->checkIncludePath(P_P)); + } + + public function testRegister() { + define('R_P', dirname(__FILE__) . D_S); + $this->clearTestIncludePath(R_P); + Wind::register(R_P, 'R_P', false); + $this->assertEquals(R_P . 'data' . D_S . 'show.php', Wind::getRealPath('R_P:data.show', 'php')); + $this->assertFalse($this->checkIncludePath(R_P)); + Wind::register(R_P, 'MyAPP', true); + $this->assertEquals(R_P . 'data' . D_S . 'show.php', Wind::getRealPath('MyAPP:data.show', 'php')); + $this->assertTrue($this->checkIncludePath(R_P)); + } + + public function testImport() { + $this->assertFalse(Wind::import('')); + $name = Wind::import('WIND:core.WindFrontController'); + $this->assertEquals('WindFrontController', $name); + $name = Wind::import('WindBase'); + $this->assertEquals('WindBase', $name); + $name = Wind::import('WIND:WindBase', false); + $this->assertEquals('WindBase', $name); + } + + public function testAutoLoadWithErrorClassException() { + try { + $name = Wind::import('data/config.php', false); + $this->assertEquals('WindBase', $name); + } catch (Exception $e) { + return; + } + $this->fail('Error Exception, in testImportWithException!'); + } + + public function testGetImports() { + $className = Wind::import('WIND:core.config.WindSystemConfig'); + $this->assertEquals($className, Wind::getImports('WIND:core.config.WindSystemConfig')); + } + + public function testSetIsAutoLoad() { + Wind::setIsAutoLoad(false); + $this->isTrue('Success'); + Wind::setIsAutoLoad(true); + } + + public function testPerLoadInjection() { + Wind::PerLoadInjection(array(), array('PPPPP.wer' => 'pp')); + $this->assertEquals('pp', Wind::getImports('PPPPP.wer')); + } + + private function clearTestIncludePath($path) { + $includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); + if (($pos = array_search($path, $includePaths)) !== false) unset($includePaths[$pos]); + set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, $includePaths)); + } + + private function checkIncludePath($path) { + $includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); + return (array_search($path, $includePaths) !== false); + } + + public static function providerRealPath() { + return array(array(WIND_PATH . 'core' . D_S . 'WindBase.php', array('WIND:core.WindBase', 'php')), array(WIND_PATH . 'core' . D_S . 'WindBase', 'WIND:core.WindBase'), array(WIND_PATH . 'compile', 'WIND:compile'), array('data', 'data'), array('data' . D_S . 'config', 'data.config')); + } +} +class WTest extends BaseTestCase { + + public function setUp() { + parent::setUP(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testApplication() { + $config = include (T_P . '/data/config.php'); + $this->assertTrue(WindBase::run('testApp', $config['wind']) instanceof WindFrontController); + } + + public function testIsCompile() { + $this->assertTrue(true); + } +} + diff --git a/_tests/core/WindErrorHandleTest.php b/_tests/core/WindErrorHandleTest.php new file mode 100644 index 00000000..e5270aed --- /dev/null +++ b/_tests/core/WindErrorHandleTest.php @@ -0,0 +1,122 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * WindErrorHandle单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindErrorHandleTest extends BaseTestCase { + private $message = 'Uncaught exception'; + public function setUp() { + parent::setUp(); + require_once('core/windErrorHandle.php'); + } + public static function providerMessage() { + return array( + array('i am error!', 'test1', '160', ''), + array('hahah you are wrong!', 'iamfile', 10000, 222), + array('this is error!', 'file1', 30, 'werwer'), + array('', '', '', ''), + ); + } + + public static function providerException() { + return array( + array(new Exception('hahaha', 1)), + array(new Exception('May be i am wrong', 2)), + array(new Exception('', 1000)), + array(new Exception('')), + ); + } + + /** + * E_USER_ERROR 级别的错误会在输出错误信息后进行截断exit(),退出, + * 所以这里如果要测试E_USER_ERROR级别的错误的话,需要先将截断的语句注释掉 + */ + public static function providerErrorHanddle() { + return array( + //array(E_USER_ERROR, 'i am error', 'errorfile', 200), + array(E_USER_WARNING, 'i am warning', 'loging', 1), + array(E_USER_NOTICE, 'i am notice', 'logout', -1), + array('', 'i am fine', '', 0), + array('', 'i', '', ''), + ); + } + /** + * @dataProvider providerMessage + */ + public function testBuildMessage($message, $file, $line, $type) { + $result = "Error Type: $type\nError Message: $message\n"; + $result .= "Info: on line $line in file $file \n"; + $this->assertEquals($result, WindErrorHandle::buildMessage($message, $file, $line, $type)); + } + + /** + * @dataProvider providerMessage + */ + public function testBuildErrorMessage($message, $file, $line, $type) { + $result = "Error Type: $type\nError Message: $message\n"; + $result .= "Info: on line $line in file $file \n"; + $result .= "PHP " . PHP_VERSION . "(" . PHP_OS . ")\n"; + $result .= "Aborting...\n"; + $this->assertEquals($result, WindErrorHandle::buildErrorMessage($message, $file, $line, $type)); + } + + /** + * @dataProvider providerException + */ + public function testExceptionHandle($exception) { + $message = "Error Type: " . $this->message . "\nError Message: " . $exception->getMessage() . "\n"; + $message .= "Info: on line " . $exception->getLine() . " in file " . $exception->getFile() . " \n"; + $message .= "PHP " . PHP_VERSION . "(" . PHP_OS . ")\n"; + $message .= "Aborting...\n"; + $message .= $exception->getTraceAsString(); + ob_start(); + WindErrorHandle::ExceptionHandle($exception); + $result = ob_get_clean(); + $this->assertEquals($message, $result); + } + + private function buildMessage($errno, $errstr, $errfile, $errline) { + switch ($errno) { + case E_USER_ERROR: + $result = "Error Type: ERROR\nError Message: $errstr\n"; + $result .= "Info: on line $errline in file $errfile \n"; + $result .= "PHP " . PHP_VERSION . "(" . PHP_OS . ")\n"; + $result .= "Aborting...\n"; + break; + case E_USER_WARNING: + $result = "Error Type: WARNING\nError Message: $errstr\n"; + $result .= "Info: on line $errline in file $errfile \n"; + break; + case E_USER_NOTICE: + $result = "Error Type: NOTICE\nError Message: $errstr\n"; + $result .= "Info: on line $errline in file $errfile \n"; + break; + default: + $result = ''; + break; + } + return $result; + } + /** + * @dataProvider providerErrorHanddle + */ + public function testErrorHandle($errno, $errstr, $errfile, $errline) { + $message = $this->buildMessage($errno, $errstr, $errfile, $errline); + ob_start(); + WindErrorHandle::errorHandle($errno, $errstr, $errfile, $errline); + $result = ob_get_clean(); + $this->assertEquals($message, $result); + } +} + diff --git a/_tests/core/WindErrorMessageTest.php b/_tests/core/WindErrorMessageTest.php new file mode 100644 index 00000000..8c49c19f --- /dev/null +++ b/_tests/core/WindErrorMessageTest.php @@ -0,0 +1,95 @@ + 2010-12-9 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * 测试WindErrorMessage + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindErrorMessageTest extends BaseTestCase { + private $errorMessage; + private $response; + private $request; + public function setUp() { + parent::setUp(); + require_once('core/WindErrorMessage.php'); + require_once('core/WindHttpResponse.php'); + require_once('core/WindHttpRequest.php'); + require_once('core/WindWebApplication.php'); + require_once('core/WindWebDispatcher.php'); + require_once('core/WindSystemConfig.php'); + $this->init(); + } + public function tearDown() { + $this->errorMessage = null; + } + + public function testGetAndSetError() { + $this->assertTrue('' == $this->errorMessage->getError('key')); + $this->errorMessage->addError('nameError', 'name'); + $this->assertEquals('nameError', $this->errorMessage->getError('name')); + $this->errorMessage->addError('', 'password'); + $this->assertEquals('', $this->errorMessage->getError('password')); + $this->errorMessage->addError(array('false', 'true'), 'flag'); + $this->assertEquals('false', $this->errorMessage->getError(0)); + $this->assertEquals('true', $this->errorMessage->getError(1)); + $this->assertTrue(is_array($this->errorMessage->getError()) && count($this->errorMessage->getError()) == 3); + } + /** + * sendError测试 + */ + public function testSendError() { + $this->assertNull($this->errorMessage->sendError()); + $this->errorMessage->addError('ddddd', 'name'); + try { + $this->errorMessage->sendError(); + } catch(Exception $e) { + return; + } + } + + /** + * sendError测试 + */ + public function testSetErrorAction() { + $this->errorMessage->setErrorAction('run', 'TestErrorController'); + $this->assertNull($this->errorMessage->sendError()); + $this->errorMessage->addError('ddddd', 'name'); + try { + $this->errorMessage->sendError(); + } catch(Exception $e) { + return; + } + } + + private function init() { + $this->request = new WindHttpRequest(); + $this->response = new WindHttpResponse(); + $systemConfig = new WindSystemConfig($this->getConfig()); + $this->response->setData($systemConfig, 'WindSystemConfig'); + $dispatcher = new WindWebDispatcher($this->request, $this->response); + $dispatcher->module = 'default'; + $this->response->setDispatcher($dispatcher); + $this->errorMessage = WindErrorMessage::getInstance($this->request, $this->response); + Wind::register(dirname(dirname(dirname(__FILE__))) . D_S, 'TEST'); + $this->errorMessage->clear(); + } + private function getConfig() { + return array( + 'modules' => array( + 'default' => array( + 'path' => 'data', + 'template' => 'default', + 'controllerSuffix' => 'controller', + 'actionSuffix' => 'action', + 'method' => 'run', + ))); + } +} diff --git a/_tests/core/WindLayoutTest.php b/_tests/core/WindLayoutTest.php new file mode 100644 index 00000000..bb1599bc --- /dev/null +++ b/_tests/core/WindLayoutTest.php @@ -0,0 +1,66 @@ +createWindLayout($fileName); + try { + $segments = $windLayout->parserLayout($dir, $ext, $contentTplName); + } catch (Exception $exception) { + $this->assertEquals(get_class($exception), 'WindException'); + } + } + + /** + * @param string $fileName + * @param string $dir + * @param string $ext + * @param string $contentTplName + * + * @dataProvider providerWithLayoutFile + */ + public function testParserLayout($fileName, $dir, $ext, $contentTplName) { + $windLayout = $this->createWindLayout($fileName); + $segments = $windLayout->parserLayout($dir, $ext, $contentTplName); + $this->assertEquals($segments[0], 'header'); + $this->assertEquals($segments[1], 'content'); + $this->assertEquals($segments[2], 'footer'); + } + + public function providerWithLayoutFileError() { + $args = array(); + $args[] = array('data.layout1', '', 'htm', 'content'); + return $args; + } + + public function providerWithLayoutFile() { + $args = array(); + $args[] = array('data.layout', '', 'htm', 'content'); + return $args; + } + + private function createWindLayout($fileName) { + require_once 'core/WindLayout.php'; + $windLayout = new WindLayout(); + $windLayout->setLayoutFile($fileName); + return $windLayout; + } + + protected function setUp() { + parent::setUp(); + } + + protected function tearDown() { + parent::tearDown(); + } + +} + diff --git a/_tests/core/WindMessageTest.php b/_tests/core/WindMessageTest.php new file mode 100644 index 00000000..148c8e57 --- /dev/null +++ b/_tests/core/WindMessageTest.php @@ -0,0 +1,205 @@ + 2010-12-9 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * WindMessage单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindMessageTest extends BaseTestCase { + private $message = null; + public function setUp() { + parent::setUp(); + require_once('core/WindMessage.php'); + $this->message = new WindMessage(); + } + public function tearDown() { + parent::tearDown(); + $this->message = null; + } + + private function addTestMessage() { + $_tmp = array('one' => 'php', 'two' => $this->message, 'three' => '', 'four', + 'five' => array('six' => 'true', 'seven' => 'false')); + $this->message->addMessage($_tmp); + } + private function getArrayToString($args) { + return trim(implode(',', (array)$args), ','); + } + + private function checkArray($array, $num, $member = array(), $ifCheck = false) { + $this->assertTrue(is_array($array) && count($array) == $num); + if (!$member) return; + foreach ((array)$member as $key => $value) { + ($ifCheck) ? $this->assertTrue(isset($array[$key]) && $array[$key] == $value) : + $this->assertTrue(isset($array[$value])); + } + } + /** + * 测试获得信息: + * 1:当信息数组中没有值的时候获取一个信息 + */ + public function testGetMessageWithNone() { + $this->assertEquals('', $this->message->getMessage('name')); + } + + /** + * 2:当信息数组中没有值的时候获取整个信息 + */ + public function testGetMessageWithNull() { + $_tmp = $this->message->getMessage(); + $this->assertTrue(is_array($_tmp) && count($_tmp) == 0); + $this->addTestMessage(); + $_tmp = $this->message->getMessage(); + $this->assertTrue(is_array($_tmp) && count($_tmp) == 5); + } + + /** + * 3:设置一个信息,并且能正确获得该信息 + */ + public function testGetMessageWithName() { + $this->addTestMessage(); + $this->assertEquals('php', $this->message->getMessage('one')); + $this->assertEquals('four', $this->message->getMessage(0)); + $this->assertEquals('false', $this->message->getMessage('seven')); + $this->assertEquals('true', $this->message->getMessage('six')); + } + /** + * 4:设置一个对象,并能正确获得该对象 + */ + public function testGetMessageWithObjectName() { + $this->addTestMessage(); + $obj = $this->message->getMessage('two'); + $this->assertTrue(is_object($obj) && $obj instanceof WindMessage); + $this->message->addMessage($this, 'case'); + $obj = $this->message->getMessage('case'); + $this->assertTrue(is_object($obj) && $obj instanceof PHPUnit_Framework_TestCase); + } + + public function testGetMessageWithString() { + $value = $this->message->getMessageWithString(); + $this->assertTrue(is_string($value) && $value == ''); + $this->addTestMessage(); + $value = $this->message->getMessageWithString(); + $args = array('one' => 'php', 'four', 'six' => 'true', 'seven' => 'false'); + $this->assertTrue(is_string($value) && ($value == $this->getArrayToString($args))); + $value = $this->message->getMessageWithString('one'); + $this->assertTrue(is_string($value) && $value == 'php'); + } + + public function testGetMessageWithArray() { + $value = $this->message->getMessageWithArray(); + $this->assertTrue(is_array($value) && count($value) == 0); + $this->addTestMessage(); + $value = $this->message->getMessageWithArray(); + $args = array('one' => 'php', '0' => 'four', 'six' => 'true', 'seven' => 'false'); + $this->checkArray($value, 5, $args, true); + $value = $this->message->getMessageWithArray('two'); + $this->assertTrue(is_array($value) && count($value) == 1); + $this->assertTrue(is_object($value[0]) && $value[0] instanceof WindMessage); + } + /** + * 添加一条信息: + * 1:添加一条空信息 + */ + public function testAddMessageWithEmpty() { + $this->message->addMessage('', 'php'); + $this->assertEquals('', $this->message->getMessage('php')); + } + /** + * 2:添加一条字串信息 + */ + public function testAddMessageWithNull() { + $this->message->addMessage(null, 'php'); + $this->assertEquals('', $this->message->getMessage('php')); + } + /** + * 3:添加对象 + */ + public function testAddMessageWithObject() { + $this->message->addMessage($this, 'obj'); + $obj = $this->message->getMessage('obj'); + $this->assertTrue(is_object($obj) && $obj instanceof PHPUnit_Framework_TestCase); + } + /** + * 4: 添加字串 + */ + public function testAddMessageWithString() { + $this->message->addMessage('hello world', 'php'); + $this->assertEquals('hello world', $this->message->getMessage('php')); + $this->message->addMessage('phpWind', 'test'); + $this->assertEquals('phpWind', $this->message->getMessage('test')); + } + + /** + * 5: 添加已存在的字串 + */ + public function testAddMessageWithSameName() { + $this->message->addMessage('hello world', 'php'); + $this->assertEquals('hello world', $this->message->getMessage('php')); + $this->message->addMessage('phpWind', 'php'); + $this->assertEquals('phpWind', $this->message->getMessage('php')); + } + + /** + * 测试清空信息 + * 1:清空单个信息 + */ + public function testClearWithName() { + $this->addTestMessage(); + $this->assertEquals('php', $this->message->getMessage('one')); + $this->message->clear('one'); + $this->assertEquals('', $this->message->getMessage('one')); + $this->assertEquals('four', $this->message->getMessage(0)); + $this->message->clear(0); + $this->assertEquals('', $this->message->getMessage(0)); + } + /** + * 2:清空所有 + */ + public function testClearWithAll() { + $this->addTestMessage(); + $_tmp = $this->message->getMessage(); + $this->assertTrue(is_array($_tmp) && count($_tmp) == 5); + $this->message->clear(); + $this->assertEquals('', $this->message->getMessage('one')); + $this->assertEquals('', $this->message->getMessage(0)); + $_tmp = $this->message->getMessage(); + $this->assertTrue(is_array($_tmp) && count($_tmp) == 0); + } + /** + * 3:清空输入空字串 + */ + public function testClearWithEmpty() { + $this->message->addMessage('phpUnit', 'test'); + $this->assertEquals('phpUnit', $this->message->getMessage('test')); + $_tmp = $this->message->getMessage(); + $this->assertTrue(is_array($_tmp) && count($_tmp) == 1); + $this->message->clear(''); + $this->assertEquals('', $this->message->getMessage('test')); + $_tmp = $this->message->getMessage(); + $this->assertTrue(is_array($_tmp) && count($_tmp) == 0); + } + + /** + * 4:清空输入null + */ + public function testClearWithNull() { + $this->message->addMessage('phpUnit', 'test'); + $this->assertEquals('phpUnit', $this->message->getMessage('test')); + $_tmp = $this->message->getMessage(); + $this->assertTrue(is_array($_tmp) && count($_tmp) == 1); + $this->message->clear(null); + $this->assertEquals('', $this->message->getMessage('test')); + $_tmp = $this->message->getMessage(); + $this->assertTrue(is_array($_tmp) && count($_tmp) == 0); + } +} \ No newline at end of file diff --git a/_tests/core/WindUrlManagerTest.php b/_tests/core/WindUrlManagerTest.php new file mode 100644 index 00000000..8995c726 --- /dev/null +++ b/_tests/core/WindUrlManagerTest.php @@ -0,0 +1,34 @@ +urlManager = new WindUrlManager($url, $urlArgs); + if ($urlArgs === '' && $url === '') { + $this->assertEquals($this->urlManager->buildUrl(), ''); + } else { + $this->assertEquals($this->urlManager->buildUrl(), 'http://localhost:80/index.php?&a=index&c=hhh'); + } + } + + public function providerWithConstruct() { + $args = array(); + $args[] = array('', ''); + $args[] = array('http://localhost:80/index.php?', array('a' => 'index', 'c' => 'hhh')); + $args[] = array('http://localhost:80/index.php?', '&a=index&c=hhh&'); + return $args; + } + + protected function setUp() { + parent::setUp(); + require_once 'core/WindUrlManager.php'; + $urlManager = new WindUrlManager(); + } +} + diff --git a/_tests/core/config/AllConfigTest.php b/_tests/core/config/AllConfigTest.php new file mode 100644 index 00000000..5cdb1ea8 --- /dev/null +++ b/_tests/core/config/AllConfigTest.php @@ -0,0 +1,22 @@ + 2011-1-24 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('core/config/parser/WindConfigParserTest.php'); +require_once ('core/config/WindSystemConfigTest.php'); + +class AllConfigTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllConfigTest'); + $suite->addTestSuite('WindConfigParserTest'); + $suite->addTestSuite('WindSystemConfigTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/core/config/WindSystemConfigTest.php b/_tests/core/config/WindSystemConfigTest.php new file mode 100644 index 00000000..65e648e8 --- /dev/null +++ b/_tests/core/config/WindSystemConfigTest.php @@ -0,0 +1,154 @@ + 2010-12-24 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * WindSystemConfig单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindSystemConfigTest extends BaseTestCase { + private $config; + private $testConfig; + public function setUp() { + parent::setUp(); + require_once ('core/config/WindSystemConfig.php'); + require_once ('core/config/parser/WindConfigParser.php'); + Wind::register(T_P, 'TEST'); + $this->testConfig = include 'data/config.php'; + $this->config = new WindSystemConfig($this->testConfig['wind'], new WindConfigParser(), 'testApp'); + } + + public function testInitConfig() { + try { + $this->config->initConfig(''); + } catch (Exception $e) { + $this->assertTrue(is_file(COMPILE_PATH . 'testApp_config.php')); + return; + } + } + + public function testGetConfig() { + $this->assertArrayEquals($this->getComponentConfig(), $this->config->getConfig('classes')); + } + + private function getComponentConfig() { + return array( + 'windWebApp' => array( + 'path' => 'WIND:core.web.WindWebApplication', + 'scope' => 'request', + 'proxy' => 'true', + ), + 'windLogger' => array( + 'path' => 'WIND:component.log.WindLogger', + 'scope' => 'request', + 'config' => array( + 'path' => '', + ), + ), + 'urlBasedRouter' => array( + 'path' => 'WIND:core.router.WindUrlBasedRouter', + 'scope' => 'application', + 'proxy' => 'true', + 'config' => array( + 'resource' => 'WIND:urlRouter_config', + 'suffix' => 'xml', + ), + ), + 'viewResolver' => array( + 'path' => 'WIND:core.viewer.WindViewer', + 'scope' => 'request', + ), + 'db' => array( + 'path' => 'WIND:component.db.WindConnectionManager', + 'scope' => 'singleton', + ), + ); + } + public function testGetConfigParser() { + $this->assertTrue($this->config->getConfigParser() instanceof WindConfigParser); + } + + public function testGetCacheName() { + $this->assertEquals('testApp_config', $this->config->getCacheName()); + } + + public function testGetAppend() { + $this->assertFalse($this->config->getAppend()); + $this->config->setAppend('php'); + $this->assertEquals('php', $this->config->getAppend()); + } + + public function testGetAppName() { + $this->assertEquals('testApp', $this->config->getAppName()); + } + + public function testGetAppClass() { + $this->assertEquals('windWebApp', $this->config->getAppClass()); + } + public function testGetRootPath() { + $_SERVER['SCRIPT_FILENAME'] = ''; + $this->assertEquals('', $this->config->getRootPath()); + } + + public function testGetFactory() { + $config = $this->config->getFactory(); + $righ = array('class-definition' => 'components', + 'class' => 'WIND:core.factory.WindComponentFactory'); + $this->assertArrayEquals($righ, $config); + $this->assertEquals('WIND:core.factory.WindComponentFactory', $this->config->getFactory('class')); + } + + public function testGetFilters() { + $filter = array('class' => 'WIND:core.filter.WindFilterChain', + 'filter1' => array('class' => 'WIND:core.web.filter.WindLoggerFilter'),); + $this->assertArrayEquals($filter, $this->config->getFilters()); + $this->assertEquals('WIND:core.filter.WindFilterChain', $this->config->getFilters('class')); + } + + public function testGetRouter() { + $router = array('class' => 'urlBasedRouter',); + $this->assertArrayEquals($router, $this->config->getRouter()); + $this->assertEquals('urlBasedRouter', $this->config->getRouter('class')); + } + + public function testGetModules() { + $modules = array('default' => array( + 'path' => 'actionControllers', + 'default' => array( + 'path' => 'template', + 'ext' => 'htm', + 'view-resolver' => array( + 'class' => 'WIND:core.viewer.WindViewer', + 'is-cache' => 'false', + 'cache-dir' => 'cache', + 'compile-dir' => 'compile', + ), + ), + ), + ); + $this->assertArrayEquals($modules, $this->config->getModules()); + $this->assertEquals($modules['default'], $this->config->getModules('default')); + } + + public function testGetTemplate() { + throw new PHPUnit_Framework_IncompleteTestError('no complete'); + } + + public function testGetViewerResolvers() { + throw new PHPUnit_Framework_IncompleteTestError('no complete'); + } + public function testGetApplications() { + throw new PHPUnit_Framework_IncompleteTestError('no complete'); + } + public function testGetErrorMessage() { + throw new PHPUnit_Framework_IncompleteTestError('no complete'); + } +} \ No newline at end of file diff --git a/_tests/core/config/parser/WindConfigParserTest.php b/_tests/core/config/parser/WindConfigParserTest.php new file mode 100644 index 00000000..3d040b13 --- /dev/null +++ b/_tests/core/config/parser/WindConfigParserTest.php @@ -0,0 +1,136 @@ + 2010-12-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +class WindConfigParserTest extends BaseTestCase { + private $parser; + private $path; + public function setUp() { + parent::setUp(); + require_once('core/config/parser/WindConfigParser.php'); + require_once('core/request/WindHttpRequest.php'); + $this->parser = new WindConfigParser(); + $_SERVER['SCRIPT_FILENAME'] = __FILE__; + } + + public function checkArray($array, $num, $memberList = array(), $flag = false) { + $this->assertTrue(is_array($array)); + $this->assertTrue(count($array) == $num); + if (!isset($memberList)) return ; + foreach ($memberList as $key => $value) { + (!$flag) ? $this->assertTrue(isset($array[$value])) + : $this->assertTrue(isset($array[$key]) && $array[$key] == $value); + } + } + + + public function testParserConfigWithErrorFile() { + try { + $result = $this->parser->parseConfig(T_P . '/data/phpwind.xml', 'phpwind'); + } catch(Exception $e) { + $this->assertTrue($e instanceof WindException); + return; + } + $this->fail('File Error no exists'); + } + + public function testParserConfigWithErrorConfig() { + try { + $result = $this->parser->parseConfig(T_P . '/data/formConfig.dat', 'testF'); + } catch(Exception $e) { + $this->assertTrue($e instanceof WindException); + return; + } + $this->fail('Config Error Init type'); + } + + public function testParserConfigWithXML() { + $result = $this->parser->parseConfig(T_P . '/data/test_config.xml', 'XML'); + $this->checkArray($result, 4, array('components', 'web-apps', 'filters', 'viewerResolvers')); + $this->assertTrue(isset($result['viewerResolvers']['pp'])); + $this->assertEquals('WIND:core.viewer.WindViewer', $result['viewerResolvers']['pp']['class']); + } + public function testParserConfigWithIni() { + $result = $this->parser->parseConfig(T_P . '/data/test_config.ini', 'Ini'); + $this->checkArray($result, 10, array('rootPath', 'modules', 'filters', 'templates', + 'error', 'applications', 'viewerResolvers', 'router', 'routerParsers', 'extensionConfig')); + $this->checkArray($result['viewerResolvers'], 1); + $this->assertEquals('WIND:core.viewer.WindViewer', $result['viewerResolvers']['default']['class']); + $this->assertTrue(strrpos($result['rootPath'], 'phpwind') !== false); + } + public function testParserConfigWithProperties() { + $result = $this->parser->parseConfig(T_P . '/data/test_config.properties', 'properties'); + $this->checkArray($result, 10, array('rootPath', 'modules', 'filters', 'templates', + 'error', 'applications', 'viewerResolvers', 'router', 'routerParsers', 'extensionConfig')); + $this->checkArray($result['error'], 2, array('default', 'QQ')); + $this->assertEquals('WIND:core.WindErrorAction', $result['error']['default']['class']); + $this->assertEquals('WindErrorAction', $result['error']['QQ']['class']); + $this->assertTrue($result['extensionConfig']['formConfig'] == 'test:controllers'); + } + public function testParserConfigWithPHP() { + $result = $this->parser->parseConfig(T_P . '/data/test_config.php', 'PHP'); + $this->checkArray($result, 10, array('rootPath', 'modules', 'filters', 'templates', + 'error', 'applications', 'viewerResolvers', 'router', 'routerParsers', 'extensionConfig')); + $this->checkArray($result['viewerResolvers'], 1); + $this->assertEquals('WIND:core.viewer.WindViewer', $result['viewerResolvers']['default']['class']); + $this->assertEquals('controllers.actionForm', $result['extensionConfig']['formConfig']); + } + + public function testParserConfigWithEmptyALL() { + $result = $this->parser->parseConfig('', ''); + $this->checkArray($result, 2, array('components', 'web-apps')); + } + + public function testParserConfigWithEmpty() { + $result = $this->parser->parseConfig('', 'Empty'); + $this->checkArray($result, 2, array('components', 'web-apps')); + } + + public function testParserWithFileException() { + try { + $result = $this->parser->parse(''); + } catch(Exception $e) { + $this->assertTrue($e instanceof WindException); + return; + } + $this->fail('No File Exception Error'); + } + + /*public function testParserWithErrorAppendFileException() { + try { + $result = $this->parser->parse(T_P . '/data/formConfig.xml', 'file', 'hahah'); + } catch(Exception $e) { + $this->assertTrue($e instanceof WindException); + return; + } + $this->fail('Error'); + }*/ + + public function testParserWithNoAlias() { + $result = $this->parser->parse(T_P . '/data/formConfig.xml'); + $this->checkArray($result, 2, array('formName', 'default')); + $this->checkArray($result['default'], 2, array('moduleName' => 'default', 'path' => 'TEST:data'), true); + } + + public function testParserWithAppend() { + $result = $this->parser->parse(T_P . '/data/formConfig.xml', 'testF', 'empty'); + $this->checkArray($result, 2, array('formName', 'default')); + $this->checkArray($result['default'], 2, array('moduleName' => 'default', 'path' => 'TEST:data'), true); + } + + public function testParserWithHasAppend() { + $result = $this->parser->parse(T_P . '/data/formConfig.xml', 'testF', 'empty'); + $this->checkArray($result, 2, array('formName', 'default')); + $this->checkArray($result['default'], 2, array('moduleName' => 'default', 'path' => 'TEST:data'), true); + } + + public function testParserWithNoAppend() { + $result = $this->parser->parse(T_P . '/data/formConfig.xml', 'testF'); + $this->checkArray($result, 2, array('formName', 'default')); + $this->checkArray($result['default'], 2, array('moduleName' => 'default', 'path' => 'TEST:data'), true); + } +} \ No newline at end of file diff --git a/_tests/core/exception/AllExceptionTest.php b/_tests/core/exception/AllExceptionTest.php new file mode 100644 index 00000000..b5fe3aad --- /dev/null +++ b/_tests/core/exception/AllExceptionTest.php @@ -0,0 +1,23 @@ + 2011-1-14 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('core/exception/WindExceptionTest.php'); +require_once ('core/exception/WindSqlExceptionTest.php'); + +class AllExceptionTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllException'); + $suite->addTestSuite('WindExceptionTest'); + $suite->addTestSuite('WindSqlExceptionTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/core/exception/WindExceptionTest.php b/_tests/core/exception/WindExceptionTest.php new file mode 100644 index 00000000..de2605a0 --- /dev/null +++ b/_tests/core/exception/WindExceptionTest.php @@ -0,0 +1,67 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindExceptionTest extends BaseTestCase { + protected $message = 'test WindException'; + public function setUp() { + parent::setUp(); + require_once ('core/exception/WindException.php'); + } + public function tearDown() { + parent::tearDown(); + } + public function testWindException() { + try { + throw new WindException($this->message); + } catch (WindException $exception) { + return true; + } + $this->fail($this->message); + } + + public function testGetInnerException() { + try { + throw new WindException($this->message, 3, new Exception($this->message)); + } catch (WindException $exception) { + $innerException = $exception->getInnerException(); + if ($innerException instanceof Exception) { + return true; + } + } + $this->fail($this->message); + } + + public function testGetStackTrace() { + try { + throw new WindException($this->message, 3); + } catch (WindException $exception) { + $trace = $exception->getStackTrace(); + if ($trace && is_array($trace)) { + return true; + } + } + $this->fail($this->message); + } + public function testGetStackTraceWithInner() { + try { + throw new WindException($this->message, 3, new Exception($this->message)); + } catch (WindException $exception) { + $trace = $exception->getStackTrace(); + if ($trace && is_array($trace)) { + return true; + } + } + $this->fail($this->message); + } +} \ No newline at end of file diff --git a/_tests/core/exception/WindSqlExceptionTest.php b/_tests/core/exception/WindSqlExceptionTest.php new file mode 100644 index 00000000..dc6504e1 --- /dev/null +++ b/_tests/core/exception/WindSqlExceptionTest.php @@ -0,0 +1,35 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSqlExceptionTest extends BaseTestCase { + public function setUp() { + parent::setUp(); + require_once ('core/exception/WindSqlException.php'); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testNewException() { + try{ + throw new WindSqlException('error', WindSqlException::DB_CONN_EMPTY); + }catch(Exception $e) { + $this->assertEquals("Database configuration is empty. 'error' ", $e->getMessage()); + $this->assertEquals('WindSqlException', get_class($e)); + return; + } + $this->fail('Test error'); + } +} \ No newline at end of file diff --git a/_tests/core/factory/AllFactoryTest.php b/_tests/core/factory/AllFactoryTest.php new file mode 100644 index 00000000..3d107ee0 --- /dev/null +++ b/_tests/core/factory/AllFactoryTest.php @@ -0,0 +1,27 @@ + 2011-1-14 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +include ('core/factory/WindClassProxyTest.php'); +include ('core/factory/WindClassDefinitionTest.php'); +include ('core/factory/WindComponentFactoryTest.php'); +include ('core/factory/WindFactoryTest.php'); + +class AllFactoryTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllFactoryTest'); + $suite->addTestSuite('WindClassProxyTest'); + $suite->addTestSuite('WindClassDefinitionTest'); + $suite->addTestSuite('WindComponentFactoryTest'); + $suite->addTestSuite('WindFactoryTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/core/factory/WindClassDefinitionTest.php b/_tests/core/factory/WindClassDefinitionTest.php new file mode 100644 index 00000000..cf2489bf --- /dev/null +++ b/_tests/core/factory/WindClassDefinitionTest.php @@ -0,0 +1,141 @@ + 2011-1-14 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +class WindClassDefinitionTest extends BaseTestCase { + private $proxy = null; + public function setUp() { + parent::setUp(); + Wind::register(T_P, 'TEST'); + require_once ('core/factory/WindClassDefinition.php'); + require_once ('core/factory/WindFactory.php'); + $this->proxy = new WindClassDefinition($this->getTestData()); + } + public function tearDown() { + parent::tearDown(); + } + + public function testGetInstanceByFactoryMethod() { + $factory = new WindFactory(array('xxx' => $this->getTestData())); + $this->assertTrue($this->proxy->getInstance($factory) instanceof ForWindClassDefinition); + } + + public function testGetInstanceByErrorFactoryMethod() { + $args = $this->getTestData(); + $args['factory-method'] = 'hahah'; + $proxy = new WindClassDefinition($args); + $factory = new WindFactory(array('xxx' => $args)); + try { + $proxy->getInstance($factory); + } catch (Exception $e) { + $this->assertEquals('WindException', get_class($e)); + return; + } + $this->fail('error'); + } + + public function testGetInstanceBySingleton() { + $args = $this->getTestData(); + $args['factory-method'] = ''; + $proxy = new WindClassDefinition($args); + $factory = new WindFactory(array('xxx' => $args)); + $this->assertTrue($proxy->getInstance($factory) instanceof ForWindClassDefinition); + } + + public function testGetInstanceByPrototype() { + $args = $this->getTestData(); + $args['factory-method'] = ''; + $args['scope'] = 'prototype'; + $proxy = new WindClassDefinition($args); + $factory = new WindFactory(array('xxx' => $args)); + $this->assertTrue($proxy->getInstance($factory) instanceof ForWindClassDefinition); + } + + public function testGetInstanceByApplication() { + $args = $this->getTestData(); + $args['factory-method'] = ''; + $args['scope'] = 'application'; + $proxy = new WindClassDefinition($args); + $factory = new WindFactory(array('xxx' => $args)); + $this->assertNull($proxy->getInstance($factory)); + require_once ('core/web/WindWebApplication.php'); + $factory->application = new WindWebApplication(); + $this->assertTrue($proxy->getInstance($factory) instanceof ForWindClassDefinition); + } + + public function testGetInstanceByRequest() { + $args = $this->getTestData(); + $args['factory-method'] = ''; + $args['scope'] = 'request'; + $proxy = new WindClassDefinition($args); + $factory = new WindFactory(array('xxx' => $args)); + $this->assertNull($proxy->getInstance($factory)); + require_once ('core/request/WindHttpRequest.php'); + $factory->request = new WindHttpRequest(); + $this->assertTrue($proxy->getInstance($factory) instanceof ForWindClassDefinition); + $this->assertTrue($proxy->getInstance($factory) instanceof ForWindClassDefinition); + } + + public function testGetInstanceByOther() { + $args = $this->getTestData(); + $args['factory-method'] = ''; + $args['scopt'] = 'other'; + $proxy = new WindClassDefinition($args); + $factory = new WindFactory(array('xxx' => $args)); + $this->assertTrue($proxy->getInstance($factory) instanceof ForWindClassDefinition); + } + + public function testGetInstanceByErrorInitMethod() { + $args = $this->getTestData(); + $args['factory-method'] = ''; + $args['init-method'] = 'test'; + $proxy = new WindClassDefinition($args); + $factory = new WindFactory(array('xxx' => $args)); + try { + $proxy->getInstance($factory); + } catch (Exception $e) { + $this->assertEquals('WindException', get_class($e)); + return; + } + $this->fail('error'); + } + + public function testGetClassName() { + $this->assertEquals('ForWindClassDefinition', $this->proxy->getClassName()); + } + + public function testGetAlias() { + $this->assertEquals('xxx', $this->proxy->getAlias()); + } + + public function testGetPath() { + $this->assertEquals('TEST:data.ForWindClassDefinition', $this->proxy->getPath()); + } + + public function testGetScope() { + $this->assertEquals('singleton', $this->proxy->getScope()); + } + + public function testGetConstructArgs() { + $this->assertTrue(is_array($this->proxy->getConstructArgs())); + } + + public function testGetProperties() { + $this->assertArrayEquals(array('name' => array('value' => 'xxx'), 'key' => array('value' => 'key')), $this->proxy->getPropertys()); + } + + public function testGetClassDefinition() { + $this->assertArrayEquals($this->getTestData(), $this->proxy->getClassDefinition()); + } + + private function getTestData() { + return array('name' => 'xxx', 'path' => 'TEST:data.ForWindClassDefinition', 'factory-method' => 'factory', + 'init-method' => 'init', 'scope' => 'singleton', + 'properties' => array('name' => array('value' => 'xxx'), 'key' => array('value' => 'key')), + 'constructor-arg' => array(), 'import' => array('resource' => '')); + } +} \ No newline at end of file diff --git a/_tests/core/factory/WindClassProxyTest.php b/_tests/core/factory/WindClassProxyTest.php new file mode 100644 index 00000000..d55c293e --- /dev/null +++ b/_tests/core/factory/WindClassProxyTest.php @@ -0,0 +1,100 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ + +class WindClassProxyTest extends BaseTestCase { + + public function testCreatInstance() { + list($instance) = $this->createInstance('Persion'); + $this->assertEquals(get_class($instance->_getInstance()), 'Persion'); + $this->assertEquals($instance->_getReflection()->getName(), 'Persion'); + } + + public function testProxy() { + list($instance, $listener) = $this->createInstance('Persion'); + $result = $instance->testPersion('a1', 'b1'); + $this->assertEquals($instance->arg1, 'a1'); + $this->assertEquals($instance->arg2, 'b1'); + $this->assertEquals($result, 'a1'); + + $listener1 = new Listener1(); + $instance->registerEventListener('testPersion', $listener, WindClassProxy::EVENT_TYPE_METHOD); + $instance->registerEventListener('testPersion', $listener1, WindClassProxy::EVENT_TYPE_METHOD); + $instance->name = 'wuqiong'; + $this->assertEquals($listener1->arg1, null); + $this->assertEquals($listener1->arg2, null); + + $result = $instance->testPersion('a', 'b'); + $this->assertEquals($result, 'a'); + $this->assertEquals($listener1->arg1, 'a_pre_a_post'); + $this->assertEquals($listener1->arg2, 'b_pre_b_post'); + } + + public function testGetter() { + list($instance, $listener) = $this->createInstance('Persion'); + $instance->name = 'wuqiong01'; + $this->assertEquals('wuqiong01', $instance->_getInstance()->name); + + $instance->registerEventListener('name', $listener, WindClassProxy::EVENT_TYPE_GETTER); + $instance->name = 'wuqiong'; + $_value = $instance->name; + $this->assertEquals($_value, 'wuqiong'); + $this->assertEquals($listener->testB, 'name_postHandle'); + } + + public function testSetter() { + list($instance, $listener) = $this->createInstance('Persion'); + $instance->name = 'wuqiong01'; + $this->assertEquals('wuqiong01', $instance->_getInstance()->name); + + $instance->registerEventListener('name', $listener, WindClassProxy::EVENT_TYPE_SETTER); + $instance->name = 'wuqiong'; + $this->assertEquals($listener->test, 'wuqiong_preHandle'); + $this->assertEquals($listener->testB, 'wuqiong_postHandle'); + } + + /** + * Enter description here ... + * + * @param string $className + * @param array $args + * @return WindClassProxy + */ + private function createInstance($className, $args = array()) { + $instance = new WindClassProxy($className, $args); + $listener = new Listener(); + return array($instance, $listener); + } + + /** + * Prepares the environment before running a test. + */ + protected function setUp() { + parent::setUp(); + require_once 'core/factory/proxy/WindClassProxy.php'; + require_once 'data/ForWindClassProxy.php'; + } + + /** + * Cleans up the environment after running a test. + */ + protected function tearDown() { + + parent::tearDown(); + } + + /** + * Constructs the test case. + */ + public function __construct() { + + } + +} + diff --git a/_tests/core/factory/WindComponentFactoryTest.php b/_tests/core/factory/WindComponentFactoryTest.php new file mode 100644 index 00000000..031748ff --- /dev/null +++ b/_tests/core/factory/WindComponentFactoryTest.php @@ -0,0 +1,61 @@ + 2011-1-30 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +class WindComponentFactoryTest extends BaseTestCase { + private $factory = null; + public function setUp() { + parent::setUp(); + require_once ('core/factory/WindComponentFactory.php'); + $this->factory = new WindComponentFactory($this->getTestData()); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testGetInstance() { + $this->assertTrue($this->factory->getInstance('ppp', 'default') instanceof WindView); + } + + public function testNoClassCreate() { + try { + $this->factory->createInstance('CoreTest', 'hahah'); + } catch (Exception $e) { + return; + } + $this->fail('Exception Error!'); + } + + public function testCreateInstance() { + $this->assertTrue($this->factory->createInstance('WindWebApplication') instanceof WindWebApplication); + } + + public function testGetClassDefinitionByAlias() { + $this->assertTrue($this->factory->getClassDefinitionByAlias('ppp') instanceof WindComponentDefinition); + } + + public function testAddClassDefinitions() { + $p = new WindComponentDefinition(array('name' => 'kkk', 'path' => 'WIND:core.WindView')); + $this->factory->addClassDefinitions($p); + $this->assertTrue($this->factory->getClassDefinitionByAlias('kkk') instanceof WindComponentDefinition); + + $p = new WindComponentDefinition(array('name' => 'ooo', 'path' => 'WIND:core.WindView')); + $this->factory->addClassDefinitions(array($p)); + $this->assertTrue($this->factory->getClassDefinitionByAlias('ooo') instanceof WindComponentDefinition); + } + + private function getTestData() { + return array( + 'ppp' => array( + 'name' => 'pppp', + 'path' => 'WIND:core.WindView', + ), + ) + ; + } +} \ No newline at end of file diff --git a/_tests/core/factory/WindFactoryTest.php b/_tests/core/factory/WindFactoryTest.php new file mode 100644 index 00000000..ff8bf8b0 --- /dev/null +++ b/_tests/core/factory/WindFactoryTest.php @@ -0,0 +1,57 @@ + 2011-1-14 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +class WindFactoryTest extends BaseTestCase { + private $factory = null; + public function setUp() { + parent::setUp(); + require_once ('core/factory/WindFactory.php'); + $this->factory = new WindFactory($this->getTestData()); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testGetInstance() { + //$this->assertNull($this->factory->getInstance('xxx')); + $this->assertTrue($this->factory->getInstance('ppp', 'default') instanceof WindView); + } + + public function testNoClassCreate() { + try { + $this->factory->createInstance('CoreTest', 'hahah'); + } catch (Exception $e) { + return; + } + $this->fail('Exception Error!'); + } + + public function testCreateInstance() { + $this->assertTrue($this->factory->createInstance('WindWebApplication') instanceof WindWebApplication); + } + + public function testGetClassDefinitionByAlias() { + //$this->assertNull($this->factory->getClassDefinitionByAlias('xxx')); + $this->assertTrue($this->factory->getClassDefinitionByAlias('ppp') instanceof WindClassDefinition); + } + + public function testAddClassDefinitions() { + $p = new WindClassDefinition(array('name' => 'kkk', 'path' => 'WIND:core.WindView')); + $this->factory->addClassDefinitions($p); + $this->assertTrue($this->factory->getClassDefinitionByAlias('kkk') instanceof WindClassDefinition); + + $p = new WindClassDefinition(array('name' => 'ooo', 'path' => 'WIND:core.WindView')); + $this->factory->addClassDefinitions(array($p)); + $this->assertTrue($this->factory->getClassDefinitionByAlias('ooo') instanceof WindClassDefinition); + } + + private function getTestData() { + return array('ppp' => array('name' => 'pppp', 'path' => 'WIND:core.WindView')); + } +} \ No newline at end of file diff --git a/_tests/core/filter/AllFilterTest.php b/_tests/core/filter/AllFilterTest.php new file mode 100644 index 00000000..e0490a18 --- /dev/null +++ b/_tests/core/filter/AllFilterTest.php @@ -0,0 +1,21 @@ + 2011-1-28 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('core/filter/WindFilterChainTest.php'); + +class AllFilterTest { + public static function main() { + PHPUnit_TestUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllFilterTest'); + $suite->addTestSuite('WIndFilterChainTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/core/filter/WindFilterChainTest.php b/_tests/core/filter/WindFilterChainTest.php new file mode 100644 index 00000000..2775ce71 --- /dev/null +++ b/_tests/core/filter/WindFilterChainTest.php @@ -0,0 +1,80 @@ + 2011-1-25 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +class WindFilterChainTest extends BaseTestCase { + private $filterChain = null; + public function setUp() { + parent::setUp(); + require_once ('core/filter/WindFilterChain.php'); + require_once ('core/config/WindConfig.php'); + Wind::register(T_P, 'TEST', false); + $this->filterChain = new WindFilterChain($this->getFilterConfig()); + } + public function tearDown() { + parent::tearDown(); + } + private function getFilterConfig() { + $filters = array('TestFilter' => array('class' => 'TEST:data.ForWindFilter'), + 'TestChain' => array('class' => 'TEST:core.filter.WindFilterChainTest')); + return $filters; + } + + public function testGetHandle() { + $handle = $this->filterChain->getHandler(); + $this->assertTrue($handle instanceof ForWindFilter); + + $handle = $this->filterChain->getHandler(); + $this->assertTrue($handle instanceof WindHandlerInterceptor); + + $this->assertNull($this->filterChain->getHandler()); + } + + public function show() { + echo 'i am excute operator!'; + return 1; + } + public function testHandle() { + $this->filterChain->setCallBack(array($this, 'show')); + $handle = $this->filterChain->getHandler(); + ob_start(); + $result = $handle->handle(1, '2'); + $tmp = ob_get_clean(); + $this->assertEquals(1, $result); + $except = "1+2i am excute operator!\$a=1,\$b=2"; + $this->assertEquals($tmp, $except); + } + + public function testDeleteFiler() { + $this->filterChain->setCallBack(array($this, 'show')); + $this->filterChain->deleteFilter('TestChain'); + $this->filterChain->deleteFilter('TestFilter'); + $handle = $this->filterChain->getHandler(); + ob_start(); + $result = $handle->handle(2); + $tmp = ob_get_clean(); + $this->assertEquals(1, $result); + $except = "i am excute operator!"; + $this->assertEquals($tmp, $except); + + } + + public function testAddFiler() { + $this->filterChain->setCallBack(array($this, 'show')); + $this->filterChain->deleteFilter('TestFilter'); + $this->filterChain->addFilter(new ForWindFilter()); + $this->filterChain->addFilter(new WindFilterChainTest(), 'ForWindFilter'); + $handle = $this->filterChain->getHandler(); + ob_start(); + $result = $handle->handle('php'); + $tmp = ob_get_clean(); + $this->assertEquals(1, $result); + $except = "php+bi am excute operator!\$a=php,\$b="; + $this->assertEquals($tmp, $except); + + } +} \ No newline at end of file diff --git a/_tests/core/request/WindHttpRequestTest.php b/_tests/core/request/WindHttpRequestTest.php new file mode 100644 index 00000000..76677b50 --- /dev/null +++ b/_tests/core/request/WindHttpRequestTest.php @@ -0,0 +1,476 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * WindHttpRequest单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindHttpRequestTest extends BaseTestCase { + private $httpRequest; + private $get = array('name' => 'xxx', 'sex' => '1', 'file' => array('filename1', 'filename2')); + private $post = array('address' => 'zhejiangU', 'step' => '5'); + private $cookie = array('logIP' => '10.1.123.99', 'loginTime' => '2010-12-17'); + public function setUp() { + parent::setUp(); + require_once ('core/request/WindHttpRequest.php'); + require_once ('core/response/WindHttpResponse.php'); + require_once ('core/exception/WindException.php'); + $_GET = array(); + $_POST = array(); + $_COOKIE = array(); + $_GET['name'] = 'xxx'; + $_GET['sex'] = '1'; + $_GET['file'] = array('filename1', 'filename2'); + $_POST['address'] = 'zhejiangU'; + $_POST['step'] = '5'; + $_COOKIE['logIP'] = '10.1.123.99'; + $_COOKIE['loginTime'] = '2010-12-17'; + $this->httpRequest = new WindHttpRequest(); + } + + public static function providerSlashes() { + return array( + array('name'), + array(array('p' => "pear'", 'a' => 'apple\'s', 'c' => '\\\\')), + array(10), + array(''), + array(null), + ); + } + + public static function providerGet() { + return array( + array('name', 'xxx'), + array('sex', '1'), + array('school', ''), + ); + } + public static function providerPost() { + return array( + array('address', 'zhejiangU'), + array('step', '5'), + array('town', ''), + ); + } + public static function providerCookie() { + return array( + array('logIP', '10.1.123.99'), + array('loginTime', '2010-12-17'), + array('cookieName', ''), + ); + } + + public static function providerDefault() { + return array( + array('defaultName', 'thankYou'), + array('defaultValue', 'haha'), + array('helloWorld', 'me too'), + array('empty', ''), + ); + } + + private function checkArray($array, $num, $member = array(), $flag = false) { + $this->assertTrue(is_array($array)); + $this->assertTrue(count($array) == $num); + if (!$member) return; + foreach ((array)$member as $key => $value) { + ($flag) ? $this->assertEquals($value, $array[$key]) : + $this->assertTrue(isset($array[$value])); + } + } + private function slashesArray($param) { + static $result = array(); + foreach ((array)$param as $key => $value) { + if (is_array($value)) $this->slashesArray($value); + $result[$key] = stripslashes($value); + } + return $result; + } + /** + * @dataProvider providerSlashes + */ + public function teststripSlashes($params) { + if (is_array($params)) { + $param = $this->slashesArray($params); + $this->checkArray($this->httpRequest->stripSlashes($params), count($param), $param, true); + } else { + $this->assertEquals(stripslashes($params), $this->httpRequest->stripSlashes($params)); + } + } + + /** + * @dataProvider providerGet + */ + public function testGetAttributeFromGet($name, $value) { + $this->assertEquals($value, $this->httpRequest->getAttribute($name)); + } + + /** + * @dataProvider providerPost + */ + public function testGetAttributeFromPost($name, $value) { + $this->assertEquals($value, $this->httpRequest->getAttribute($name)); + } + + /** + * @dataProvider providerCookie + */ + public function testGetAttributeFromCookie($name, $value) { + $this->assertEquals($value, $this->httpRequest->getAttribute($name)); + } + + /** + * @dataProvider providerDefault + */ + public function testGetAttributeWithDefaultValue($name, $value) { + $this->assertEquals($value, $this->httpRequest->getAttribute($name, $value)); + } + + /** + * @dataProvider providerGet + */ + public function testGetQuery($name, $value) { + $this->assertEquals($value, $this->httpRequest->getQuery($name)); + } + + /** + * @dataProvider providerDefault + */ + public function testGetQueryWithDefault($name, $value) { + $this->assertEquals($value, $this->httpRequest->getQuery($name, $value)); + } + + public function testGetQuestWithNull() { + $param = $this->httpRequest->getQuery(); + $this->checkArray($param, 3, array('name', 'sex', 'file')); + $this->checkArray($param['file'], 2, array('filename1', 'filename2'), true); + } + + /** + * @dataProvider providerPost + */ + public function testGetPost($name, $value) { + $this->assertEquals($value, $this->httpRequest->getPost($name)); + } + /** + * @dataProvider providerDefault + */ + public function testGetPostWithDefault($name, $value) { + $this->assertEquals($value, $this->httpRequest->getPost($name, $value)); + } + + public function testGetPostWithNull() { + $param = $this->httpRequest->getPost(); + $this->checkArray($param, 2, array('address' => 'zhejiangU', 'step' => '5'), true); + } + + /** + * @dataProvider providerGet + */ + public function testGet($name, $value) { + $this->assertEquals($value, $this->httpRequest->getGet($name)); + } + /** + */ + public function testGetWithDefault() { + foreach(self::providerDefault() as $value) + $this->assertEquals($value[1], $this->httpRequest->getGet($value[0], $value[1])); + } + + public function testGetWithNull() { + $param = $this->httpRequest->getGet(); + $this->checkArray($param, 3, array('name', 'sex', 'file')); + $this->checkArray($param['file'], 2, array('filename1', 'filename2'), true); + } + + /** + * @dataProvider providerCookie + */ + public function testGetCookie($name, $value) { + $this->assertEquals($value, $this->httpRequest->getCookie($name)); + } + + /** + * @dataProvider providerDefault + */ + public function testGetCookieWithDefault($name, $value) { + $this->assertEquals($value, $this->httpRequest->getCookie($name, $value)); + } + + public function testGetCookieWithNull() { + $param = $this->httpRequest->getCookie(); + $this->checkArray($param, 2, array('logIP' => '10.1.123.99', 'loginTime' => '2010-12-17'), true); + } + + public function testGetSession() { + $_SESSION = array(); + $_SESSION['isAdmin'] = 'true'; + $_SESSION['goods'] = '1213'; + $this->assertEquals('true', $this->httpRequest->getSession('isAdmin')); + $this->assertEquals('1213', $this->httpRequest->getSession('goods')); + $this->assertEquals('', $this->httpRequest->getSession('name', '')); + $this->assertEquals('xxx', $this->httpRequest->getSession('name', 'xxx')); + $param = $this->httpRequest->getSession(); + $this->checkArray($param, 2, array('isAdmin' => 'true', 'goods' => '1213'), true); + } + + public function testGetServer() { + $_SERVER = array(); + $_SERVER['GLOBAL'] = 'D;//yes'; + $_SERVER['hahah'] = 'werwe'; + $this->assertEquals('D;//yes', $this->httpRequest->getServer('GLOBAL')); + $this->assertEquals('werwe', $this->httpRequest->getServer('hahah')); + $this->assertEquals('', $this->httpRequest->getServer('name', '')); + $this->assertEquals('xxx', $this->httpRequest->getServer('name', 'xxx')); + $param = $this->httpRequest->getServer(); + $this->checkArray($param, 2, array('GLOBAL' => 'D;//yes', 'hahah' => 'werwe'), true); + } + + public function testGetEnv() { + $_ENV = array(); + $_ENV['enviroment'] = 'apache2'; + $_ENV['version'] = '2.2'; + $this->assertEquals('apache2', $this->httpRequest->getEnv('enviroment')); + $this->assertEquals('2.2', $this->httpRequest->getEnv('version')); + $this->assertEquals('', $this->httpRequest->getEnv('name', '')); + $this->assertEquals('xxx', $this->httpRequest->getEnv('name', 'xxx')); + $param = $this->httpRequest->getEnv(); + $this->checkArray($param, 2, array('enviroment' => 'apache2', 'version' => '2.2'), true); + } + + public function testGetScheme() { + $scheme = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) ? 'https' : 'http'; + $this->assertTrue($scheme == $this->httpRequest->getScheme()); + } + + public function testGetProtocol() { + $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'; + $this->assertTrue($protocol == $this->httpRequest->getProtocol()); + } + + /** + * WindHttpRequest会在第一次运行后保持值·· + * 测试其他逻辑需要先注释已经有值的判断(//if (!$this->_clientIp)),同时去除注释 + */ + public function testGetClientIp() { + $this->assertTrue('0.0.0.0' == $this->httpRequest->getClientIp()); + $_SERVER['HTTP_CLIENT_IP'] = '192.168.0.200'; + /*$this->assertTrue('192.168.0.200' == $this->httpRequest->getClientIp()); + + $_SERVER['HTTP_PROXY_USER'] = '10.1.200.23'; + $_SERVER['HTTP_CLIENT_IP'] = ''; + $this->assertTrue('10.1.200.23' == $this->httpRequest->getClientIp()); + + $_SERVER['HTTP_PROXY_USER'] = ''; + $_SERVER['HTTP_CLIENT_IP'] = ''; + $_SERVER['REMOTE_ADDR'] = '172.36.5.2'; + $this->assertTrue('172.36.5.2' == $this->httpRequest->getClientIp());*/ + } + + public function testGetRequestMethod() { + $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : ''; + $this->assertEquals($method, $this->httpRequest->getRequestMethod()); + } + + public function testGetRequestType() { + //$this->assertEquals(IWindRequest::REQUEST_TYPE_WEB, $this->httpRequest->getRequestType()); + throw new PHPUnit_Framework_IncompleteTestError('no complete'); + } + + public function testGetIsAjaxRequest() { + $this->assertFalse($this->httpRequest->getIsAjaxRequest()); + } + + public function testIsSecure() { + $this->assertFalse($this->httpRequest->isSecure()); + } + public function testIsGet() { + $this->assertFalse($this->httpRequest->isGet()); + } + public function testIsPost() { + $this->assertFalse($this->httpRequest->isPost()); + } + public function testIsPut() { + $this->assertFalse($this->httpRequest->isPut()); + } + public function testIsDelete() { + $this->assertFalse($this->httpRequest->isDelete()); + } + + public function testGetRequestUriWithException() { + try{ + $uri = $this->httpRequest->getRequestUri(); + } catch (WindException $exception) { + return; + } + $this->fail('Exception'); + } + /** + * WindHttpRequest会在第一次运行后保持值·· + * 测试其他逻辑需要先注释已经有值的判断(//if (!$this->_requestUri)) + */ + public function testGetRequestUri() { + $_SERVER['HTTP_X_REWRITE_URL'] = '/example/index.php?a=test'; + $this->assertEquals('/example/index.php?a=test', $this->httpRequest->getRequestUri()); + + $_SERVER['HTTP_X_REWRITE_URL'] = ''; + $_SERVER['HTTP_HOST'] = 'http://www.phpwind.net'; + $_SERVER['REQUEST_URI'] = 'http://www.phpwind.net/example/index.php?a=test'; + $this->assertEquals('/example/index.php?a=test', $this->httpRequest->getRequestUri()); + + $_SERVER['REQUEST_URI'] = ''; + $_SERVER['ORIG_PATH_INFO'] = '/example/index.php'; + $_SERVER['QUERY_STRING'] = 'a=test'; + $this->assertEquals('/example/index.php?a=test', $this->httpRequest->getRequestUri()); + } + + public function testGetScriptUrlWithException() { + try{ + $url = $this->httpRequest->getScriptUrl(); + } catch (Exception $exception) { + $this->assertEquals('WindException', get_class($exception)); + return; + } + } + + /** + * WindHttpRequest会在第一次运行后保持值·· + * 测试其他逻辑需要先注释已经有值的判断(//if (!$this->_scriptUrl)) + */ + public function testGetScriptUrl() { + $_SERVER['SCRIPT_FILENAME'] = "/usr/ppt/demos/example/index.php"; + + $_SERVER['SCRIPT_NAME'] = '/usr/ppt/demos/example/index.php'; + $this->assertEquals('/usr/ppt/demos/example/index.php', $this->httpRequest->getScriptUrl()); + + $_SERVER['SCRIPT_NAME'] = ''; + $_SERVER['PHP_SELF'] = '/usr/ppt/demos/example/index.php'; + $this->assertEquals('/usr/ppt/demos/example/index.php', $this->httpRequest->getScriptUrl()); + + $_SERVER['PHP_SELF'] = ''; + $_SERVER['ORIG_SCRIPT_NAME'] = '/usr/ppt/demos/example/index.php'; + $this->assertEquals('/usr/ppt/demos/example/index.php', $this->httpRequest->getScriptUrl()); + + $_SERVER['ORIG_SCRIPT_NAME'] = ''; + $_SERVER['DOCUMENT_ROOT'] = 'D:/php'; + $_SERVER['SCRIPT_FILENAME'] = "D:/php/usr/ppt/demos/example/index.php"; + $this->assertEquals('/usr/ppt/demos/example/index.php', $this->httpRequest->getScriptUrl()); + + } + + public function testGetScript() { + $_SERVER['SCRIPT_FILENAME'] = "/usr/ppt/demos/example/index.php"; + $_SERVER['SCRIPT_NAME'] = '/usr/ppt/demos/example/index.php'; + $this->assertEquals('index.php', $this->httpRequest->getScript()); + } + + public function testGetHeader() { + $this->assertFalse($this->httpRequest->getHeader('accept')); + $_SERVER['HTTP_ACCEPT'] = 'HTTP1.0'; + $this->assertEquals('HTTP1.0', $this->httpRequest->getHeader('accept')); + $this->assertEquals('HTTP1.0', $this->httpRequest->getHeader('http-accept')); + $this->assertEquals('HTTP1.0', $this->httpRequest->getHeader('ACCEPT')); + } + public function testGetServerPort() { + $default = $this->httpRequest->isSecure() ? 443 : 80; + $port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : $default; + $this->assertEquals($port, $this->httpRequest->getServerPort()); + } + public function testGetHostInfoWithException() { + try{ + $this->httpRequest->getHostInfo(); + } catch(WindException $e) { + return; + } + $this->fail('an exception is catched'); + } + public function testGetHostInfo() { + $_SERVER['HTTP_HOST'] = 'localhost:80'; + $this->assertEquals('http://localhost:80', $this->httpRequest->getHostInfo()); + $_SERVER['HTTP_HOST'] = ''; + $_SERVER['SERVER_NAME'] = 'localhost'; + $this->assertEquals('http://localhost:80', $this->httpRequest->getHostInfo()); + } + public function testGetBaseUrl() { + $_SERVER['SCRIPT_FILENAME'] = "/usr/ppt/demos/example/index.php"; + $_SERVER['SCRIPT_NAME'] = '/usr/ppt/demos/example/index.php'; + $_SERVER['HTTP_HOST'] = 'localhost:80'; + $this->assertEquals('http://localhost:80/usr/ppt/demos/example', $this->httpRequest->getBaseUrl(true)); + $this->assertEquals('/usr/ppt/demos/example', $this->httpRequest->getBaseUrl(false)); + } + public function testGetPathInfoWithException() { + try{ + $this->assertEquals('', $this->httpRequest->getPathInfo()); + }catch(WindException $e) { + return ; + } + $this->fail('Exception error!'); + } + /** + * WindHttpRequest会在第一次运行后保持值·· + * 测试其他逻辑需要先注释已经有值的判断(//if (!$this->_pathInfo) ) + */ + public function testGetPathInfo() { + $_SERVER['HTTP_X_REWRITE_URL'] = '/example/index.php?a=test'; + $_SERVER['PHP_SELF'] = '/usr/ppt/demos/example/index.php?a=test'; + $_SERVER['SCRIPT_FILENAME'] = "/usr/ppt/demos/example/index.php"; + $_SERVER['SCRIPT_NAME'] = '/usr/ppt/demos/example/index.php'; + $this->assertTrue('' == $this->httpRequest->getPathInfo()); + } + + public function testGetServerName() { + $serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : ''; + $this->assertEquals($serverName, $this->httpRequest->getServerName()); + } + + public function testSetServerPort() { + $this->httpRequest->setServerPort(89); + $this->assertEquals(89, $this->httpRequest->getServerPort()); + } + + public function testGetRemoteHost() { + $value = isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : null; + $this->assertEquals($value, $this->httpRequest->getRemoteHost()); + } + + public function testGetUrlReferer() { + $value = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null; + $this->assertEquals($value, $this->httpRequest->getUrlReferer()); + } + public function testGetRemotePort() { + $value = isset($_SERVER['REMOTE_PORT']) ? $_SERVER['REMOTE_PORT'] : null; + $this->assertEquals($value, $this->httpRequest->getRemotePort()); + } + public function testGetUserAgent() { + $value = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; + $this->assertEquals($value, $this->httpRequest->getUserAgent()); + } + public function testGetAcceptTypes() { + $value = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : ''; + $this->assertEquals($value, $this->httpRequest->getAcceptTypes()); + } + + public function testGetAcceptCharset() { + $value = isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : ''; + $this->assertEquals($value, $this->httpRequest->getAcceptCharset()); + } + + public function testGetAcceptLanguage() { + $value = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : ''; + $language = explode(',', $value); + $value = $language[0] ? $language[0] : 'zh-cn'; + $this->assertEquals($value, $this->httpRequest->getAcceptLanguage()); + } + public function testGetResponse() { + $this->assertTrue($this->httpRequest->getResponse() instanceof WindHttpResponse); + } +} \ No newline at end of file diff --git a/_tests/core/response/WindHttpResponseTest.php b/_tests/core/response/WindHttpResponseTest.php new file mode 100644 index 00000000..84637361 --- /dev/null +++ b/_tests/core/response/WindHttpResponseTest.php @@ -0,0 +1,221 @@ + 2010-12-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * WindHttpResponse单元测试 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindHttpResponseTest extends BaseTestCase { + private $httpResponse; + public function setUp() { + parent::setUp(); + require_once('core/response/WindHttpResponse.php'); + require_once('core/exception/WindException.php'); + $this->httpResponse = WindHttpResponse::getInstance(); + } + public static function providerSets() { + return array( + array('name', 'xxx', false), + array('id_name', 'xjx', true), + array('-id_2', 'phpwind', false), + array('___2r_time', '2010', true), + array('--Pear---_lod', 'xiaowai', false), + array('-pear_id', '', false), + array(' ', 'contents', false), + array('', '', true), + array(' ', '', true), + ); + } + public static function providerAdd() { + return array( + array('name', 'phpSchool', true), + array('', '', false), + array('_id_name', 'hello', false), + array('-pear_id', 'iphone', true), + array('--Pear----lod', 'xiaonei', false), + array('-banan-QQ', '', false), + array('', 'contents', false), + array(' ', '', false), + ); + } + public static function providerStatus() { + return array( + array('200', ''), + array(10, ''), + array(505, 'errorMessage no is 505'), + array(499, '499'), + array(400, 'errorInfo no is 400'), + array(399, 'errorInfo no is 399'), + array(300, 'errorInfo no is 300'), + array(array(22), ''), + ); + } + public static function providerBody() { + return array( + array('i am content', ''), + array('i am header', 'header'), + array('i am body', array('body')), + array(array('i am lucy'), 'body'), + array('', 'footer'), + array('', ''), + ); + } + private function checkArray($array, $num, $member = array(), $flag = false) { + $this->assertTrue(is_array($array)); + $this->assertEquals($num, count($array)); + if (!$member) return; + foreach ((array)$member as $key => $value) { + if (!$flag) { + $this->assertTrue(isset($array[$value])); + continue; + } + $this->assertTrue(isset($array[$key]) && $value == $array[$key]); + } + } + + /** + * @dataProvider providerAdd + */ + public function testAddHeader($name, $value, $replace) { + $this->httpResponse->addHeader($name, $value, $replace); + $this->isTrue('OK'); + } + + public function testGetHeaderForAdd() { + $header = $this->httpResponse->getHeaders(); + $this->checkArray($header, 4); + $this->checkArray($header[0], 3, array('name' => 'Name', 'value' => 'phpSchool', 'replace' => true), true); + $this->checkArray($header[1], 3, array('name' => '-Id-Name', 'value' => 'hello', 'replace' => false), true); + $this->checkArray($header[2], 3, array('name' => '-Pear-Id', 'value' => 'iphone', 'replace' => true), true); + $this->checkArray($header[3], 3, array('name' => '--Pear----Lod', 'value' => 'xiaonei', 'replace' => false), true); + } + + /** + * @dataProvider providerSets + */ + public function testSetHeader($name, $value, $replace) { + $this->httpResponse->setHeader($name, $value, $replace); + $this->isTrue('OK'); + } + + public function testGetHeaderForSet() { + $header = $this->httpResponse->getHeaders(); + $this->checkArray($header, 4); + $this->checkArray($header[0], 3, array('name' => 'Name', 'value' => 'xxx', 'replace' => false), true); + $this->checkArray($header[1], 3, array('name' => '-Id-Name', 'value' => 'hello', 'replace' => false), true); + $this->checkArray($header[2], 3, array('name' => '-Pear-Id', 'value' => 'iphone', 'replace' => true), true); + $this->checkArray($header[3], 3, array('name' => '--Pear----Lod', 'value' => 'xiaowai', 'replace' => false), true); + } + + public function testClearHeaders() { + $this->httpResponse->clearHeaders(); + $header = $this->httpResponse->getHeaders(); + $this->checkArray($header, 0); + } + /** + * @dataProvider providerStatus + */ + public function testSetStatus($no, $message) { + $this->httpResponse->setStatus($no, $message); + $this->isTrue('OK'); + } + + /** + * @dataProvider providerBody + * @param string $content + * @param string $name + */ + public function testSetBody($content, $name) { + $this->httpResponse->setBody($content, $name); + $this->isTrue('OK'); + } + + public function testGetBodyByName() { + $this->assertEquals('i am body', $this->httpResponse->getBody('default')); + $this->assertEquals('', $this->httpResponse->getBody('footer')); + $this->assertEquals(null, $this->httpResponse->getBody('body')); + $this->assertEquals(null, $this->httpResponse->getBody(array('default'))); + $this->assertEquals('i am header', $this->httpResponse->getBody('header')); + } + public function testGetBodyByFalse() { + $content = array('default' => 'i am body', + 'header' => 'i am header'); + $this->assertEquals(implode('', $content), $this->httpResponse->getBody(false)); + } + public function testGetBodyByTrue() { + $content = array('default' => 'i am body', + 'header' => 'i am header'); + $this->checkArray($this->httpResponse->getBody(true), 2, $content, true); + } + + public function testSendBody() { + $content = array('default' => 'i am body', + 'header' => 'i am header'); + ob_start(); + $this->httpResponse->sendBody(); + $value = ob_get_clean(); + $this->assertEquals(implode('', $content), $value); + } + + public function testClearBody() { + $this->httpResponse->clearBody(); + $body = $this->httpResponse->getBody(true); + $this->checkArray($body, 0); + } + + public function testSetDispatcher() { + $this->httpResponse->setDispatcher(array('dispatcher')); + $this->isTrue('OK'); + } + public function testGetDispatcher() { + $dispatcher = $this->httpResponse->getDispatcher(); + $this->assertEquals('dispatcher', $dispatcher[0]); + } + + public function testIsSendedHeader() { + $this->assertFalse($this->httpResponse->isSendedHeader()); + /*echo 'send Header'; + $this->assertTrue($this->httpResponse->isSendedHeader());*/ + try{ + $this->httpResponse->isSendedHeader(true); + } catch(Exception $e) { + $this->assertTrue('WindException' == get_class($e)); + return; + } + } + + /** + * @dataProvider providerStatus + * @param unknown_type $no + * @param unknown_type $message + */ + public function testSendError($no, $message) { + $this->httpResponse->sendError($no, $message); + $this->isTrue('OK'); + } + + public function testSendErrorWithBody() { + $body = $this->httpResponse->getBody(true); + $this->checkArray($body, 1, array('default' => 'errorInfo no is 400'), true); + } + + public function testSendRedirect() { + throw new PHPUnit_Framework_IncompleteTestError('TODO'); + } + + public function testSendResponse() { + throw new PHPUnit_Framework_IncompleteTestError('TODO'); + } + public function testSendHeaders() { + throw new PHPUnit_Framework_IncompleteTestError('TODO'); + } +} \ No newline at end of file diff --git a/_tests/core/router/AllRouterTest.php b/_tests/core/router/AllRouterTest.php new file mode 100644 index 00000000..bb46f8d4 --- /dev/null +++ b/_tests/core/router/AllRouterTest.php @@ -0,0 +1,20 @@ + 2011-1-14 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('core/router/WindUrlBasedRouterTest.php'); + +class AllRouterTest { + public static function main() { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllRouterTest'); + $suite->addTestSuite('WindUrlBasedRouterTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/core/router/WindUrlBasedRouterTest.php b/_tests/core/router/WindUrlBasedRouterTest.php new file mode 100644 index 00000000..05886342 --- /dev/null +++ b/_tests/core/router/WindUrlBasedRouterTest.php @@ -0,0 +1,117 @@ +setGet($a, $c, $m); + $this->router->doParse($this->request, $this->response); + $url = $this->router->buildUrl(); + $this->assertEquals($url, 'http://localhost:80/index.php'); + } + + /** + * @param unknown_type $a + * @param unknown_type $c + * @param unknown_type $m + * @dataProvider providerWithDoParser + */ + public function testDoParser($a, $c, $m) { + $this->setGet($a, $c, $m); + $this->router->doParse($this->request, $this->response); + $this->assertEquals($this->router->getAction(), $a); + $this->assertEquals($this->router->getController(), $c); + $this->assertEquals($this->router->getModule(), $m); + } + + public function testDoParserWithNoConfig() { + $config = $this->getConfig(); + $config['module'] = ''; + $config['controller'] = ''; + $config['action'] = ''; + $this->router->setConfig(new WindConfig($config)); + $this->setGet('add', 'index', 'default'); + $this->router->doParse($this->request, $this->response); + $this->assertEquals($this->router->getAction(), 'run'); + $this->assertEquals($this->router->getController(), 'index'); + $this->assertEquals($this->router->getModule(), 'default'); + } + + public function testGetHandler() { + try{ + $this->router->getHandler($this->request, $this->response); + }catch(Exception $e) { + + } + } + + public function testGetHandlerWithErrorModuleConfig() { + $config = $this->getConfig(); + $config['module']['default-value'] = 'test'; + $this->router->setConfig(new WindConfig($config)); + $this->router->doParse($this->request, $this->response); + try{ + $this->router->getHandler($this->request, $this->response); + }catch(Exception $e) { + $this->assertEquals('WindException', get_class($e)); + return; + } + $this->fail('error'); + } + + public function providerWithDoParser() { + $args = array(); + $args[] = array('add', 'index', 'default'); + return $args; + } + + private function setGet($a, $c, $m) { + $_GET['a'] = $a; + $_GET['c'] = $c; + $_GET['m'] = $m; + } + + private function getConfig() { + return array( + 'module' => array( + 'url-param' => 'm', + 'default-value' => 'default', + ), + 'controller' => array( + 'url-param' => 'c', + 'default-value' => 'index', + ), + 'action' => array( + 'url-param' => 'a', + 'default-value' => 'run', + ), + ); + } + protected function setUp() { + parent::setUp(); + require_once 'core/router/WindUrlBasedRouter.php'; + require_once 'core/request/WindHttpRequest.php'; + require_once 'core/config/WindSystemConfig.php'; + $this->router = new WindUrlBasedRouter(); + $this->request = new WindHttpRequest(); + $this->router->setConfig(new WindConfig($this->getConfig())); + $config = include(T_P . '/data/config.php'); + $this->request->setAttribute(WindFrontController::WIND_CONFIG, new WindSystemConfig($config['wind'], null, 'testApp')); + $this->response = $this->request->getResponse(); + } +} + diff --git a/_tests/core/viewer/AllViewerTest.php b/_tests/core/viewer/AllViewerTest.php new file mode 100644 index 00000000..03755247 --- /dev/null +++ b/_tests/core/viewer/AllViewerTest.php @@ -0,0 +1,23 @@ + 2011-1-28 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once ('core/viewer/WindViewerTest.php'); +require_once ('core/viewer/WindViewTest.php'); + +class AllViewerTest { + public static function main() { + PHPUnit_TestUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllViewerTest'); + $suite->addTestSuite('WindViewerTest'); + $suite->addTestSuite('WindViewTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/core/viewer/WindViewTest.php b/_tests/core/viewer/WindViewTest.php new file mode 100644 index 00000000..04f235a8 --- /dev/null +++ b/_tests/core/viewer/WindViewTest.php @@ -0,0 +1,100 @@ +createWindView(); + $viewResolver = $windView->createViewerResolver(); + $this->assertEquals('WindViewer', get_class($viewResolver), 'test create viewer resolver failed.'); + } + + public function testInitViewWithForward() { + $windView = $this->createWindView(); + $this->assertEquals($windView->templateDefault, 'index'); + $this->assertEquals($windView->initViewWithForward($this->createWindForward())->templateDefault, 'testIndex'); + } + + /** + * @dataProvider providerConfig + */ + public function testCreateWindView($configName, $config) { + $windView = $this->createWindView($configName, $config); + $this->assertEquals($windView->templateDir, 'template'); + $this->assertEquals($windView->templateExt, 'htm'); + $this->assertEquals($windView->templateDefault, 'index'); + $this->assertEquals($windView->templateCacheDir, 'cache'); + $this->assertEquals($windView->templateCompileDir, 'compile'); + } + + /** + * @dataProvider providerErrorConfig + */ + public function testCreateWindViewWithErrorConfig($configName, $config) { + try { + $windView = $this->createWindView($configName, $config); + } catch (Exception $exception) { + $this->assertEquals(get_class($exception), 'WindException'); + } + } + + private function createWindForward() { + $forward = new WindForward(); + $forward->setTemplateName('testIndex'); + return $forward; + } + + private function createWindView($configName = '', $config = array()) { + if (!empty($config)) C::init($config); + require_once 'core/WindView.php'; + return new WindView($configName); + } + + public function providerErrorConfig() { + $configs = array(); + $configs[] = array('', array()); + $configs[] = array('wind', + array( + 'templates' => array( + 'default' => array('dir' => 'template', 'default' => 'index', 'ext' => 'htm', + 'resolver' => 'default', 'isCache' => '0', 'cacheDir' => 'cache', + 'compileDir' => 'compile'), + 'wind1' => array('dir' => 'template', 'default' => 'index', 'ext' => 'htm', + 'resolver' => 'default', 'isCache' => '0', 'cacheDir' => 'cache', + 'compileDir' => 'compile')), + 'viewerResolvers' => array('default' => 'WIND:core.viewer.WindViewer'))); + return $configs; + } + + public function providerConfig() { + $configs = array(); + $configs[] = array('wind', + array( + 'templates' => array( + 'default' => array('dir' => 'template', 'default' => 'index', 'ext' => 'htm', + 'resolver' => 'default', 'isCache' => '0', 'cacheDir' => 'cache', + 'compileDir' => 'compile'), + 'wind' => array('dir' => 'template', 'default' => 'index', 'ext' => 'htm', + 'resolver' => 'default', 'isCache' => '0', 'cacheDir' => 'cache', + 'compileDir' => 'compile')), + 'viewerResolvers' => array('default' => 'WIND:core.viewer.WindViewer'))); + $configs[] = array('default', + array( + 'templates' => array( + 'default' => array('dir' => 'template', 'default' => 'index', 'ext' => 'htm', + 'resolver' => 'default', 'isCache' => '0', 'cacheDir' => 'cache', + 'compileDir' => 'compile'), + 'wind' => array('dir' => 'template', 'default' => 'index', 'ext' => 'htm', + 'resolver' => 'default', 'isCache' => '0', 'cacheDir' => 'cache', + 'compileDir' => 'compile')), + 'viewerResolvers' => array('default' => 'WIND:core.viewer.WindViewer'))); + return $configs; + } + + protected function setUp() { + parent::setUp(); + } + + protected function tearDown() { + parent::tearDown(); + } +} + diff --git a/_tests/core/viewer/WindViewerTest.php b/_tests/core/viewer/WindViewerTest.php new file mode 100644 index 00000000..98532c40 --- /dev/null +++ b/_tests/core/viewer/WindViewerTest.php @@ -0,0 +1,94 @@ +viewer->windFetch(); + $this->assertStringEqualsFile($templateFile, $content); + } + + /** + * @param string $templateFile + * @dataProvider providerWindFetch + */ + public function testImmediatelyWindFetch($templateFile) { + ob_start(); + $this->viewer->immediatelyWindFetch(); + $content = ob_get_clean(); + $this->assertStringEqualsFile($templateFile, $content); + } + + public function providerWindFetch() { + $args = array(); + $args[] = array(T_P . D_S . 'data' . D_S . 'pageTemplate.htm'); + return $args; + } + + /** + * @dataProvider providerViewerWithLayout + */ + public function testViewerWithLayout($layoutFile, $templateFile) { + $layout = new WindLayout(); + $layout->setLayoutFile($layoutFile); + $this->viewer->setLayout($layout); + $content = $this->viewer->windFetch(); + $this->assertStringEqualsFile($templateFile, $content); + } + + public function providerViewerWithLayout() { + $args = array(); + $args[] = array('pageLayout', T_P . D_S . 'data' . D_S . 'pageTemplate.htm'); + return $args; + } + + /** + * @dataProvider providerWindAssign + */ + public function testWindAssign($vars, $key) { + $this->viewer->windAssign($vars, $key); + $this->assertEquals($this->viewer->getVar('test1'), '1'); + $obj = $this->viewer->getVarWithObject('pageTemplate'); + $this->assertEquals($obj->test1, '1'); + } + + public function providerWindAssign() { + $std = new stdClass(); + $std->test1 = '1'; + $std->test2 = '2'; + $std->test3 = '3'; + $args = array(); + $args[] = array(array('test1' => '1', 'test2' => '2', 'test3' => '3'), ''); + $args[] = array($std, ''); + $args[] = array('1', 'test1'); + return $args; + } + + public function testInitWithView() { + + } + + private function initViewerWithView() { + include_once 'data/config.php'; + $view = new WindView('default'); + $view->templateDir = 'data'; + $view->templateDefault = 'pageTemplate'; + $view->templateExt = 'htm'; + $this->viewer->initWithView($view); + } + + protected function setUp() { + parent::setUp(); + require_once 'core/viewer/WindViewer.php'; + require_once 'core/viewer/WindView.php'; + require_once 'core/viewer/WindLayout.php'; + $this->viewer = new WindViewer(); + $this->initViewerWithView(); + } + +} + diff --git a/_tests/core/web/AllWebTest.php b/_tests/core/web/AllWebTest.php new file mode 100644 index 00000000..d12caf16 --- /dev/null +++ b/_tests/core/web/AllWebTest.php @@ -0,0 +1,21 @@ + 2011-1-28 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once('core/web/WindForwardTest.php'); + +class AllWebTest { + public static function main() { + PHPUnit_TestUI_TestRunner::run(self::suite()); + } + + public static function suite() { + $suite = new PHPUnit_Framework_TestSuite('WindFramework AllWebTest'); + $suite->addTestSuite('WindForwardTest'); + return $suite; + } +} \ No newline at end of file diff --git a/_tests/core/web/WindForwardTest.php b/_tests/core/web/WindForwardTest.php new file mode 100644 index 00000000..297d26aa --- /dev/null +++ b/_tests/core/web/WindForwardTest.php @@ -0,0 +1,101 @@ +windForward->setLayout($layout); + $this->assertEquals(get_class($this->windForward->getLayout()), 'WindLayout'); + } + + public function providerWithLayout() { + require_once 'core/WindLayout.php'; + $args = array(); + $args[] = array(new WindLayout()); + return $args; + }*/ + + /** + * @dataProvider providerWithForwardAction + */ + public function testWindForwardAction($action, $actionPath, $isRedirect, $args) { + $this->windForward->setAction($action, $actionPath, $isRedirect, $args); + $this->assertEquals($this->windForward->getAction(), $action); + $this->assertEquals($this->windForward->getActionPath(), $actionPath); + if ($isRedirect) + $this->assertEquals(get_class($this->windForward->getRedirecter()), 'WindUrlManager'); + else + $this->assertNull($this->windForward->getRedirecter()); + } + + public function providerWithForwardAction() { + $args = array(); + $args[] = array('hello', '', false, array()); + $args[] = array('hello', 'defaultControllers.indexController', false, array()); + $args[] = array('hello', 'defaultControllers.indexController', true, array()); + $args[] = array('hello', 'defaultControllers.indexController', true, array('a' => '111')); + return $args; + } + + /** + * @dataProvider providerWithForwardTemplate + */ + public function testWindForwardTemplate($templateName, $templatePath, $templateConfig) { + $this->windForward->setTemplateName($templateName); + $this->assertEquals($this->windForward->getTemplateName(), $templateName); + + $this->windForward->setTemplatePath($templatePath); + $this->assertEquals($this->windForward->getTemplatePath(), $templatePath); + + $this->windForward->setTemplateConfig($templateConfig); + $this->assertEquals($this->windForward->getTemplateConfig(), $templateConfig); + } + + public function providerWithForwardTemplate() { + $args = array(); + $args[] = array('hello', '', ''); + $args[] = array('hello', 'hello.template', ''); + $args[] = array('hello', 'hello.template', 'default'); + return $args; + } + + /** + * @param string $vars + * @param string $key + * + * @dataProvider providerWithSetVars + */ + public function testSetVars($vars, $key = '') { + $this->windForward->setVars($vars, $key); + $_vars = $this->windForward->getVars(); + $this->assertEquals('1', $_vars['test1']); + } + + public function providerWithSetVars() { + $std = new stdClass(); + $std->test1 = '1'; + $args = array(); + $args[] = array('1', 'test1'); + $args[] = array(array('test1' => '1')); + $args[] = array($std); + return $args; + } + + protected function setUp() { + parent::setUp(); + require_once 'core/web/WindForward.php'; + $this->windForward = new WindForward(); + } + + protected function tearDown() { + parent::tearDown(); + } + +} + diff --git a/_tests/data/ForWindClassDefinition.php b/_tests/data/ForWindClassDefinition.php new file mode 100644 index 00000000..8b1d7b33 --- /dev/null +++ b/_tests/data/ForWindClassDefinition.php @@ -0,0 +1,38 @@ + 2011-1-30 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +class ForWindClassDefinition { + private $message = ''; + + public function __construct() { + $this->message = 'test'; + } + + public static function factory() { + return new self(); + } + + public function init() { + $this->message = 'new'; + } + + /** + * @return the $message + */ + public function getMessage() { + return $this->message; + } + + /** + * @param field_type $message + */ + public function setMessage($message) { + $this->message = $message; + } + +} \ No newline at end of file diff --git a/_tests/data/ForWindClassProxy.php b/_tests/data/ForWindClassProxy.php new file mode 100644 index 00000000..0d72f1d2 --- /dev/null +++ b/_tests/data/ForWindClassProxy.php @@ -0,0 +1,81 @@ + 2010-11-2 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2010 phpwind.com + * @license + */ + +require_once 'core/filter/WindHandlerInterceptor.php'; + +class Listener extends WindHandlerInterceptor { + + public $test; + + public $testB; + + public function preHandle($userName = '') { + $this->test = $userName . '_preHandle'; + } + + public function postHandle($userName = '') { + $this->testB = $userName . '_postHandle'; + } + +} + +class Listener1 extends WindHandlerInterceptor { + + public $arg1; + + public $arg2; + + public function preHandle($arg1 = '', $arg2 = '') { + $this->arg1 = $arg1 . '_pre'; + $this->arg2 = $arg2 . '_pre'; + } + + public function postHandle($arg1 = '', $arg2 = '') { + $this->arg1 .= '_' . $arg1 . '_post'; + $this->arg2 .= '_' . $arg2 . '_post'; + } + +} + +/** + * Enter description here ... + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class Persion { + + public $name = ''; + + public $arg1; + + public $arg2; + + /** + * @return the $name + */ + public function getName() { + return $this->name; + } + + /** + * @param field_type $name + */ + public function setName($name) { + $this->name = $name; + } + + public function testPersion($arg1, $arg2) { + $this->arg1 = $arg1; + $this->arg2 = $arg2; + return $this->arg1; + } + +} \ No newline at end of file diff --git a/_tests/data/ForWindFilter.php b/_tests/data/ForWindFilter.php new file mode 100644 index 00000000..c8df24ba --- /dev/null +++ b/_tests/data/ForWindFilter.php @@ -0,0 +1,24 @@ + 2011-1-25 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once "core/filter/WindFilter.php"; + +class ForWindFilter extends WindFilter { + public function preHandle() { + $args = func_get_args(); + $a = isset($args[0]) ? trim($args[0]) : 'a'; + $b = isset($args[1]) ? trim($args[1]) : 'b'; + echo "{$a}+{$b}"; + } + public function postHandle() { + $args = func_get_args(); + $a = isset($args[0]) ? trim($args[0]) : ''; + $b = isset($args[1]) ? trim($args[1]) : ''; + echo "\$a={$a},\$b={$b}"; + } +} \ No newline at end of file diff --git a/_tests/data/TestForm.php b/_tests/data/TestForm.php new file mode 100644 index 00000000..10e2b27b --- /dev/null +++ b/_tests/data/TestForm.php @@ -0,0 +1,81 @@ + 2010-12-29 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +require_once('component/form/WindActionForm.php'); +class TestForm extends WindActionForm { + protected $name; + protected $password; + protected $address = 'hangz'; + protected $nick; + + public function __construct() { + $this->setIsValidation(true); + $this->setErrorAction('class', 'showError'); + } + + public function nameValidate() { + if (strlen($this->name) < 6) { + $this->addError('name too short', 'nameError'); + } + } + /** + * @return the $name + */ + public function getName() { + return $this->name; + } + + /** + * @return the $password + */ + public function getPassword() { + return $this->password; + } + + /** + * @return the $address + */ + public function getAddress() { + return $this->address; + } + + /** + * @return the $nick + */ + public function getNick() { + return $this->nick; + } + + /** + * @param field_type $name + */ + public function setName($name) { + $this->name = $name; + } + + /** + * @param field_type $password + */ + public function setPassword($password) { + $this->password = $password; + } + + /** + * @param field_type $address + */ + public function setAddress($address) { + $this->address = $address; + } + + /** + * @param field_type $nick + */ + public function setNick($nick) { + $this->nick = $nick; + } +} \ No newline at end of file diff --git a/_tests/data/WindIniParserTest.ini b/_tests/data/WindIniParserTest.ini new file mode 100644 index 00000000..3291f587 --- /dev/null +++ b/_tests/data/WindIniParserTest.ini @@ -0,0 +1,31 @@ +name=test +people.name=xxx +people.sex=1 +people.job=PHP + + +xxx.name=sfewr +xxx.school=浙江 +xxx.sex=f + + +student.your.name.second.value=i +your.name.second.name=am +your.name.second.key=your +your.name.second.attribute=friend + +[xjx] +address = china +sex=0 +job = java + +[student] +name=xxx +school=zhejiang +home.address.country=china +home.address.city=jinh +home.address.town=changs + +your.name.second.value=dddddddd +your.name.second.name=amssssss +your.name.second.key=your \ No newline at end of file diff --git a/_tests/data/WindPropertiesParserTest.properties b/_tests/data/WindPropertiesParserTest.properties new file mode 100644 index 00000000..2b904998 --- /dev/null +++ b/_tests/data/WindPropertiesParserTest.properties @@ -0,0 +1,22 @@ +name=test +people.name=xxx +people.sex=1 +people.job=PHP + + +xxx.name=sfewr +xxx.school=浙江 +xxx.sex=f + + +student.your.name.second.value=i +your.name.second.name=am +your.name.second.key=your +your.name.second.attribute=friend + + +[xjx] +namexjx=ddd +address = china +sex = 0 +job.name = java diff --git a/_tests/data/WindXmlParserTest.xml b/_tests/data/WindXmlParserTest.xml new file mode 100644 index 00000000..35472f04 --- /dev/null +++ b/_tests/data/WindXmlParserTest.xml @@ -0,0 +1,51 @@ + + + + + + wind + 100 + windFramework + + + 20 + 200 + + + C# + 30 + 150 + + + C++ + 0.0002 + true + + + C++ + 0.0002 + true + zhejiang + thanks + + C++ + 0.0002 + + + + + Smarty + 0.0002 + false + + + framework + 0.0002 + true + + + key + 0.0002 + false + + \ No newline at end of file diff --git a/_tests/data/classes_config.xml b/_tests/data/classes_config.xml new file mode 100644 index 00000000..c84bdb64 --- /dev/null +++ b/_tests/data/classes_config.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/_tests/data/component_config.xml b/_tests/data/component_config.xml new file mode 100644 index 00000000..b37428df --- /dev/null +++ b/_tests/data/component_config.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_tests/data/config.php b/_tests/data/config.php new file mode 100644 index 00000000..7387a6dc --- /dev/null +++ b/_tests/data/config.php @@ -0,0 +1,95 @@ + array( + 'imports' => array( + 'components' => array( + 'resource' => 'TEST:data.component_config', + 'suffix' => 'xml', + 'init-delay' => 'false', + 'is-append' => 'true', + ), + 'classes' => array( + 'resource' => 'TEST:data.classes_config', + 'suffix' => 'xml', + 'init-delay' => 'false', + 'is-append' => 'true', + ), + ), + 'web-apps' => array( + 'testApp' => array( + 'class' => 'windWebApp', + 'root-path' => '', + 'factory' => array( + 'class-definition' => 'components', + 'class' => 'WIND:core.factory.WindComponentFactory', + ), + 'filters' => array( + 'class' => 'WIND:core.filter.WindFilterChain', + 'filter1' => array( + 'class' => 'WIND:core.web.filter.WindLoggerFilter', + ), + ), + 'router' => array( + 'class' => 'urlBasedRouter', + ), + 'modules' => array( + 'default' => array( + 'path' => 'actionControllers', + 'default' => array( + 'path' => 'template', + 'ext' => 'htm', + 'view-resolver' => array( + 'class' => 'WIND:core.viewer.WindViewer', + 'is-cache' => 'false', + 'cache-dir' => 'cache', + 'compile-dir' => 'compile', + ), + ), + ), + ), + ), + ), + ), + 'components' => array( + 'windWebApp' => array( + 'path' => 'WIND:core.web.WindWebApplication', + 'scope' => 'request', + 'proxy' => 'true', + ), + 'windLogger' => array( + 'path' => 'WIND:component.log.WindLogger', + 'scope' => 'request', + 'config' => array( + 'path' => '', + ), + ), + 'urlBasedRouter' => array( + 'path' => 'WIND:core.router.WindUrlBasedRouter', + 'scope' => 'application', + 'proxy' => 'true', + 'config' => array( + 'module' => array( + 'url-param' => 'm', + 'default-value' => 'default', + ), + 'controller' => array( + 'url-param' => 'c', + 'default-value' => 'index', + ), + 'action' => array( + 'url-param' => 'a', + 'default-value' => 'run', + ), + ), + ), + 'viewResolver' => array( + 'path' => 'WIND:core.viewer.WindViewer', + 'scope' => 'request', + ), + 'db' => array( + 'path' => 'WIND:component.db.WindConnectionManager', + 'scope' => 'singleton', + ), + ), +); +?> \ No newline at end of file diff --git a/_tests/data/db_config.php b/_tests/data/db_config.php new file mode 100644 index 00000000..c7699eac --- /dev/null +++ b/_tests/data/db_config.php @@ -0,0 +1,31 @@ + 2011-1-30 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +return array( + 'connections' => array( + 'phpwind' => array( + 'driver' => 'mysql', + 'host' => 'localhost', + 'user' => 'root', + 'password' => 'root', + 'port' => '3306', + 'name' => 'phpwind803', + 'charset' => 'utf8', + ), + ), + 'drivers' => array( + 'mysql' => array( + 'builder' => 'mysql', + 'class' => 'WIND:component.db.drivers.mysql.WindMySql', + ), + ), + 'builders' => array( + 'mysql' => array( + 'class' => 'WIND:component.db.drivers.mysql.WindMySqlBuilder', + ), + ), +); \ No newline at end of file diff --git a/_tests/data/formConfig.xml b/_tests/data/formConfig.xml new file mode 100644 index 00000000..bc34a935 --- /dev/null +++ b/_tests/data/formConfig.xml @@ -0,0 +1,8 @@ + + + formName +
+ default + TEST:data +
+
diff --git a/_tests/data/layout.htm b/_tests/data/layout.htm new file mode 100644 index 00000000..3fdf2feb --- /dev/null +++ b/_tests/data/layout.htm @@ -0,0 +1,3 @@ +setSegments('header') ?> +setContent() ?> +setSegments('footer') ?> \ No newline at end of file diff --git a/_tests/data/pageLayout.htm b/_tests/data/pageLayout.htm new file mode 100644 index 00000000..c73ad605 --- /dev/null +++ b/_tests/data/pageLayout.htm @@ -0,0 +1 @@ +setSegments($this->tplName) ?> diff --git a/_tests/data/pageTemplate.htm b/_tests/data/pageTemplate.htm new file mode 100644 index 00000000..90d73004 --- /dev/null +++ b/_tests/data/pageTemplate.htm @@ -0,0 +1 @@ +hello world. diff --git a/_tests/data/test_config.ini b/_tests/data/test_config.ini new file mode 100644 index 00000000..2108cef2 --- /dev/null +++ b/_tests/data/test_config.ini @@ -0,0 +1,2 @@ +applications.web.class = WIND:core.WindWebApplication +rootPath=D:/phpwind \ No newline at end of file diff --git a/_tests/data/test_config.php b/_tests/data/test_config.php new file mode 100644 index 00000000..a7377400 --- /dev/null +++ b/_tests/data/test_config.php @@ -0,0 +1,18 @@ + 2010-12-20 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +return array( + 'applications' => array( + 'com' => array( + 'class' => 'WindPHPWind', + ), + ), + 'extensionConfig' => array( + 'formConfig' => 'controllers.actionForm', + ) +); +?> \ No newline at end of file diff --git a/_tests/data/test_config.properties b/_tests/data/test_config.properties new file mode 100644 index 00000000..175d59f8 --- /dev/null +++ b/_tests/data/test_config.properties @@ -0,0 +1,3 @@ +#error +error.QQ.class=WindErrorAction +extensionConfig.formConfig = test:controllers \ No newline at end of file diff --git a/_tests/data/test_config.xml b/_tests/data/test_config.xml new file mode 100644 index 00000000..58a91066 --- /dev/null +++ b/_tests/data/test_config.xml @@ -0,0 +1,13 @@ + + + + + WIND:component.form.WindFormFilter1 + + + + + WIND:core.viewer.WindViewer + + + \ No newline at end of file diff --git a/_tests/readme b/_tests/readme new file mode 100644 index 00000000..ed21a05a --- /dev/null +++ b/_tests/readme @@ -0,0 +1,87 @@ +****************************************************************** +说明如下: +****************************************************************** +要用phpunit进行单元测试,需要先在zend中设置你的工程使用的unit类库,方法如下: +1]、点击需要测试的工程,右键->properties: +2]、在该选项框的左边选中:php-Include-Path +3]、在右边的选项卡片中,选中:Libraries +如果里面已经含有phpunit类库则可以跳过下面的步骤: +4]、单击添加类库按钮:Add Library +5]、选中PHPUnit,一路Next,然后OK 即可 +如果zend studio中没有默认的PHPUnit类库,则需要自己去网上下载该包并引入。 + + +****************************************************************** +目录说明: +单元测试的目录结构和框架的目录结构采用相同的结构, +对应目录下的单元测试放在对应的测试目录中。 +每个目录下都需要建一个统一测试该目录下的所有测试类的测试类,名称以All+目录名+Test为类名及文件名 +并且该类继承BaseTestSuite类 + + +****************************************************************** +测试编写说明: +引入文件:BaseTestCase.php //该文件中声明了一个常量R_P, 指定到框架所在目录的 +同时申明了一个BaseTestCase 和BaseTestSuite类分别 +继承了PHPUnit_Framework_TestCase和PHPUnit_Framework_TestSuite +--------------------------------------------------------------------- +单元测试单个测试类编写: +1、以类文件名字前加Test为测试类的类名及文件名。 + 比如,我要测试WindMySqlBuilder这个类,则将名字取名为WindMySqlBuilderTest +2、这个测试类需要继承BaseTestCase这个基类, +3、测试类中根据测试的需要加载自己的类文件,比如加载WindMySqlBuilder,而其 + 所需的基础文件已经在BaseTestCase这个文件中加载,需要引入这个文件 +4、该测试类中如果有初始化的信息可以重写setup ,销毁调用tearDown +5、对于需要测试的函数,需要使用test+方法名,添加测试方法 +6、测试的执行:点击页面右键->run as -> PHPUnit + 或者使用快捷键:alt+shift+x U + + +注意:这里需要引入要测试的类 + +--------------------------------------------------------------------- +单元测试多个测试类同时测试编写---suite: +1、继承PHPUnit_Framework_TestSuite 的子类BaseTestSuite +2、重写静态方法suite,该方法在加载完需要测试的测试类后最终返回一个自身对象 +3、加载测试类:有两种方式: + 1): addTest();//这个需要加载的是PHPUnit_Framework_TestSuite的子类对象,所以如果要用该方法加载,需要用测试类创建该对象 + 比如: addTest(new PHPUnit_Framework_TestSuite('TestWSqlBuilder')); + 同时该方法也用于在该suite集中增加另外一个suite集,比如我实现了一个suite是AllCoreTest + 则: addTest(AllCoreTest::suite()); + 2): addTestSuite();//这个需要加载只要测试类的名字就可以,该方法会自动创建对象 + 比如: addTestSuite('TestWSqlBuilder'); + +4、执行该suite + 点击页面右键->run as -> PHPUnit + 或者使用快捷键:alt+shift+x U + +注意:这里需要引入要加载的测试类 + + +------------------------------------------------------------------- +全局测试类的入口: +该为了使用方便,该测试部署也提供了一个全局的测试类入口,用来测试所有测试类 +入口为止:测试根目录下的WindAllTests.php文件, 执行该文件,将会测试所有被加载的测试类 +该类也是一个suite,满足上面所有suite需要的要求,不同的是: +1、该类中suite方法中加载了所有对应子目录下的AllTests 类, 而无需加载每一个测试类。 +2、该类引入的文件也除基本测试配置文件(BaseTestSetting)之外只要引入对应的AllTests类文件即可 + + + + +****************************************************************** +断言方法:assert* +****************************************************************** +测试结果说明: +红色条:存在测试失败的方法 +绿色条:全部方法测试成功 + +方法前面的: +红色叉叉:测试失败的方法 +蓝色叉叉:含有测试失败的情况 +绿色勾勾:测试成功的方法 + + + + + diff --git a/_tests/windTest.bat b/_tests/windTest.bat new file mode 100644 index 00000000..a6f90284 --- /dev/null +++ b/_tests/windTest.bat @@ -0,0 +1,2 @@ +set TEST_DIR=%cd% +phpunit --bootstrap "%TEST_DIR%/bootstrap.php" %* \ No newline at end of file diff --git a/_tests/windTest.sh b/_tests/windTest.sh new file mode 100644 index 00000000..5b0d55c0 --- /dev/null +++ b/_tests/windTest.sh @@ -0,0 +1,18 @@ +#!/usr/bin/php + + */ + +require dirname(__FILE__) . '/bootstrap.php'; + +require_once 'PHPUnit/Util/Filter.php'; + +PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT'); + +require 'PHPUnit/TextUI/Command.php'; + +define('PHPUnit_MAIN_METHOD', 'PHPUnit_TextUI_Command::main'); + +PHPUnit_TextUI_Command::main(); \ No newline at end of file diff --git a/demos/helloworld/controller/IndexController.php b/demos/helloworld/controller/IndexController.php new file mode 100644 index 00000000..aaacbe8c --- /dev/null +++ b/demos/helloworld/controller/IndexController.php @@ -0,0 +1,19 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class IndexController extends WindController { + + public function run() { + echo 'Hello world'; + exit(); + } + +} +?> \ No newline at end of file diff --git a/demos/helloworld/index.php b/demos/helloworld/index.php new file mode 100644 index 00000000..4010fabc --- /dev/null +++ b/demos/helloworld/index.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/docs/configtemplate/compiler_config.xml b/docs/configtemplate/compiler_config.xml new file mode 100644 index 00000000..f6af5359 --- /dev/null +++ b/docs/configtemplate/compiler_config.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/configtemplate/db_config.xml b/docs/configtemplate/db_config.xml new file mode 100644 index 00000000..46e52d46 --- /dev/null +++ b/docs/configtemplate/db_config.xml @@ -0,0 +1,15 @@ + + + + + mysql + master + localhost + root + + 3306 + phpwind + utf8 + + + diff --git a/docs/configtemplate/dbcache_config.xml b/docs/configtemplate/dbcache_config.xml new file mode 100644 index 00000000..078cf251 --- /dev/null +++ b/docs/configtemplate/dbcache_config.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/docs/configtemplate/filecache_config.xml b/docs/configtemplate/filecache_config.xml new file mode 100644 index 00000000..8c4e3b44 --- /dev/null +++ b/docs/configtemplate/filecache_config.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/docs/configtemplate/ini/compiler_config.ini b/docs/configtemplate/ini/compiler_config.ini new file mode 100644 index 00000000..404ea13e --- /dev/null +++ b/docs/configtemplate/ini/compiler_config.ini @@ -0,0 +1,9 @@ +;配置自定义模板标签 +;[support-tags] +;标签tag1的配置 +;标签 +;tag1.tag= +;标签匹配表达式 +;tag1.pattern= +;标签编译的类文件 +;tag1.compiler= diff --git a/docs/configtemplate/ini/db_config.ini b/docs/configtemplate/ini/db_config.ini new file mode 100644 index 00000000..4a7a05b6 --- /dev/null +++ b/docs/configtemplate/ini/db_config.ini @@ -0,0 +1,10 @@ +;dbConfig的配置信息 +;可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 +myConnection.driver=mysql +myConnection.type=master +myConnection.host=localhost +myConnection.user=root +myConnection.password= +myConnection.port=3306 +myConnection.name=phpwind +myConnection.charset=utf8 diff --git a/docs/configtemplate/ini/dbcache_config.ini b/docs/configtemplate/ini/dbcache_config.ini new file mode 100644 index 00000000..bf5b66f8 --- /dev/null +++ b/docs/configtemplate/ini/dbcache_config.ini @@ -0,0 +1,17 @@ +;数据库缓存的配置信息 + +;配置数据缓存表 +[cache-table] +table-name.value=pw_cache +field-key.value=name +field-value.value=cache +field-expire.value=time +expirestrage.value=true + +;缓存key是否经过安全处理 +[security] +value=true + +;缓存过期时间 +[expires] +value=20 \ No newline at end of file diff --git a/docs/configtemplate/ini/filecache_config.ini b/docs/configtemplate/ini/filecache_config.ini new file mode 100644 index 00000000..8ff58ec0 --- /dev/null +++ b/docs/configtemplate/ini/filecache_config.ini @@ -0,0 +1,12 @@ +;文件缓存配置 + +;缓存文件的保存路径(支持命名空间的方式配置该路径) +cache-dir.value=WEB:compile +;缓存的级别 +cache-level.value=0 +;缓存文件的后缀 +cache-suffix.value=php +;缓存文件的key值是否经过安全处理 +security.value=true +;缓存文件的过期时间 +expires.value=20 \ No newline at end of file diff --git a/docs/configtemplate/ini/memcache.ini b/docs/configtemplate/ini/memcache.ini new file mode 100644 index 00000000..fce4a4e2 --- /dev/null +++ b/docs/configtemplate/ini/memcache.ini @@ -0,0 +1,21 @@ +;memcache配置 + +;memcache服务器相关配置 可以配置多个 +[servers] +phpwind.host=127.0.0.1 +phpwind.port=11211 + +cac.host=127.0.0.1 +cac.port=11212 + +;压缩的级次 +[compress] +value=2 + +;缓存key是否经过安全过滤 +[security] +value=true + +;缓存过期时间 +[expires] +value=20 \ No newline at end of file diff --git a/docs/configtemplate/ini/wind_config.ini b/docs/configtemplate/ini/wind_config.ini new file mode 100644 index 00000000..64c3d0f5 --- /dev/null +++ b/docs/configtemplate/ini/wind_config.ini @@ -0,0 +1,31 @@ +;应用配置 +[web-apps] +;default:为应用的name +default.class=windWebApp +default.root-path= +;配置default应用的路径规则 +;配置default应用的路由配置信息,module配置 +default.router.config.module.url-param=m +default.router.config.module.default-value=default +;controller配置 +default.router.config.controller.url-param=c +default.router.config.controller.default-value=index +;action配置 +default.router.config.action.url-param=a +default.router.config.action.default-value=run + +;配置default应用的模块 +;如下,配置了一个名为default的模块,及该default模块下该有的一些配置项信息 +;default模块的路径信息 +default.modules.default.path=controller +;default模块的error controller类 +default.modules.default.error-handler.class=WIND:core.web.WindErrorHandler +;default模块的controller后缀信息 +default.modules.default.controller-suffix.value=Controller +;default模块的视图配置 +;模板文件路径 +default.modules.default.view.config.template-dir.value=template +;模板后缀 +default.modules.default.view.config.template-ext.value=htm +;模板编译文件保存路径 +default.modules.default.view.config.compile-dir.value=compile.template \ No newline at end of file diff --git a/docs/configtemplate/memcache_config.xml b/docs/configtemplate/memcache_config.xml new file mode 100644 index 00000000..388f0c85 --- /dev/null +++ b/docs/configtemplate/memcache_config.xml @@ -0,0 +1,21 @@ + + + + + + + 127.0.0.1 + 11211 + + + 127.0.0.1 + 11212 + + + + + + + + + diff --git a/docs/configtemplate/php/compiler_config.php b/docs/configtemplate/php/compiler_config.php new file mode 100644 index 00000000..414c8a35 --- /dev/null +++ b/docs/configtemplate/php/compiler_config.php @@ -0,0 +1,23 @@ + 2011-3-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 配置模板自定义标签 + */ +return array( + /*配置标签*/ + 'support-tags' => array( + /** 标签名称 + 'tag1' => array( + 'tag' => '', //标签 + 'pattern' => '', //匹配表达式 + 'compiler' => '', //解析类文件 + ) + */ + ), +); diff --git a/docs/configtemplate/php/db_config.php b/docs/configtemplate/php/db_config.php new file mode 100644 index 00000000..df364c20 --- /dev/null +++ b/docs/configtemplate/php/db_config.php @@ -0,0 +1,23 @@ + 2011-3-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * dbConfig的配置 + * 可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 + */ +return array( + 'myConnection' => array( + 'driver' => 'mysql', + 'host' => 'localhost', + 'type' => 'master', + 'user' => 'root', + 'password' => '', + 'port' => '3306', + 'name' => 'phpwind', + 'charset' => 'utf8', + ), +); \ No newline at end of file diff --git a/docs/configtemplate/php/dbcache_config.php b/docs/configtemplate/php/dbcache_config.php new file mode 100644 index 00000000..11f42238 --- /dev/null +++ b/docs/configtemplate/php/dbcache_config.php @@ -0,0 +1,25 @@ + 2011-3-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 数据库缓存的配置信息 + */ + return array( + /*配置数据缓存表*/ + 'cache-table' => array( + 'table-name' => array('value' => 'pw_cache'), + 'field-key' => array('value' => 'name'), + 'field-value' => array('value' => 'cache'), + 'field-expire' => array('value' => 'time'), + 'expirestrage' => array('value' => 'true'), + ), + /*缓存key是否经过安全处理*/ + 'security' => array('value' => 'true'), + /*缓存过期时间*/ + 'expires' => array('value' => '20'), + ); \ No newline at end of file diff --git a/docs/configtemplate/php/filecache_config.php b/docs/configtemplate/php/filecache_config.php new file mode 100644 index 00000000..1afeae2d --- /dev/null +++ b/docs/configtemplate/php/filecache_config.php @@ -0,0 +1,23 @@ + 2011-3-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 文件缓存的配置 + */ +return array( + /*缓存文件的保存路径(支持命名空间的方式配置该路径)*/ + 'cache-dir' => array('value' => 'WEB:compile'), + /*缓存的级别*/ + 'cache-level' => array('value' => '0'), + /*缓存文件的后缀*/ + 'cache-suffix' => array('value' => 'php'), + /*缓存文件的key值是否经过安全处理*/ + 'security' => array('value' => 'true'), + /*缓存文件的过期时间*/ + 'expires' => array('value' => '20'), +); \ No newline at end of file diff --git a/docs/configtemplate/php/memcache.php b/docs/configtemplate/php/memcache.php new file mode 100644 index 00000000..9828ef04 --- /dev/null +++ b/docs/configtemplate/php/memcache.php @@ -0,0 +1,23 @@ + 2011-3-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * memcache配置 + */ +return array( + /*memcache服务器相关配置 可以配置多个*/ + 'servers' => array( + 'phpwind' => array('host' => '127.0.0.1', 'port' => '11211'), + 'cac' => array('host' => '127.0.0.1', 'port' => '11212') + ), + /*压缩的级次*/ + 'compress' => array('value' => '2'), + /*缓存key是否经过安全过滤*/ + 'security' => array('value' => 'true'), + /*缓存过期时间*/ + 'expires' => array('value' => '20')); \ No newline at end of file diff --git a/docs/configtemplate/php/wind_config.php b/docs/configtemplate/php/wind_config.php new file mode 100644 index 00000000..06833ba5 --- /dev/null +++ b/docs/configtemplate/php/wind_config.php @@ -0,0 +1,69 @@ + 2011-3-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +return array( + 'web-apps' => array( + /*配置应用项名为default*/ + 'default' => array( + 'class' => 'windWebApp', + 'root-path' => '', + /*配置default应用的路由规则*/ + 'router' => array( + 'config' => array( + /*配置路径中module的规则*/ + 'module' => array( + 'url-param' => 'm', + 'default-value' => 'default', + ), + /*配置路径中controller的规则*/ + 'controller' => array( + 'url-param' => 'c', + 'default-value' => 'index', + ), + /*配置路径中action的规则*/ + 'action' => array( + 'url-param' => 'a', + 'default-value' => 'run', + ), + ), + ), + /*配置default应用的模块配置*/ + 'modules' => array( + /*配置default模块*/ + 'default' => array( + /*default模块的路径*/ + 'path' => 'controller', + /*default模块的中controller的后缀*/ + 'controller-suffix' => array( + 'value' => 'controller', + ), + /*default模块中处理error的Action controller路径*/ + 'error-handler' => array( + 'class' => 'WIND:core.web.WindErrorHandler', + ), + /*default模块的试图配置*/ + 'view' => array( + 'config' => array( + /*模板路径*/ + 'template-dir' => array( + 'value' => 'template', + ), + /*模板后缀*/ + 'template-ext' => array( + 'value' => 'htm', + ), + /*模板编译路径*/ + 'compile-dir' => array( + 'value' => 'compile.template', + ), + ), + ), + ), + ), + ), + ), +); \ No newline at end of file diff --git a/docs/configtemplate/properties/db_config.properties b/docs/configtemplate/properties/db_config.properties new file mode 100644 index 00000000..f983f053 --- /dev/null +++ b/docs/configtemplate/properties/db_config.properties @@ -0,0 +1,10 @@ +#dbconfig的配置 +#可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 +myConnection.driver=mysql +myConnection.type=master +myConnection.host=localhost +myConnection.user=root +myConnection.password= +myConnection.port=3306 +myConnection.name=phpwind +myConnection.charset=utf8 diff --git a/docs/configtemplate/properties/dbcache_config.properties b/docs/configtemplate/properties/dbcache_config.properties new file mode 100644 index 00000000..b4e194fa --- /dev/null +++ b/docs/configtemplate/properties/dbcache_config.properties @@ -0,0 +1,17 @@ +#数据库缓存的配置信息 + +#配置数据缓存表 +[cache-table] +table-name.value=pw_cache +field-key.value=name +field-value.value=cache +field-expire.value=time +expirestrage.value=true + +#缓存key是否经过安全处理 +[security] +value=true + +#缓存过期时间 +[expires] +value=20 \ No newline at end of file diff --git a/docs/configtemplate/properties/filecache_config.properties b/docs/configtemplate/properties/filecache_config.properties new file mode 100644 index 00000000..da3399fe --- /dev/null +++ b/docs/configtemplate/properties/filecache_config.properties @@ -0,0 +1,12 @@ +#文件缓存配置 + +#缓存文件的保存路径(支持命名空间的方式配置该路径) +cache-dir.value=WEB:compile +#缓存的级别 +cache-level.value=0 +#缓存文件的后缀 +cache-suffix.value=php +#缓存文件的key值是否经过安全处理 +security.value=true +#缓存文件的过期时间 +expires.value=20 \ No newline at end of file diff --git a/docs/configtemplate/properties/memcache.properties b/docs/configtemplate/properties/memcache.properties new file mode 100644 index 00000000..cd5949fd --- /dev/null +++ b/docs/configtemplate/properties/memcache.properties @@ -0,0 +1,21 @@ +#memcache配置 + +#memcache服务器相关配置 可以配置多个 +[servers] +phpwind.host=127.0.0.1 +phpwind.port=11211 + +cac.host=127.0.0.1 +cac.port=11212 + +#压缩的级次 +[compress] +value=2 + +#缓存key是否经过安全过滤 +[security] +value=true + +#缓存过期时间 +[expires] +value=20 \ No newline at end of file diff --git a/docs/configtemplate/properties/viewTemplateConfig.properties b/docs/configtemplate/properties/viewTemplateConfig.properties new file mode 100644 index 00000000..79b1562a --- /dev/null +++ b/docs/configtemplate/properties/viewTemplateConfig.properties @@ -0,0 +1,9 @@ +#配置自定义模板标签 +#[support-tags] +#标签tag1的配置 +#标签 +#tag1.tag= +#标签匹配表达式 +#tag1.pattern= +#标签编译的类文件 +#tag1.compiler= diff --git a/docs/configtemplate/properties/wind_config.properties b/docs/configtemplate/properties/wind_config.properties new file mode 100644 index 00000000..10c7433c --- /dev/null +++ b/docs/configtemplate/properties/wind_config.properties @@ -0,0 +1,31 @@ +#应用配置 +[web-apps] +#default:为应用的name +default.class=windWebApp +default.root-path= +#配置default应用的路径规则 +#配置default应用的路由配置信息,module配置 +default.router.config.module.url-param=m +default.router.config.module.default-value=default +#controller配置 +default.router.config.controller.url-param=c +default.router.config.controller.default-value=index +#action配置 +default.router.config.action.url-param=a +default.router.config.action.default-value=run + +#配置default应用的模块 +#如下,配置了一个名为default的模块,及该default模块下该有的一些配置项信息 +#default模块的路径信息 +default.modules.default.path=controller +#default模块的error controller类 +default.modules.default.error-handler.class=WIND:core.web.WindErrorHandler +#default模块的controller后缀信息 +default.modules.default.controller-suffix.value=Controller +#default模块的视图配置 +#模板文件路径 +default.modules.default.view.config.template-dir.value=template +#模板后缀 +default.modules.default.view.config.template-ext.value=htm +#模板编译文件保存路径 +default.modules.default.view.config.compile-dir.value=compile.template \ No newline at end of file diff --git a/docs/configtemplate/wind_config.xml b/docs/configtemplate/wind_config.xml new file mode 100644 index 00000000..d43dc009 --- /dev/null +++ b/docs/configtemplate/wind_config.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wind/Wind.php b/wind/Wind.php new file mode 100644 index 00000000..2cd52df5 --- /dev/null +++ b/wind/Wind.php @@ -0,0 +1,10 @@ + + * @author Qiong Wu + * @version $Id$ + * @copyright Copyright © 2003-2015 phpwind.com + */ +class Wind extends WindBase {} +Wind::init(); diff --git a/wind/WindBase.php b/wind/WindBase.php new file mode 100644 index 00000000..d7abccea --- /dev/null +++ b/wind/WindBase.php @@ -0,0 +1,430 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindBase { + private static $_namespace = array(); + private static $_imports = array(); + private static $_classes = array(); + private static $_instances = array(); + private static $_extensions = 'php'; + private static $_includePaths = array(); + private static $_isAutoLoad = true; + private static $_logger = null; + + /** + * 加载应用 + * @param string $appName + * @param string $config + * @throws WindException + * @return + */ + public static function run($appName = '', $config = '') { + $frontController = new WindFrontController($appName, $config); + $frontController->run(); + } + + /** + * 加载一个类或者加载一个包 + * 如果加载的包中有子文件夹不进行循环加载 + * 参数格式说明:'WIND:core.base.WFrontController' + * WIND 注册的应用名称,应用名称与路径信息用‘:’号分隔 + * core.base.WFrontController 相对的路径信息 + * 如果不填写应用名称 ,例如‘core.base.WFrontController’,那么加载路径则相对于默认的应用路径 + * + * 加载一个类的参数方式:'WIND:core.base.WFrontController' + * 加载一个包的参数方式:'WIND:core.base.*' + * + * @param string $filePath | 文件路径信息 或者className + * @param boolean $autoIncludes | 是否采用自动加载方式 + * @param boolean $recursivePackage | 当需要加载的路径为文件夹时是否递归它 + * @return string|null + */ + public static function import($filePath, $recursivePackage = false) { + if (!$filePath) return false; + if ($className = self::_isImported($filePath)) return $className; + if (($pos = strrpos($filePath, '.')) !== false) + $fileName = substr($filePath, $pos + 1); + elseif (($pos1 = strrpos($filePath, ':')) !== false) + $fileName = substr($filePath, $pos1 + 1); + else + $fileName = $filePath; + $isPackage = $fileName === '*'; + if ($isPackage) { + $filePath = substr($filePath, 0, $pos); + $dirPath = self::getRealPath($filePath, true); + if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); + while (($file = readdir($dh)) !== false) { + if (is_dir($dirPath . D_S . $file)) { + if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { + $_filePath = $filePath . '.' . $file . '.' . '*'; + self::import($_filePath, $recursivePackage); + } + } else { + if (($pos = strrpos($file, '.')) === false) { + $fileName = $file; + } else { + if (substr($file, $pos + 1) === self::$_extensions) { + $fileName = substr($file, 0, $pos); + } + } + self::_setImport($fileName, $filePath . '.' . $fileName); + } + } + closedir($dh); + } else { + self::_setImport($fileName, $filePath); + } + return $fileName; + } + + /** + * 将路径信息注册到命名空间,该方法不会覆盖已经定义过的命名空间 + * @param string $path | 需要注册的路径 + * @param string $name | 路径别名 + * @param boolean $includePath | 是否同时定义includePath + * @param boolean $reset | 是否覆盖已经存在的定义,默认false + * @return + */ + public static function register($path, $alias = '', $includePath = false, $reset = false) { + if (!$path) return; + $alias = strtolower(trim($alias)); + if (!empty($alias)) { + if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = $path; + } + if ($includePath) { + if (empty(self::$_includePaths)) { + self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); + if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset(self::$_includePaths[$pos]); + } + array_unshift(self::$_includePaths, $path); + if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { + throw new Exception('set include path error.'); + } + } + } + + /** + * 类文件自动加载方法 callback + * @param string $className + * @param string $path + * @return null + */ + public static function autoLoad($className, $path = '') { + if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; + if ($path === '') { + throw new Exception('auto load ' . $className . ' failed.'); + } + $path = self::getRealPath($path . '.' . self::$_extensions); + if ((include $path) === false) { + throw new Exception('include file ' . $path . ' failed.'); + } + } + + /** + * @param string $key + * @return string|array + */ + public static function getImports($key = '') { + return $key ? self::$_imports[$key] : self::$_imports; + } + + /** + * 返回命名空间的路径信息 + * @param string $namespace + * @return string|Ambigous + */ + public static function getRootPath($namespace = '') { + if (!$namespace) return ''; + $namespace = strtolower($namespace); + return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; + } + + /** + * 解析路径信息,并返回路径的详情 + * @param string $filePath 路径信息 + * @param boolean $info 是否为目录路径 + * @return string|array('isPackage','fileName','extension','realPath') + */ + public static function getRealPath($filePath, $isDir = false) { + $filePath = trim($filePath, ' '); + $namespace = $suffix = ''; + if (!$isDir) { + $_pos1 = strrpos($filePath, '.'); + $suffix = trim(substr($filePath, $_pos1 + 1), '.'); + $filePath = substr($filePath, 0, $_pos1); + } + if (($pos = strpos($filePath, ':')) !== false) { + $namespace = self::getRootPath(substr($filePath, 0, $pos)); + } + $filePath = str_replace('.', D_S, $filePath); + if ($namespace) $filePath = rtrim($namespace, D_S) . D_S . substr($filePath, $pos + 1); + return $suffix ? $filePath . '.' . $suffix : $filePath; + } + + /** + * 将核心库文件打包 + * @throws Exception + * @return + */ + public static function perLoadCoreLibrary($libPath) { + self::import('COM:utility.WindPack'); + $pack = new WindPack(); + $fileList = array(); + foreach (self::$_imports as $key => $value) { + $_key = self::getRealPath($key . '.' . self::$_extensions); + $fileList[$_key] = array( + $key, + $value); + } + $pack->packFromFileList($fileList, $libPath, WindPack::STRIP_PHP, true); + } + + /** + * 初始化框架 + */ + public static function init() { + self::_checkEnvironment(); + self::_setDefaultSystemNamespace(); + self::_registerAutoloader(); + self::_loadBaseLib(); + } + + /** + * @param string $message + * @param int $level + */ + public static function log($message, $level = WindLogger::LEVEL_INFO, $type = 'wind.core') { + if (IS_DEBUG && $level >= IS_DEBUG && $level != WindLogger::LEVEL_PROFILE) { + self::getLogger()->log($message, $level, $type); + } + } + + /** + * @param $token + * @param $message + * @param $type + */ + public static function profileBegin($token, $message = '', $type = 'wind.core') { + if (IS_DEBUG && IS_DEBUG >= WindLogger::LEVEL_PROFILE) { + $msg = $token . ':' . $message; + self::getLogger()->profileBegin($msg, $type); + } + } + + /** + * @param $token + * @param $message + * @param $type + */ + public static function profileEnd($token, $message = '', $type = 'wend.core') { + if (IS_DEBUG && IS_DEBUG >= WindLogger::LEVEL_PROFILE) { + $msg = $token . ':' . $message; + self::getLogger()->profileEnd($msg, $type); + } + } + + /** + * 返回系统日志对象 + * @return WindLogger + */ + public static function getLogger() { + if (self::$_logger === null) { + self::$_logger = new WindLogger(); + self::$_logger->setLogFile(COMPILE_PATH . 'log/log.txt'); + } + return self::$_logger; + } + + /** + * 系统命名空间注册方法 + * @return + */ + private static function _setDefaultSystemNamespace() { + self::register(WIND_PATH, 'WIND'); + self::register(WIND_PATH . 'component' . D_S, 'COM'); + } + + /** + * 检查框架运行环境 + * @return + */ + private static function _checkEnvironment() { + if (!self::_checkPhpVersion()) throw new Exception('php version is too old, php ' . PHPVERSION . ' or later.', E_WARNING); + if (!defined('COMPILE_PATH')) throw new Exception('compile path undefined.'); + function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); + } + + /** + * @param string $className + * @param string $classPath + * @return + */ + private static function _setImport($className, $classPath) { + if (self::_isImported($className)) return; + self::$_imports[$classPath] = $className; + if (self::$_isAutoLoad) + self::$_classes[$className] = $classPath; + else + self::autoLoad($className, $classPath); + } + + /** + * 判断是否类是否已经被加载,如果已经被加载则返回路径信息,如果没有被加载则返回false + * @param string $path + * @return boolean|string + */ + private static function _isImported($param) { + if (isset(self::$_imports[$param])) return self::$_imports[$param]; + if (in_array($param, self::$_imports)) return $param; + return false; + } + + /** + * 注册自动加载回调方法 + * @return + */ + private static function _registerAutoloader() { + if (!self::$_isAutoLoad) return; + if (function_exists('spl_autoload_register')) + spl_autoload_register('Wind::autoLoad'); + else + self::$_isAutoLoad = false; + } + + /** + * 加载核心层库函数 + * @return + */ + private static function _loadBaseLib() { + $_core = self::_coreLib(); + foreach ($_core as $key => $value) { + self::_setImport($key, $value); + } + } + + /* private utility */ + private static function _checkPhpVersion() { + $v1 = $v2 = $v3 = $m1 = $m2 = $m3 = 0; + $phpversion = phpversion(); + sscanf($phpversion, "%d.%d.%d", $v1, $v2, $v3); + sscanf(PHPVERSION, "%d.%d.%d", $m1, $m2, $m3); + if ($v1 > $m1) return true; + if ($v1 < $m1) return false; + if ($v2 > $m2) return true; + if ($v2 < $m2) return false; + if ($v3 > $m3) return true; + if ($v3 < $m3) return false; + return true; + } + + /** + * 核心库文件 + * @return + */ + private static function _coreLib() { + return array( + 'AbstractWindServer' => 'WIND:core.AbstractWindServer', + 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', + 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', + 'WindConfig' => 'WIND:core.config.WindConfig', + 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', + 'WindDaoCacheListener' => 'WIND:core.dao.listener.WindDaoCacheListener', + 'WindActionException' => 'WIND:core.exception.WindActionException', + 'WindCacheException' => 'WIND:core.exception.WindCacheException', + 'WindDaoException' => 'WIND:core.exception.WindDaoException', + 'WindException' => 'WIND:core.exception.WindException', + 'WindFinalException' => 'WIND:core.exception.WindFinalException', + 'WindSqlException' => 'WIND:core.exception.WindSqlException', + 'WindViewException' => 'WIND:core.exception.WindViewException', + 'IWindFactory' => 'WIND:core.factory.IWindFactory', + 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', + 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', + 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', + 'WindComponentDefinition' => 'WIND:core.factory.WindComponentDefinition', + 'WindComponentFactory' => 'WIND:core.factory.WindComponentFactory', + 'WindFactory' => 'WIND:core.factory.WindFactory', + 'WindFilter' => 'WIND:core.filter.WindFilter', + 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', + 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', + 'IWindRequest' => 'WIND:core.request.IWindRequest', + 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', + 'IWindResponse' => 'WIND:core.response.IWindResponse', + 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', + 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', + 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', + 'AbstractWindTemplateCompiler' => 'WIND:core.viewer.AbstractWindTemplateCompiler', + 'AbstractWindViewTemplate' => 'WIND:core.viewer.AbstractWindViewTemplate', + 'WindTemplateCompilerAction' => 'WIND:core.viewer.compiler.WindTemplateCompilerAction', + 'WindTemplateCompilerComponent' => 'WIND:core.viewer.compiler.WindTemplateCompilerComponent', + 'WindTemplateCompilerEcho' => 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', + 'WindTemplateCompilerInternal' => 'WIND:core.viewer.compiler.WindTemplateCompilerInternal', + 'WindTemplateCompilerPage' => 'WIND:core.viewer.compiler.WindTemplateCompilerPage', + 'WindTemplateCompilerScript' => 'WIND:core.viewer.compiler.WindTemplateCompilerScript', + 'WindTemplateCompilerTemplate' => 'WIND:core.viewer.compiler.WindTemplateCompilerTemplate', + 'WindViewTemplate' => 'WIND:core.viewer.compiler.WindViewTemplate', + 'IWindViewerResolver' => 'WIND:core.viewer.IWindViewerResolver', + 'WindViewCacheListener' => 'WIND:core.viewer.listener.WindViewCacheListener', + 'WindLayout' => 'WIND:core.viewer.WindLayout', + 'WindView' => 'WIND:core.viewer.WindView', + 'WindViewerResolver' => 'WIND:core.viewer.WindViewerResolver', + 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', + 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', + 'IWindApplication' => 'WIND:core.web.IWindApplication', + 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', + 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', + 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', + 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', + 'WindAction' => 'WIND:core.web.WindAction', + 'WindController' => 'WIND:core.web.WindController', + 'WindDispatcher' => 'WIND:core.web.WindDispatcher', + 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', + 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', + 'WindFormController' => 'WIND:core.web.WindFormController', + 'WindForward' => 'WIND:core.web.WindForward', + 'WindFrontController' => 'WIND:core.web.WindFrontController', + 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', + 'WindWebApplication' => 'WIND:core.web.WindWebApplication', + 'WindComponentModule' => 'WIND:core.WindComponentModule', + 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', + 'WindHelper' => 'WIND:core.WindHelper', + 'WindModule' => 'WIND:core.WindModule', + 'WindLogger' => 'COM:log.WindLogger'); + } +} +/* 组件定义 */ +!defined('COMPONENT_WEBAPP') && define('COMPONENT_WEBAPP', 'windWebApp'); +!defined('COMPONENT_ERRORHANDLER') && define('COMPONENT_ERRORHANDLER', 'errorHandler'); +!defined('COMPONENT_LOGGER') && define('COMPONENT_LOGGER', 'windLogger'); +!defined('COMPONENT_FORWARD') && define('COMPONENT_FORWARD', 'forward'); +!defined('COMPONENT_ROUTER') && define('COMPONENT_ROUTER', 'urlBasedRouter'); +!defined('COMPONENT_URLHELPER') && define('COMPONENT_URLHELPER', 'urlHelper'); +!defined('COMPONENT_VIEW') && define('COMPONENT_VIEW', 'windView'); +!defined('COMPONENT_VIEWRESOLVER') && define('COMPONENT_VIEWRESOLVER', 'viewResolver'); +!defined('COMPONENT_TEMPLATE') && define('COMPONENT_TEMPLATE', 'template'); +!defined('COMPONENT_ERRORMESSAGE') && define('COMPONENT_ERRORMESSAGE', 'errorMessage'); +!defined('COMPONENT_DB') && define('COMPONENT_DB', 'db'); +//TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 +//********************约定变量*********************************** +define('WIND_M_ERROR', 'windError'); +define('WIND_CONFIG_CACHE', 'wind_components_config'); +//**********配置*******通用常量定义*************************************** +define('WIND_CONFIG_CONFIG', 'config'); +define('WIND_CONFIG_CLASS', 'class'); +define('WIND_CONFIG_CLASSPATH', 'path'); +define('WIND_CONFIG_RESOURCE', 'resource'); +define('WIND_CONFIG_VALUE', 'value'); \ No newline at end of file diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php new file mode 100644 index 00000000..eb5cf5e2 --- /dev/null +++ b/wind/component/cache/AbstractWindCache.php @@ -0,0 +1,237 @@ + + * @author Su Qian + * @version $Id$ + * @package + */ +abstract class AbstractWindCache extends WindComponentModule { + + /** + * key的安全码 + * @var string + */ + private $securityCode = ''; + + /** + * 缓存前缀 + * @var sting + */ + private $keyPrefix = ''; + + /** + * 缓存过期时间 + * @var int + */ + private $expire = ''; + + /** + * 缓存依赖的类名称 + * @var string + */ + const DEPENDENCYCLASS = 'dependencyclass'; + + /** + * 标志存储时间 + * @var string + */ + const STORETIME = 'store'; + + /** + * 标志存储数据 + * @var string + */ + const DATA = 'data'; + + /** + * 配置文件中标志过期时间名称定义(也包含缓存元数据中过期时间 的定义) + * @var string + */ + const EXPIRE = 'expires'; + + /** + * 配置文件中标志缓存依赖名称的定义 + * @var string + */ + const DEPENDENCY = 'dependency'; + + /** + * 配置文件中缓存安全码名称的定义 + * @var string + */ + const SECURITY = 'security'; + + /** + * 配置文件中缓存键的前缀名称的定义 + * @var string + */ + const KEYPREFIX = 'prefix'; + + /** + * 设置缓存,如果key不存在,设置缓存,否则,替换已有key的缓存。 + * @param string $key 保存缓存数据的键。 + * @param string $value 保存缓存数据。 + * @param int $expires 缓存数据的过期时间,0表示永不过期 + * @param IWindCacheDependency $denpendency 缓存依赖 + * @return boolean + */ + public abstract function set($key, $value, $expires = 0, IWindCacheDependency $denpendency = null); + + /** + * 获取指定缓存 + * @param string $key 获取缓存数据的标识,即键 + * @return mixed + */ + public abstract function get($key); + + /** + * 通过key批量获取缓存数据 + * @param array $keys + * @return array + */ + public function batchGet(array $keys) { + $data = array(); + foreach ($keys as $key) { + $data[$key] = $this->get($key); + } + return $data; + } + + /** + * 删除缓存数据 + * @param string $key 获取缓存数据的标识,即键 + * @return string + */ + public abstract function delete($key); + + /** + * 通过key批量删除缓存数据 + * @param array $keys + * @return boolean + */ + public function batchDelete(array $keys) { + foreach ($keys as $key) { + $this->delete($key); + } + return true; + } + + /** + * 清空所有缓存 + */ + public abstract function clear(); + + /** + * 如果缓存中有数据,则检查缓存依赖是否已经变更,如果变更则删除缓存 + * @param string $key 键 + * @param array $data 缓存中的数据 + * @return boolean true表示缓存依赖已变更,false表示缓存依赖未变改 + */ + protected function checkDependencyChanged($key, array $data) { + if (isset($data[self::DEPENDENCY]) && isset($data[self::DEPENDENCYCLASS])) { + Wind::import('Wind:component.cache.dependency.' . $data[self::DEPENDENCYCLASS]); + /* @var $dependency IWindCacheDependency*/ + $dependency = unserialize($data[self::DEPENDENCY]); + if (($dependency instanceof IWindCacheDependency) && $dependency->hasChanged()) { + $this->delete($key); + return true; + } + } + return false; + } + + /** + * 从缓存元数据中取得真实的数据 + * @param string $key + * @param mixed $data + * @return mixed + */ + protected function getDataFromMeta($key, $data) { + if (is_array($data)) { + if ($this->checkDependencyChanged($key, $data)) { + return null; + } + return isset($data[self::DATA]) ? $data[self::DATA] : null; + } + return $data; + } + + /** + * 获取存储的数据 + * @param string $value + * @param string $expires + * @param IWindCacheDependency $denpendency + * @return string + */ + protected function storeData($value, $expires = null, $denpendency = null) { + $data = array( + self::DATA => $value, + self::EXPIRE => $expires, + self::STORETIME => time()); + if ($denpendency && (($denpendency instanceof IWindCacheDependency))) { + $denpendency->injectDependent($this); + $data[self::DEPENDENCY] = serialize($denpendency); + $data[self::DEPENDENCYCLASS] = get_class($denpendency); + } + return serialize($data); + } + + /** + * 生成安全的key + * @param string $key + * @return string + */ + protected function buildSecurityKey($key) { + return $this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key : $key; + } + + /** + * @return the $securityCode + */ + protected function getSecurityCode() { + return $this->getConfig(self::SECURITY, WIND_CONFIG_VALUE, '', $this->securityCode); + } + + /** + * 返回缓存Key值前缀,默认值为null无任何前缀添加 + * @return the $prefix + */ + protected function getKeyPrefix() { + return $this->keyPrefix; + } + + /** + * 返回过期时间设置,默认值为0永不过期 + * @return the $expire + */ + public function getExpire() { + if ('' === $this->expire) { + $this->expire = $this->getConfig(self::EXPIRE, WIND_CONFIG_VALUE, '', '0'); + } + return $this->expire; + } + + /** + * @param string $securityCode + */ + public function setSecurityCode($securityCode) { + $this->securityCode = $securityCode; + } + + /** + * @param sting $keyPrefix + */ + public function setKeyPrefix($keyPrefix) { + $this->keyPrefix = $keyPrefix; + } + + /** + * @param int $expire + */ + public function setExpire($expire) { + $this->expire = $expire; + } + +} \ No newline at end of file diff --git a/wind/component/cache/IWindCacheDependency.php b/wind/component/cache/IWindCacheDependency.php new file mode 100644 index 00000000..d0776536 --- /dev/null +++ b/wind/component/cache/IWindCacheDependency.php @@ -0,0 +1,43 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 缓存依赖 + * 在依赖对象和被依赖对象对象之间建立一种有效的关联,当被依赖对象发生改变时,依赖对象就在缓存中被清楚 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +interface IWindCacheDependency { + + /** + * 注入依赖 + * @param IWindCache $cache + */ + public function injectDependent(IWindCache $cache); + + /** + * CacheDependency 对象是否已更改 + * @return boolean + */ + public function hasChanged(); + + /** + * 获取依赖项的上次更改时间 + * @return string + */ + public function getLastModified(); + + /** + * 标记依赖项的上次更改时间。 + */ + public function setLastModified(); +} \ No newline at end of file diff --git a/wind/component/cache/dependency/WindCacheDependency.php b/wind/component/cache/dependency/WindCacheDependency.php new file mode 100644 index 00000000..5bf4ad77 --- /dev/null +++ b/wind/component/cache/dependency/WindCacheDependency.php @@ -0,0 +1,88 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.cache.IWindCacheDependency'); +/** + * 缓存依赖基类 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindCacheDependency implements IWindCacheDependency{ + /** + * @var mixed 缓存依赖控制者 + */ + protected $dependent = null; + /** + * @var string 依赖项的上次更改时间 + */ + protected $lastModified; + /** + * @var IWindCache 缓存创建者 + */ + protected $cache = null; + + public function __construct(){ + + } + + /** + * @see wind/component/cache/base/IWindCacheDependency#injectDependent() + */ + public function injectDependent(IWindCache $cache){ + $this->cache = $cache; + $this->setLastModified(); + $this->dependent = $this->notifyDependencyChanged(); + } + + /** + * @see wind/component/cache/base/IWindCacheDependency#hasChanged() + */ + public function hasChanged(){ + return $this->getDependent() != $this->notifyDependencyChanged(); + } + /** + * @see wind/component/cache/base/IWindCacheDependency#getLastModified() + */ + public function getLastModified(){ + return $this->lastModified; + } + + + /** + * @see wind/component/cache/base/IWindCacheDependency#setLastModified() + */ + public function setLastModified(){ + $this->lastModified = time(); + } + + /** + * 获取缓存依赖控制者 + * @return mixed + */ + public function getDependent(){ + return $this->dependent; + } + + /** + * 取得创建缓存依赖的创造者. + * @return IWindCache + */ + public function getCache(){ + return $this->cache; + } + + /* + * 通知依赖项已更改。 + */ + protected function notifyDependencyChanged(){ + return null; + } + +} \ No newline at end of file diff --git a/wind/component/cache/dependency/WindSqlCacheDependency.php b/wind/component/cache/dependency/WindSqlCacheDependency.php new file mode 100644 index 00000000..6593916a --- /dev/null +++ b/wind/component/cache/dependency/WindSqlCacheDependency.php @@ -0,0 +1,19 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.cache.dependency.WindCacheDependency'); +/** + * 监视特定的数据库表,以便在该表发生更改时,自动从 Cache 中删除与该表关联的项。数据库表发生更改时,将自动删除缓存项 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSqlCacheDependency extends WindCacheDependency{ + +} \ No newline at end of file diff --git a/wind/component/cache/operator/WindApc.php b/wind/component/cache/operator/WindApc.php new file mode 100644 index 00000000..b164fa39 --- /dev/null +++ b/wind/component/cache/operator/WindApc.php @@ -0,0 +1,65 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + * tags + */ +class WindApc { + + public function __construct() { + if (!function_exists('apc_store')) { + throw new WindException('The apc extension must be loaded !'); + } + } + + /** + * 添加缓存 + * @param string $key 缓存键 + * @param mixed $value 缓存键对应的值 + * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 + */ + public function add($key, $value, $ttl = 0){ + return apc_add($key, $value, $ttl); + } + /** + * 设置缓存,如果缓存存在,则覆写,否则添加 + * @param string $key 缓存键 + * @param mixed $value 缓存键对应的值 + * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 + */ + public function set($key, $value, $ttl = 0) { + return apc_store($key, $value, $ttl); + } + + /** + * 根据键移除缓存 + * @param string $key 缓存的键 + * @return mixed + */ + public function get($key) { + return apc_fetch($key); + } + /** + * 删除缓存 + * @param string $key + */ + public function delete($key) { + return apc_delete($key); + } + /** + * 清空所有缓存 + */ + public function flush() { + apc_clear_cache(); + return apc_clear_cache('user'); + } +} \ No newline at end of file diff --git a/wind/component/cache/operator/WindEaccelerator.php b/wind/component/cache/operator/WindEaccelerator.php new file mode 100644 index 00000000..24d1403b --- /dev/null +++ b/wind/component/cache/operator/WindEaccelerator.php @@ -0,0 +1,118 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindEaccelerator { + public function __construct() { + if (!function_exists('eaccelerator_get')) { + throw new WindException('The eaccelerator extension must be loaded !'); + } + } + /** + * @param string $key 缓存键 + * @param mixed $value 缓存键对应的值 + * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 + * @return boolean + */ + public function set($key, $value, $ttl = 0) { + return eaccelerator_put($key, $value, $ttl); + } + + /** + * 根据键移除缓存 + * @param string $key 缓存的键 + * @return mixed + */ + public function get($key) { + return eaccelerator_get($key); + } + + /** + * 删除缓存 + * @param string $key + */ + public function delete($key) { + return eaccelerator_rm($key); + } + + /** + * 为 键加上锁定操作,以保证多进程多线程操作时数据的同步。 + * @param string $key + */ + public function lock($key) { + return eaccelerator_lock($key); + } + + /** + * 来释放这个锁或等待程序请求结束时自动释放这个锁。 + * @param string $key + * @return + */ + public function unlock($key) { + return eaccelerator_unlock($key); + } + /** + * 将 $eval_code 代码的输出缓存 $ttl 秒 + * @param string $key + * @param string $eval_code + * @param int $ttl + */ + public function cacheOutput($key, $eval_code, $ttl = 0) { + return eaccelerator_cache_output($key, $eval_code, $ttl); + } + + /** + * 将 $eval_code 代码的执行结果缓存 $ttl 秒 + * @param string $key + * @param string $eval_code + * @param int $ttl + */ + public function cacheResult($key, $eval_code, $ttl = 0) { + return eaccelerator_cache_result($key, $eval_code, $ttl); + } + + /** + * 将当前整页缓存 $ttl 秒。 + * @param string $key + * @param int $ttl + */ + public function pageCache($key, $ttl = 0) { + return eaccelerator_cache_page($key, $ttl); + } + + /** + * 删除由 eaccelerator_cache_page() 执行的缓存, + * @param string $key + */ + public function deletePageCache($key) { + return eaccelerator_rm_page($key); + } + + /** + * 移除清理所有已过期的key + */ + public function clearExpiredCache() { + return eaccelerator_gc(); + } + + /** + * 清空所有缓存 + */ + public function flush() { + $this->clearExpiredCache(); + $cacheKeys = eaccelerator_list_keys(); + foreach ($cacheKeys as $key) { + $this->delete(substr($key['name'], 1)); + } + } +} \ No newline at end of file diff --git a/wind/component/cache/operator/WindMemcache.php b/wind/component/cache/operator/WindMemcache.php new file mode 100644 index 00000000..a7b73b71 --- /dev/null +++ b/wind/component/cache/operator/WindMemcache.php @@ -0,0 +1,141 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * WindMemcache操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindMemcache { + + const HOST = 'host'; + + const PORT = 'port'; + + const PCONNECT = 'pconn'; + + const WEIGHT = 'weight'; + + const TIMEOUT = 'timeout'; + + const RETRY = 'retry'; + + const STATUS = 'status'; + + const FCALLBACK = 'fcallback'; + + const COMPRESS = 'compress'; + + const SERVERCONFIG = 'servers'; + + /** + * @var Memcache + */ + private $memcache = null; + + public function __construct() { + if (!extension_loaded('Memcache')) { + throw new WindException('The memcache extension must be loaded !'); + } + $this->memcache = new Memcache(); + } + + /** + * 设置一个指定 key 的缓存变量内容 + * @param string $key 缓存数据的键, 其长度不能超过250个字符 + * @param mixed $value 值,整型将直接存储,其他类型将被序列化存储,其值最大为1M + * @param int $flag 是否使用 zlib 压缩 + * @param int $expire 过期时间,0 为永不过期,可使用 unix 时间戳格式或距离当前时间的秒数,设为秒数时不能大于 2592000(30 天) + */ + public function set($key, $value, $flag = 0, $expire = 0) { + return $this->memcache->set($key, $value, $flag, $expire); + } + + /** + * 获取某个或者一组 key 的变量缓存值 + * @param mixed $key + */ + public function get($key) { + return $this->memcache->get($key); + } + + /** + * 删除某一个或一组变量的缓存 + * @param string $key 存的键 键值不能为null和'’,当它等于前面两个值的时候php会有警告错误。 + * @param int $timeout 删除这项的时间,如果它等于0,这项将被立刻删除反之如果它等于30秒,那么这项被删除在30秒内 + */ + public function delete($key, $timeout = 0) { + return $this->memcache->delete($key, $timeout); + } + + /** + * 清空所有缓存内容,不是真的删除缓存的内容,只是使所有变量的缓存过期,使内存中的内容被重写 + */ + public function flush() { + $this->memcache->flush(); + } + + /** + * 取得缓存操作句柄 + * @return Memcache + */ + public function getMemcache() { + return $this->memcache; + } + + /** + * 批量添加memecache服务器 + * @param array $servers + */ + public function setServers(array $servers) { + foreach ($servers as $server) { + if (!is_array($server)) { + throw new WindException('The memcache config is incorrect'); + } + $this->setServer($server); + } + } + + /** + * 添加memached服务器 + * @example $server = array( + * array( + * 'host'=>'localhost', + * 'port'=>11211 + * 'pconn'=>true + * ), + * array( + * 'host'=>'localhost', + * 'port'=>11212 + * 'pconn'=>false + * ) + * @param array $server + */ + public function setServer(array $server) { + if (!isset($server[self::HOST])) { + throw new WindException('The memcache server ip address is not exist'); + } + if (!isset($server[self::PORT])) { + throw new WindException('The memcache server port is not exist'); + } + $defaultServer = array(self::HOST => '', self::PORT => '', self::PCONNECT => true, self::WEIGHT => 1, + self::TIMEOUT => 15, self::RETRY => 15, self::STATUS => true, self::FCALLBACK => null); + list($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback) = array_values(array_merge($defaultServer, $server)); + $this->memcache->addServer($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback); + } + + public function close() { + return $this->memcache->close(); + } + + public function __destruct() { + $this->close(); + } +} \ No newline at end of file diff --git a/wind/component/cache/operator/WindWinCache.php b/wind/component/cache/operator/WindWinCache.php new file mode 100644 index 00000000..e0cf5a53 --- /dev/null +++ b/wind/component/cache/operator/WindWinCache.php @@ -0,0 +1,88 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + * tags + */ +class WindWinCache{ + public function __construct() { + if (!function_exists('wincache_ucache_get')) { + throw new WindException('The wincache extension must be loaded !'); + } + } + + /** + * 添加缓存 + * @param string $key 缓存键 + * @param mixed $value 缓存键对应的值 + * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 + */ + public function add($key, $value, $ttl = 0){ + return wincache_ucache_add($key, $value, $ttl); + } + /** + * 设置缓存,如果缓存存在,则覆写,否则添加 + * @param string $key 缓存键 + * @param mixed $value 缓存键对应的值 + * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 + */ + public function set($key, $value, $ttl = 0) { + return wincache_ucache_set($key, $value, $ttl); + } + + /** + * 根据键移除缓存 + * @param string $key 缓存的键 + * @return mixed + */ + public function get($key) { + return wincache_ucache_get($key); + } + /** + * 删除缓存 + * @param string $key + */ + public function delete($key) { + return wincache_ucache_delete($key); + } + + /** + * 为 键加上锁定操作,以保证多进程多线程操作时数据的同步。 + * @param string $key + */ + public function lock($key) { + return wincache_lock($key); + } + + /** + * 来释放这个锁或等待程序请求结束时自动释放这个锁。 + * @param string $key + * @return + */ + public function unlock($key) { + return wincache_unlock($key); + } + + /** + * 判断一个某个键对应的缓存是否存在 + * @param string $key + */ + public function exist($key){ + return wincache_ucache_exists($key); + } + /** + * 清空所有缓存 + */ + public function flush() { + return wincache_ucache_clear(); + } +} diff --git a/wind/component/cache/operator/WindXCache.php b/wind/component/cache/operator/WindXCache.php new file mode 100644 index 00000000..5ccb1c97 --- /dev/null +++ b/wind/component/cache/operator/WindXCache.php @@ -0,0 +1,66 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + * tags + */ +class WindXCache { + + public function __construct() { + if (!function_exists('xcache_get')) { + throw new WindException('The xcache extension must be loaded !'); + } + } + + /** + * 设置缓存,如果缓存存在,则覆写,否则添加 + * @param string $key 缓存键 + * @param mixed $value 缓存键对应的值 + * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 + */ + public function set($key, $value, $ttl = 0) { + return xcache_set($key, $value, $ttl); + } + + /** + * 根据键移除缓存 + * @param string $key 缓存的键 + * @return mixed + */ + public function get($key) { + return xcache_get($key); + } + /** + * 删除缓存 + * @param string $key + */ + public function delete($key) { + return xcache_unset($key); + } + + /** + * 判断一个某个键对应的缓存是否存在 + * @param string $key + */ + public function exist($key) { + return xcache_isset($key); + } + /** + * 清空所有缓存 + */ + public function flush() { + for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) { + xcache_clear_cache(XC_TYPE_VAR, $i); + } + return true; + } +} diff --git a/wind/component/cache/operator/WindZendCache.php b/wind/component/cache/operator/WindZendCache.php new file mode 100644 index 00000000..c482a0de --- /dev/null +++ b/wind/component/cache/operator/WindZendCache.php @@ -0,0 +1,55 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindZendCache{ + + public function __construct() { + if (!function_exists('zend_shm_cache_fetch')) { + throw new WindException('The zend cache extension must be loaded !'); + } + } + + /** + * 设置缓存,如果缓存存在,则覆写,否则添加 + * @param string $key 缓存键 + * @param mixed $value 缓存键对应的值 + * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 + */ + public function set($key, $value, $ttl = 0) { + return zend_shm_cache_store($key, $value, $ttl); + } + + /** + * 根据键移除缓存 + * @param string $key 缓存的键 + * @return mixed + */ + public function get($key) { + return zend_shm_cache_fetch($key); + } + /** + * 删除缓存 + * @param string $key + */ + public function delete($key) { + return zend_shm_cache_delete($key); + } + + /** + * 清空所有缓存 + */ + public function flush() { + return zend_shm_cache_clear(); + } +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheApc.php b/wind/component/cache/strategy/WindCacheApc.php new file mode 100644 index 00000000..72ade731 --- /dev/null +++ b/wind/component/cache/strategy/WindCacheApc.php @@ -0,0 +1,55 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +Wind::import('WIND:component.cache.operator.WindApc'); +/** + * php加速器缓存 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindCacheApc extends AbstractWindCache { + + /** + * @var WindApc + */ + protected $apc = null; + + public function __construct(){ + $this->apc = new WindApc(); + } + /* + * @see AbstractWindCache#set() + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire;echo $expire; + return $this->apc->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); + } + + /* + * @see AbstractWindCache#get() + */ + public function get($key) { + return $this->getDataFromMeta($key, unserialize($this->apc->get($this->buildSecurityKey($key)))); + } + /* + * @see AbstractWindCache#delete() + */ + public function delete($key) { + return $this->apc->delete($this->buildSecurityKey($key)); + } + /** + * @see AbstractWindCache#clear() + */ + public function clear() { + return $this->apc->flush(); + } + +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheDb.php b/wind/component/cache/strategy/WindCacheDb.php new file mode 100644 index 00000000..bcbb78ee --- /dev/null +++ b/wind/component/cache/strategy/WindCacheDb.php @@ -0,0 +1,251 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindCacheDb extends AbstractWindCache { + + /** + * 分布式管理 + * @var AbstractWindDbAdapter + */ + protected $dbHandler; + + /** + * 缓存表 + * @var string + */ + protected $table = 'pw_cache'; + + /** + * 缓存表的键字段 + * @var string + */ + protected $keyField = 'key'; + + /** + * 缓存表的值字段 + * @var string + */ + protected $valueField = 'value'; + + /** + * 缓存表过期时间字段 + * @var string + */ + protected $expireField = 'expire'; + + /** + * 数据过期策略 + * @var boolean + */ + protected $expirestrage = true; + + const CACHETABLE = 'cache-table'; + + const TABLENAME = 'table-name'; + + const KEY = 'field-key'; + + const VALUE = 'field-value'; + + const EXPIRE = 'field-expire'; + + const STRAGE = 'expirestrage'; + + public function __construct(AbstractWindDbAdapter $dbHandler = null) { + $dbHandler && $this->setDbHandler($dbHandler); + } + + /* + * @see AbstractWindCache#set() + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire; + $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->expireField)->where($this->keyField . ' = :key ', array( + ':key' => $this->buildSecurityKey($key)))->select()->getRow(); + if ($data) { + return !$this->expirestrage && '0' === $data[$this->expireField] ? null : $this->update($key, $value, $expire, $denpendency); + } else { + return $this->store($key, $value, $expire, $denpendency); + } + return true; + } + + /* + * @see AbstractWindCache#get() + */ + public function get($key) { + if ($this->expirestrage) { + $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->valueField)->where($this->keyField . ' = :key ', array( + ':key' => $this->buildSecurityKey($key)))->select()->getRow(); + } else { + $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->valueField)->where($this->expireField . ' != 0 AND ' . $this->keyField . ' = :key ', array( + ':key' => $this->buildSecurityKey($key)))->select()->getRow(); + } + return $this->getDataFromMeta($key, unserialize($data[$this->valueField])); + } + + /* + * @see AbstractWindCache#batchFetch() + */ + public function batchGet(array $keys) { + foreach ($keys as $key => $value) { + $keys[$key] = $this->buildSecurityKey($value); + } + if (true === $this->expirestrage) { + $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->valueField, $this->keyField)->where($this->keyField . ' in ( :key ) ', array( + ':key' => $keys))->select()->getAllRow(); + } else { + $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->valueField, $this->keyField)->where($this->expireField . ' != 0 AND ' . $this->keyField . ' in ( :key ) ', array( + ':key' => $keys))->select()->getAllRow(); + } + $result = $changed = array(); + foreach ($data as $_data) { + $_data = unserialize($_data[$this->valueField]); + if (isset($_data[self::DEPENDENCY]) && $_data[self::DEPENDENCY] instanceof IWindCacheDependency) { + if ($_data[self::DEPENDENCY]->hasChanged()) { + $changed[] = $_data[$this->keyField]; + } else { + $result[$_data[$this->keyField]] = $_data[self::DATA]; + } + } + } + $changed && $this->batchDelete($changed); + return $result; + } + + /* + * @see AbstractWindCache#delete() + */ + public function delete($key) { + if ($this->expirestrage) { + $this->dbHandler->getSqlBuilder()->from($this->table)->where($this->keyField . ' = :key ', array( + ':key' => $this->buildSecurityKey($key)))->delete(); + } else { + $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->expireField . ' = 0')->where($this->keyField . ' = :key ', array( + ':key' => $this->buildSecurityKey($key)))->update(); + } + } + + /* + * @see AbstractWindCache#batchDelete() + */ + public function batchDelete(array $keys) { + foreach ($keys as $key => $value) { + $keys[$key] = $this->buildSecurityKey($value); + } + if ($this->expirestrage) { + $this->dbHandler->getSqlBuilder()->from($this->table)->where($this->keyField . ' in (:key) ', array( + ':key' => $keys))->delete(); + } else { + $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->expireField . ' = 0')->where($this->keyField . ' in (:key) ', array( + ':key' => $keys))->update(); + } + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + if ($this->expirestrage) { + return $this->dbHandler->getSqlBuilder()->from($this->table)->delete(); + } else { + return $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->expireField . ' = 0')->update(); + } + return false; + } + + /** + * 删除过期数据 + */ + public function deleteExpiredCache() { + if ($this->expirestrage) { + $this->dbHandler->getSqlBuilder()->from($this->table)->where($this->expireField . ' !=0 AND ' . $this->expireField . ' < :expires', array( + ':expires' => time()))->delete(); + } else { + $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->expireField . ' = 0')->where($this->expireField . ' < :expires', array( + ':expires' => time()))->update(); + } + } + + public function setDbHandler(AbstractWindDbAdapter $dbHandler) { + $this->dbHandler = $dbHandler; + } + + /* + * @see WindComponentModule#setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->expirestrage = 'true' === $this->getTableConfig(self::STRAGE,WIND_CONFIG_VALUE); + $this->table = $this->getTableConfig(self::TABLENAME,WIND_CONFIG_VALUE); + $this->keyField = $this->getTableConfig(self::KEY,WIND_CONFIG_VALUE); + $this->valueField = $this->getTableConfig(self::VALUE,WIND_CONFIG_VALUE); + $this->expireField = $this->getTableConfig(self::EXPIRE,WIND_CONFIG_VALUE);; + } + + /** + * @return mixed + */ + protected function getTableConfig($name = '', $subname = '') { + $tableConfig = $this->getConfig(self::CACHETABLE); + if (empty($name)) { + return $tableConfig; + } + if (empty($subname)) { + return isset($tableConfig[$name]) ? $tableConfig[$name] : $tableConfig; + } + return isset($tableConfig[$name][$subname]) ? $tableConfig[$name][$subname] : $tableConfig[$name]; + } + + /** + * 存储数据 + * @param string $key + * @param string $value + * @param int $expires + * @param IWindCacheDependency $denpendency + * @return boolean + */ + protected function store($key, $value, $expires = 0, IWindCacheDependency $denpendency = null) { + $data = addslashes($this->storeData($value, $expires, $denpendency)); + if ($expires) { + $expires += time(); + } + return $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->keyField, $this->valueField, $this->expireField)->data($this->buildSecurityKey($key), $data, $expires)->insert(); + } + + /** + * 更新数据 + * @param string $key + * @param int $value + * @param int $expires + * @param IWindCacheDependency $denpendency + * @return boolean + */ + protected function update($key, $value, $expires = 0, IWindCacheDependency $denpendency = null) { + $data = $this->storeData($value, $expires, $denpendency); + if ($expires) { + $expires += time(); + } + return $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->valueField . ' = :value,' . $this->expireField . ' = :expires', array( + ':value' => $data, ':expires' => $expires))->where($this->keyField . '=:key', array( + ':key' => $this->buildSecurityKey($key)))->update(); + } + + public function __destruct() { + if (null !== $this->dbHandler) { + $this->deleteExpiredCache(); + } + } + +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheEaccelerator.php b/wind/component/cache/strategy/WindCacheEaccelerator.php new file mode 100644 index 00000000..74347ea0 --- /dev/null +++ b/wind/component/cache/strategy/WindCacheEaccelerator.php @@ -0,0 +1,58 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +Wind::import('WIND:component.cache.operator.WindEaccelerator'); +/** + * Eaccelerator是一款php加速器、优化器、编码器及动态内容缓存。 + * WindEaccelerator实现Eaccelerator动态内容缓存功能。 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindCacheEaccelerator extends AbstractWindCache { + + /** + * @var WindEaccelerator + */ + protected $eaccelerator = null; + + public function __construct() { + $this->eaccelerator = new WindEaccelerator(); /* @var WindEaccelerator*/ + } + + /* + * @see AbstractWindCache#set() + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire; + return $this->eaccelerator->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); + } + + /* + * @see AbstractWindCache#get() + */ + public function get($key) { + return $this->getDataFromMeta($key, unserialize($this->eaccelerator->get($this->buildSecurityKey($key)))); + } + + /* + * @see AbstractWindCache#delete() + */ + public function delete($key) { + return $this->eaccelerator->delete($this->buildSecurityKey($key)); + } + + /* + * @see AbstractWindCache#clear() + * @return boolean + */ + public function clear() { + return $this->eaccelerator->flush(); + } +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheFile.php b/wind/component/cache/strategy/WindCacheFile.php new file mode 100644 index 00000000..08850ae0 --- /dev/null +++ b/wind/component/cache/strategy/WindCacheFile.php @@ -0,0 +1,187 @@ + + * @author Su Qian + * @version $Id$ + * @package + */ +class WindCacheFile extends AbstractWindCache { + + /** + * 缓存目录 + * @var string + */ + protected $cacheDir; + + /** + * 缓存后缀 + * @var string + */ + protected $cacheFileSuffix = ''; + + /** + * 缓存多级目录。最好不要超3层目录 + * @var int + */ + protected $cacheDirectoryLevel = ''; + + const CACHEDIR = 'cache-dir'; + + const SUFFIX = 'cache-suffix'; + + const LEVEL = 'cache-level'; + + /* (non-PHPdoc) + * @see AbstractWindCache::set() + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire; + return $this->writeData($this->getRealCacheKey($key), $this->storeData($value, $expire, $denpendency), $expire); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::get() + */ + public function get($key) { + return $this->getDataFromMeta($key, $this->readData($this->getRealCacheKey($key))); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::delete() + */ + public function delete($key) { + $cacheFile = $this->getRealCacheKey($key); + if (is_file($cacheFile)) { + return WindFile::delFile($cacheFile); + } + return false; + } + + /* (non-PHPdoc) + * @see AbstractWindCache::clear() + */ + public function clear($isExpired = false) { + return WindFile::clearDir($this->getCacheDir(), $isExpired); + } + /** + * 获取缓存文件名。 + * @param string $key + * @return string + */ + protected function getRealCacheKey($key, $getDir = false) { + $filename = $this->buildSecurityKey($key) . '.' . ltrim($this->getCacheFileSuffix(), '.'); + $_tmp = $this->getCacheDir(); + if (0 < $this->getCacheDirectoryLevel()) { + for ($i = $this->getCacheDirectoryLevel(); $i > 0; --$i) { + if (false === isset($key[$i])) continue; + $_tmp .= $key[$i] . DIRECTORY_SEPARATOR; + } + if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); + } + if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); + return $getDir ? $_tmp : $_tmp . $filename; + } + + /** + * 写入文件缓存 + * @param string $file 缓存文件名 + * @param string $data 缓存数据 + * @param int $mtime 缓存文件的修改时间,即缓存的过期时间 + * @return boolean + */ + protected function writeData($file, $data, $mtime = 0) { + if (WindFile::write($file, $data) == strlen($data)) { + $mtime += $mtime ? time() : 0; + chmod($file, 0777); + return touch($file, $mtime); + } + return false; + } + + /** + * 从文件中读取缓存内容 + * @param string $file 缓存文件名 + * @return null|string + */ + protected function readData($file) { + if (false === is_file($file)) return null; + $mtime = filemtime($file); + if (0 === $mtime || ($mtime && $mtime > time())) + return unserialize(WindFile::read($file)); + elseif (0 < $mtime) + WindFile::delFile($file); + return null; + } + + /* (non-PHPdoc) + * @see AbstractWindCache::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setCacheDir($this->getConfig(self::CACHEDIR, WIND_CONFIG_VALUE)); + } + + /** + * 设置缓存目录 + * @param string $dir + */ + private function setCacheDir($dir) { + $this->cacheDir = Wind::getRealPath($dir,true) . DIRECTORY_SEPARATOR; + } + + /** + * @return the $cacheDir + */ + public function getCacheDir() { + if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0777, true); + return $this->cacheDir; + } + + /** + * @return the $cacheFileSuffix + */ + protected function getCacheFileSuffix() { + if ('' === $this->cacheFileSuffix) { + $this->cacheFileSuffix = $this->getConfig(self::SUFFIX, WIND_CONFIG_VALUE, '', 'bin'); + } + return $this->cacheFileSuffix; + } + + /** + * 返回cache目录级别,默认为0,不分级,最大分级为5 + * @return the $cacheDirectoryLevel + */ + protected function getCacheDirectoryLevel() { + if ('' === $this->cacheDirectoryLevel) { + $this->cacheDirectoryLevel = $this->getConfig(self::LEVEL, WIND_CONFIG_VALUE, '', 0); + } + return $this->cacheDirectoryLevel > 5 ? 5 : $this->cacheDirectoryLevel; + } + + /** + * @param string $cacheFileSuffix + */ + public function setCacheFileSuffix($cacheFileSuffix) { + $this->cacheFileSuffix = $cacheFileSuffix; + } + + /** + * @param int $cacheDirectoryLevel + */ + public function setCacheDirectoryLevel($cacheDirectoryLevel) { + $this->cacheDirectoryLevel = $cacheDirectoryLevel; + } + + /** + * 垃圾回收,清理过期缓存 + */ + public function __destruct() { + $this->clear(true); + } + +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheMem.php b/wind/component/cache/strategy/WindCacheMem.php new file mode 100644 index 00000000..daf313b9 --- /dev/null +++ b/wind/component/cache/strategy/WindCacheMem.php @@ -0,0 +1,114 @@ + + * @author Su Qian + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +Wind::import('WIND:component.cache.operator.WindMemcache'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindCacheMem extends AbstractWindCache { + + /** + * memcache缓存操作句柄 + * @var WindMemcache + */ + protected $memcache = null; + + /** + * 是否对缓存采取压缩存储 + * @var int + */ + protected $compress = 0; + + //配置信息 + /** + * 是否对缓存进行压缩,如果缓存的值较大,可进行压缩 + * @var int + */ + const COMPRESS = 'compress'; + + /** + * 取得memcache配置项 + * @var string + */ + const SERVERCONFIG = 'servers'; + + public function __construct() { + $this->memcache = new WindMemcache(); + } + + /* + * @see AbstractWindCache::set() + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire; + return $this->memcache->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $this->compress, (int) $expire); + } + + /* + * @see AbstractWindCache::get() + */ + public function get($key) { + return $this->getDataFromMeta($key, unserialize($this->memcache->get($this->buildSecurityKey($key), $this->compress))); + } + + /* + * @see AbstractWindCache::delete() + */ + public function delete($key) { + return $this->memcache->delete($this->buildSecurityKey($key)); + } + + /* + * @see AbstractWindCache::clear() + */ + public function clear() { + return $this->memcache->flush(); + } + + /* + * @see WindComponentModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->memcache->setServers($this->getServersConfig()); + $this->compress = $this->getCompress(); + } + + /* + * @see AbstractWindCache#getCacheHandler() + * @return WindMemcache + */ + public function getCacheHandler() { + return $this->memcache; + } + + /** + * 取得缓存配置 + * @return array|mixed + */ + protected function getServersConfig($name = '', $subName = '') { + $servers = $this->getConfig(self::SERVERCONFIG); + if (empty($name)) { + return $servers; + } + if (empty($subName)) { + return isset($servers[$name]) ? $servers[$name] : $servers; + } + return isset($servers[$name][$subName]) ? $servers[$name][$subName] : $servers[$name]; + } + + protected function getCompress() { + $compress = $this->getConfig(self::COMPRESS, WIND_CONFIG_VALUE, '', 0); + return $compress ? MEMCACHE_COMPRESSED : 0; + } + +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheWin.php b/wind/component/cache/strategy/WindCacheWin.php new file mode 100644 index 00000000..0e58bcaf --- /dev/null +++ b/wind/component/cache/strategy/WindCacheWin.php @@ -0,0 +1,54 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +Wind::import('WIND:component.cache.operator.WindWinCache'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ + +class WindCacheWin extends AbstractWindCache { + /** + * @var WindWinCache + */ + protected $wincache = null; + + public function __construct(){ + $this->wincache = new WindWinCache(); + } + /* + * @see AbstractWindCache#set() + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire; + return $this->wincache->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); + } + /* + * @see AbstractWindCache#fetch() + */ + public function get($key) { + return $this->getDataFromMeta($key, unserialize($this->wincache->get($this->buildSecurityKey($key)))); + } + + /* + * @see AbstractWindCache#delete() + */ + public function delete($key) { + return $this->wincache->delete($this->buildSecurityKey($key)); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + return $this->wincache->flush(); + } + +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheXCache.php b/wind/component/cache/strategy/WindCacheXCache.php new file mode 100644 index 00000000..90b08a73 --- /dev/null +++ b/wind/component/cache/strategy/WindCacheXCache.php @@ -0,0 +1,55 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +Wind::import('WIND:component.cache.operator.WindUXCache'); +/** + * xcache加速缓存 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindCacheXCache extends AbstractWindCache { + + /** + * @var WindXCache + */ + protected $xcache = null; + + public function __construct(){ + $this->xcache = new WindXCache(); + } + /* + * @see AbstractWindCache#set() + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire; + return $this->xcache->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); + } + /* + * @see AbstractWindCache#fetch() + */ + public function get($key) { + return $this->getDataFromMeta($key, unserialize($this->xcache->get($this->buildSecurityKey($key)))); + } + + /* + * @see AbstractWindCache#delete() + */ + public function delete($key) { + return $this->xcache->delete($this->buildSecurityKey($key)); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + return $this->xcache->flush(); + } + +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheZend.php b/wind/component/cache/strategy/WindCacheZend.php new file mode 100644 index 00000000..e4e4b2e9 --- /dev/null +++ b/wind/component/cache/strategy/WindCacheZend.php @@ -0,0 +1,58 @@ + + * @author Su Qian + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +Wind::import('WIND:component.cache.operator.WindUZendCache'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindCacheZend extends AbstractWindCache { + + /** + * @var WindZendCache + */ + protected $zendCache = null; + + public function __construct() { + $this->zendCache = new WindZendCache(); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::set() + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire; + return $this->zendCache->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::get() + */ + public function get($key) { + return $this->getDataFromMeta($key, unserialize($this->zendCache->get($this->buildSecurityKey($key)))); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::delete() + */ + public function delete($key) { + return $this->zendCache->delete($this->buildSecurityKey($key)); + } + + /** + * @see AbstractWindCache::clear() + * @return boolean + */ + public function clear() { + return $this->zendCache->flush(); + } + +} \ No newline at end of file diff --git a/wind/component/collections/WindList.php b/wind/component/collections/WindList.php new file mode 100644 index 00000000..f8783ca8 --- /dev/null +++ b/wind/component/collections/WindList.php @@ -0,0 +1,280 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * WindList集合. + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindList implements IteratorAggregate, ArrayAccess, Countable { + + /** + * @var array 集合列表 + */ + private $list = array(); + /** + * @var string 列表总数指示器 + */ + private $count = 0; + /** + * @var boolean 列表是否只读 + */ + private $isReadOnly = false; + + /** + * @var boolean 是否固定大小 + */ + private $isFixedSize = false; + + /** + * WindList 实现有三种类别:只读、固定大小、可变大小。 + * 无法修改只读 WindList。 + * 固定大小的 WindList 不允许添加或移除元素,但允许修改现有元素。 + * 可变大小的 WindList 允许添加、移除和修改元素。 + * @param boolean $readOnly 是否只读 + * @param array|WindList $data 固定长度,如果指定了$data,那么这个WindList集合的长度是固定的,只许修改 + */ + public function __construct($data = array(),$readOnly = false) { + $this->isReadOnly = $readOnly; + if(false === empty($data)){ + if(is_array($data)){ + $this->list = $data; + }elseif($data instanceof WindList){ + $this->list = $data->getList(); + }else{ + throw new WindException("Parameter type is incorrect"); + } + $this->isFixedSize = true; + $this->count = count($this->list); + } + + } + /** + * 向 WindList 中添加项。 + * @param mixed $value + * @return boolean + */ + public function add($value) { + return $this->insertAt($this->count, $value); + } + /** + * 在 WindList 中的指定索引处插入项。 + * @param int $index + * @param mixed $value + * @return boolean + */ + public function insertAt($index, $value) { + if($this->isFixedSize && $this->count === $index){ + throw new WindException("The list size is fixed"); + } + if (false === $this->isReadOnly) { + if ($this->count === $index) { + $this->list[$this->count++] = $value; + } elseif (0 <= $index && $this->count > $index) { + array_splice($this->list, $index, 0, array($value)); + $this->count++; + } elseif ($this->count < $index || 0 > $index) { + throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); + } + } else { + throw new WindException('The list of read-only'); + } + return true; + } + /** + * 取得指定索引的项 + * @param int $index 指定索引 + * @return mixed + */ + public function itemAt($index) { + if (false === isset($this->list[$index])) { + throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); + } + return $this->list[$index]; + } + /** + * 返回指定项的索引,返回-1表向没有指定项 + * @param mixed $value 指定项 + * @return int + */ + public function indexOf($value) { + return false !== ($index = array_search($value, $this->list, true)) ? $index : -1; + } + /** + * 判断WindList中是否包含指定项 + * @param mixed $value 指定项 + * @return boolean + */ + public function contain($value) { + return 0 <= $this->indexOf($value); + } + /** + * 判断WindList中是否包含指定的索引 + * @param int $index 指定索引 + * @return boolean + */ + public function containAt($index) { + return 0 <= $index && $this->count > $index; + } + /** + * 修改WindList中指定索引的项 + * @param int $index 指定索引 + * @param mixed $value 要修改的项 + * @return boolean + */ + public function modify($index,$value){ + $this->removeAt($index,true); + $this->count++; + $this->insertAt($index, $value); + $this->count--; + return true; + } + /** + * 从WindList中移除指定索引的项 + * @param int $index 指定索引 + * @return mixed + */ + public function removeAt($index,$force = false) { + if ($this->isReadOnly) { + throw new WindException('The list of read-only'); + } + if($this->isFixedSize && false === $force){ + throw new WindException("The list size is fixed"); + } + if ($index > $this->count || $index < 0) { + throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); + } + $this->count--; + if (0 === $index) { + return array_shift($this->list); + } + if ($this->count === $index) { + return array_pop($this->list); + } + $item = $this->list[$index]; + array_splice($this->list, $index, 1); + return $item; + } + /** + * 从WindList中移除指定的项 + * @param mixed $value 指定的项 + * @return boolean + */ + public function remove($value) { + return $this->removeAt($this->indexOf($value)); + } + /** + * 清空WindList + * @return boolean + */ + public function clear() { + if ($this->isReadOnly) { + throw new WindException('The list of read-only'); + } + if($this->isFixedSize){ + throw new WindException("The list size is fixed"); + } + $this->count = 0; + $this->list = array(); + return true; + } + /** + * 将数组中的值合并到WindList + * @param array $array 要合并的数组 + * @return boolean + */ + public function mergeFromArray(array $array) { + foreach ($array as $value) { + $this->add($value); + } + return true; + } + /** + * 将WindList集合合并到WindList + * @param WindList $list 要合并的WindList集合 + * @return boolean + */ + public function mergeFromList(WindList $list) { + foreach ($list as $value) { + $this->add($value); + } + return true; + } + /** + * @return array + */ + public function getList() { + return $this->list; + } + /** + * 取得集合的总数 + * @return string + */ + public function getCount() { + return $this->count; + } + /** + * 取得集合是否只读 + * @return boolean + */ + public function getIsReadOnly() { + return $this->isReadOnly; + } + /** + * 取得集合是否是固定大小 + * @return boolean + */ + public function getIsFixedSize(){ + return $this->isFixedSize; + } + /* + * 计算集合的总个数 + * @see Countable#count() + */ + public function count() { + return $this->getCount(); + } + /** + * @param int $offset + */ + public function offsetExists($offset) { + return $this->containAt($offset); + } + /** + * @param int $offset + */ + public function offsetGet($offset) { + return $this->itemAt($offset); + } + /** + * @param int $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) { + if (null === $offset || $this->count === $offset) { + return $this->add($value); + } + return $this->modify($offset, $value); + } + /** + * @param int $offset + */ + public function offsetUnset($offset) { + return $this->removeAt($offset); + } + /** + * 取得集合的迭代器 + */ + public function getIterator() { + return new ArrayIterator($this->list); + } + +} \ No newline at end of file diff --git a/wind/component/collections/WindQueue.php b/wind/component/collections/WindQueue.php new file mode 100644 index 00000000..0400068c --- /dev/null +++ b/wind/component/collections/WindQueue.php @@ -0,0 +1,134 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 队列操作,先进先出 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindQueue implements IteratorAggregate,Countable{ + /** + * @var array 队列列表 + */ + private $list = array(); + /** + * @var string 列表总数指示器 + */ + private $count = 0; + + /** + * 移除并返回位于 Queue顶部的元素。 + * @return mixed + */ + public function dequeue(){ + if(!$this->count){ + throw new WindException("The queue is empty"); + } + --$this->count; + return array_shift($this->list); + } + + /** + * 返回位于 Queue顶部的对象但不将其移除。 + * @return mixed + */ + public function peek(){ + if(!$this->count){ + throw new WindException("The queue is empty"); + } + return $this->list[0]; + } + + /** + * 将元素添加到 Queue的底部。 + * @param mixed $value + * @return number + */ + public function enqueue($value){ + ++$this->count; + return array_push($this->list,$value); + } + + /** + * 确定某元素是否在 Queue中。 + * @param mixed $value + * @return boolean + */ + public function contain($value){ + return false !==array_search($value, $this->list, true); + } + + /** + * 将数组中的值合并到当前WindQueue队列 + * @param array $array 要合并的数组 + * @return boolean + */ + public function mergeFromArray(array $array) { + foreach ($array as $value) { + $this->enqueue($value); + } + return true; + } + /** + * 将WindQueue队列集合合并到当前WindQueue队列 + * @param WindQueue $list 要合并的WindQueue集合 + * @return boolean + */ + public function mergeFromQueue(WindQueue $queue) { + foreach ($queue as $value) { + $this->enqueue($value); + } + return true; + } + + /** + *清空队列 + */ + public function clear(){ + $this->list = array(); + $this->count = 0; + return true; + } + + /** + * 创建 Queue的浅表副本。 + * @return WindQueue + */ + public function __clone(){ + return new self(); + } + + /** + * 取得队列个数 + * @return int + */ + public function getCount(){ + return $this->count; + } + + + /* + * 计算队列个数 + * @see Countable#count() + */ + public function count() { + return $this->getCount(); + } + + /** + * 取得队列的迭代器 + */ + public function getIterator() { + return new ArrayIterator($this->list); + } + + +} \ No newline at end of file diff --git a/wind/component/collections/WindSortedList.php b/wind/component/collections/WindSortedList.php new file mode 100644 index 00000000..6408320a --- /dev/null +++ b/wind/component/collections/WindSortedList.php @@ -0,0 +1,333 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 表示键/值对的集合,这些键值对按键排序并可按照键和索引访问。 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSortedList implements IteratorAggregate, ArrayAccess, Countable { + /** + * @var array 集合列表 + */ + private $list = array(); + /** + * @var int 列表总数指示器 + */ + private $count = 0; + /** + * @var boolean 列表是否只读 + */ + private $isReadOnly = false; + + /** + * @var boolean 是否固定大小 + */ + private $isFixedSize = false; + + /** + * WindList 实现有三种类别:只读、固定大小、可变大小。 + * 无法修改只读 WindList。 + * 固定大小的 WindList 不允许添加或移除元素,但允许修改现有元素。 + * 可变大小的 WindList 允许添加、移除和修改元素。 + * @param boolean $readOnly 是否只读 + * @param array|WindList $data 固定长度,如果指定了$data,那么这个WindList集合的长度是固定的,只许修改 + */ + public function __construct($data = array(), $readOnly = false) { + $this->isReadOnly = $readOnly; + if (false === empty($data)) { + if (is_array($data)) { + $this->list = $data; + } elseif ($data instanceof WindList) { + $this->list = $data->getList(); + } else { + throw new WindException("Parameter type is incorrect"); + } + $this->isFixedSize = true; + $this->count = count($this->list); + } + + } + + /** + * 将带有指定键和值的元素添加到 WindSortedList 对象。 + * @param mixed $key + * @param mixed $value + */ + public function add($key, $value) { + $this->checkPermissions(); + if (isset($this->list[$key])) { + throw new WindException($key . ' key already exists in the collection'); + } + $this->list[$key] = $value; + ++$this->count; + return true; + } + /** + * 确定 WindSortedList对象是否包含特定的键。 + * @param mixed $key + * @return boolean + */ + public function contains($key) { + return $this->containsKey($key); + } + + /** + * 根据指定的索引确定 WindSortedList对象是否包含特定的键。 + * @param mixed $key + * @return boolean + */ + public function containsIndex($index) { + return $this->containsKey($this->getKey($index)); + } + + /** + * 确定 WindSortedList对象是否包含特定的键。 + * @param mixed $key + * @return boolean + */ + public function containsKey($key) { + return 0 <= $this->indexOfKey($key); + } + + /** + * 确定 WindSortedList对象是否包含特定值。 + * @param mixed $value + * @return boolean + */ + public function containsValue($value) { + return 0 <= $this->indexOfValue($value); + } + + /** + * 获取 WindSortedList 对象的指定索引处的键。 + * @param int $index 指定的索引 + * @return mixed + */ + public function getKey($index) { + $keys = $this->getKeyList(); + if (false === isset($keys[$index])) { + throw new WindException('Index out of range, is indeed the range should be between 0 to ' . $this->count); + } + return $keys[$index]; + } + + /** + * 获取WindSortedList 对象中的键。 + * @return mixed + */ + public function getKeyList() { + return array_keys($this->list); + } + + /** + * 获取WindSortedList 对象中的值。 + * @return mixed + */ + public function getValueList() { + return array_values($this->list); + } + + /** + * 返回WindSortedList 对象中指定键的从零开始的索引。 + * @param mixed $key + * @return mixed + */ + public function indexOfKey($key) { + return false !== ($index = array_search($key, $this->getKeyList(), true)) ? $index : -1; + } + + /** + * 返回指定的值在 SortedList 对象中第一个匹配项的从零开始的索引。 + * @param mixed $value + * @return mixed + */ + public function indexOfValue($value) { + return false !== ($index = array_search($value, $this->getValueList(), true)) ? $index : -1; + } + + /** + * 从WindSortedList中返回指定键的的值 + * @param int $key + * @return mixed + */ + public function item($key) { + if (false === isset($this->list[$key])) { + throw new WindException($key . ' is not exists in the collection'); + } + return $this->list[$key]; + } + /** + * 从WindSortedList中返回指定索引的的值 + * @param int $index + * @return mixed + */ + public function itemAt($index) { + $key = $this->getKey($index); + return $this->list[$key]; + } + /** + * 从 SortedList 对象中移除带有指定键的元素。 + * @param mixed $key + * @return mixed + */ + public function remove($key) { + $this->checkPermissions(); + if (false === isset($this->list[$key])) { + throw new WindException($key . ' is not exists in the collection'); + } + $item = $this->list[$key]; + unset($this->list[$key]); + --$this->count; + return $item; + } + /** + * 移除 WindSortedList对象的指定索引处的元素。 + * @param int $index + * @return mixed + */ + public function removeAt($index) { + $this->checkPermissions(); + $key = $this->getKey($index); + $item = $this->list[$key]; + unset($this->list[$key]); + --$this->count; + return $item; + } + /** + * 替换WindSortedList对象中指定索引处的值。 + * @param int $index + * @param mixed $value + * @return boolean + */ + public function setByIndex($index, $value) { + $this->checkPermissions(false); + $key = $this->getKey($index); + $this->list[$key] = $value; + return true; + } + /** + * 替换WindSortedList对象中指定键处的值。 + * 如果指定的键存在,那么替换,否则新增 + * @param mixed $key + * @param mixed $value + * @return mixed + */ + public function setByKey($key, $value) { + $this->checkPermissions(false); + if (isset($this->list[$key])) { + $item = $this->list[$key]; + $this->list[$key] = $value; + return $item; + } + $this->list[$key] = $value; + ++$this->count; + return $value; + } + + /** + * 从 SortedList 对象中移除所有元素。 + * @return boolean + */ + public function clear() { + $this->checkPermissions(); + $this->count = 0; + $this->list = array(); + return true; + } + /** + * 取得集合是否只读 + * @return boolean + */ + public function getIsReadOnly() { + return $this->isReadOnly; + } + /** + * 取得集合是否是固定大小 + * @return boolean + */ + public function getIsFixedSize(){ + return $this->isFixedSize; + } + /** + * 返回集合的总数 + * @return number + */ + public function getCount() { + return $this->count; + } + /* 计算集合总数 + * @see Countable#count() + */ + public function count() { + return $this->getCount(); + } + /** + * 取得WindSortedList集合迭代器 + * @return ArrayIterator + */ + public function getIterator() { + return new ArrayIterator($this->list); + } + /* + * @see ArrayAccess#offsetExists() + */ + public function offsetExists($offset) { + if (is_int($offset)) { + return $this->containsIndex($offset); + } + return $this->containsKey($offset); + } + /* + * @see ArrayAccess#offsetGet() + */ + public function offsetGet($offset) { + if (is_int($offset)) { + return $this->itemAt($offset); + } + return $this->item($offset); + } + /* + * @see ArrayAccess#offsetSet() + */ + public function offsetSet($offset, $value) { + if (is_int($offset)) { + return $this->setByIndex($offset, $value); + } + return $this->setByKey($offset, $value); + } + /* + * @see ArrayAccess#offsetUnset() + */ + public function offsetUnset($offset) { + if (is_int($offset)) { + return $this->removeAt($offset); + } + return $this->remove($offset); + } + /** + * 创建 WindSortedList对象的浅表副本。 + * @return WindSortedList + */ + public function __clone() { + return new self($this->list, $this->isReadOnly); + } + + private function checkPermissions($ifcheckFixedSize = true) { + if ($this->isReadOnly) { + throw new WindException('The list of read-only'); + } + if ($this->isFixedSize && $ifcheckFixedSize) { + throw new WindException("The list size is fixed"); + } + } + +} \ No newline at end of file diff --git a/wind/component/collections/WindStack.php b/wind/component/collections/WindStack.php new file mode 100644 index 00000000..0a935496 --- /dev/null +++ b/wind/component/collections/WindStack.php @@ -0,0 +1,125 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 堆栈操作,先进后出 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindStack implements IteratorAggregate,Countable{ + + /** + * @var array 集合列表 + */ + private $list = array(); + /** + * @var string 列表总数指示器 + */ + private $count = 0; + + /** + * 移除并返回位于 Stack 底部的对象。 + * @return mixed + */ + public function pop(){ + if(!$this->count){ + throw new WindException("The stack is empty"); + } + --$this->count; + return array_pop($this->list); + } + + /** + * 返回位于 Stack底部的对象但不将其移除。 + * @return mixed + */ + public function peek(){ + if(!$this->count){ + throw new WindException("The stack is empty"); + } + return $this->list[$this->count-1]; + } + + /** + * 确定某元素是否在 Stack中。 + * @param mixed $value + * @return boolean + */ + public function contain($value){ + return false !== array_search($value, $this->list, true); + } + /** + * 将元素插入 Stack 的底部。 + * @param mixed $value + * @return number + */ + public function push($value){ + ++$this->count; + return array_push($this->list,$value); + } + /** + * 清空队列 + */ + public function clear(){ + $this->count = 0; + $this->list = array(); + return true; + } + /** + * 将数组中的值合并到当前tack队列 + * @param array $array 要合并的数组 + * @return boolean + */ + public function mergeFromArray($array) { + foreach ($array as $value) { + $this->push($value); + } + return true; + } + /** + * 将WindStack堆栈集合合并到当前Stack队列 + * @param WindStack $list 要合并的WindStack集合 + * @return boolean + */ + public function mergeFromStack(WindStack $stack) { + foreach ($stack as $value) { + $this->push($value); + } + return true; + } + /** + * 取得堆栈个数 + * @return string + */ + public function getCount(){ + return $this->count; + } + /* + * 计算堆栈的总个数 + * @see Countable#count() + */ + public function count() { + return $this->getCount(); + } + /** + * 取得堆栈的迭代器 + */ + public function getIterator() { + return new ArrayIterator($this->list); + } + /** + * 创建 stack的浅表副本。 + * @return WindStack + */ + public function __clone(){ + return new self(); + } +} \ No newline at end of file diff --git a/wind/component/dao/AbstractWindDao.php b/wind/component/dao/AbstractWindDao.php new file mode 100644 index 00000000..44889024 --- /dev/null +++ b/wind/component/dao/AbstractWindDao.php @@ -0,0 +1,93 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindDao extends WindModule { + + protected $dbClass = 'WIND:component.db.WindConnection'; + + protected $dbConfig = ''; + + protected $cacheClass = ''; + + protected $cacheConfig = ''; + + protected $isDataCache = false; + + protected $dbDefinition = null; + + /** + * @var WindConnection 数据库链接兑现 + */ + private $connection = null; + + /** + * @var AbstractWindCache 缓存操作句柄 + */ + private $cacheHandler = null; + + /* + * @see WindModule::getWriteTableForGetterAndSetter() + */ + protected function getWriteTableForGetterAndSetter() { + return array('dbClass', 'dbConfig', 'cacheClass', 'isDataCache', 'dbHandler', 'cacheConfig', 'cacheHandler'); + } + + /** + * 获得DB类定义 + * @return WindComponentDefinition + */ + public function getDbDefinition() { + Wind::import('WIND:core.factory.WindComponentDefinition'); + $definition = new WindComponentDefinition(); + $definition->setPath($this->dbClass); + $definition->setScope(WindComponentDefinition::SCOPE_SINGLETON); + $definition->setAlias($this->dbClass); + $definition->setConfig(array(WindComponentDefinition::RESOURCE => $this->dbConfig)); + return $definition; + } + + /** + * 获得Cache类定义 + * @return WindComponentDefinition + */ + public function getCacheDefinition() { + Wind::import('WIND:core.factory.WindComponentDefinition'); + $definition = new WindComponentDefinition(); + $definition->setPath($this->cacheClass); + $definition->setScope(WindComponentDefinition::SCOPE_SINGLETON); + $definition->setAlias($this->cacheClass); + $definition->setConfig(array(WindComponentDefinition::RESOURCE => $this->cacheConfig)); + return $definition; + } + + /** + * 获得需要缓存的处理的方法名称数组 + * array('methodName1'=>'WIND:component') + * @return multitype: + */ + public function getCacheMethods() { + return array(); + } + + /** + * @return WindConnection $connection + */ + public function getConnection() { + return $this->connection; + } + + /** + * @param WindConnection $windConnection + */ + public function setConnection($windConnection) { + $this->connection = $windConnection; + } +} +?> \ No newline at end of file diff --git a/wind/component/dao/AbstractWindDaoFactory.php b/wind/component/dao/AbstractWindDaoFactory.php new file mode 100644 index 00000000..80ee1d20 --- /dev/null +++ b/wind/component/dao/AbstractWindDaoFactory.php @@ -0,0 +1,141 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindDaoFactory { + protected $windFactory = null; + protected $daoResource = ''; + protected $dbConnections = array(); + protected $caches = array(); + + /** + * 返回Dao类实例 + * + * @param string $className + */ + public function getDao($className) { + try { + $_path = ''; + if (strpos($className, ":") !== false || strpos($className, ".") !== false) { + $_path = $className; + } elseif ($this->getDaoResource()) { + $_path = $this->getDaoResource() . '.' . $className; + } else { + $_path = $className; + } + $className = Wind::import($_path); + $daoInstance = WindFactory::createInstance($className); + $daoInstance->setConnection($this->createDbConnection($daoInstance)); + if (!$daoInstance->getIsDataCache()) return $daoInstance; + $daoInstance->setCacheHandler($this->createCacheHandler($daoInstance)); + $daoInstance->setClassProxy(new WindClassProxy()); + $daoInstance = $daoInstance->getClassProxy(); + $this->registerCacheListener($daoInstance); + return $daoInstance; + } catch (Exception $exception) { + throw new WindDaoException($exception->getMessage()); + } + } + + /** + * 注册Dao缓存监听 + * @param AbstractWindDao daoInstance + */ + private function registerCacheListener($daoInstance) { + $caches = (array) $daoInstance->getCacheMethods(); + foreach ($caches as $classMethod => $classPath) { + if (!$classMethod) continue; + if ($classPath === 'default') + $_className = Wind::import('COM:dao.listener.WindDaoCacheListener'); + else + $_className = Wind::import($classPath); + if (!$_className) continue; + $daoInstance->registerEventListener($classMethod, new $_className($daoInstance)); + } + } + + /** + * 返回DbHandler + * @param AbstractWindDao $daoObject + * @return WindConnection + */ + protected function createDbConnection($daoObject) { + $_dbClass = $daoObject->getDbClass(); + $_connection = null; + if (!isset($this->dbConnections[$_dbClass])) { + $this->createWindFactory(); + $defintion = $daoObject->getDbDefinition(); + $this->windFactory->addClassDefinitions($defintion); + $this->dbConnections[$_dbClass] = $this->windFactory->getInstance($defintion->getAlias()); + } + return $this->getHandler($_dbClass); + } + + /** + * @param string $key + * @return WindConnection + */ + private function getHandler($key) { + $connection = $this->dbConnections[$key]; + if ($connection === null) return null; + if ($connection instanceof WindConnectionManager) { + return $connection->getConnection(); + } elseif ($connection instanceof WindConnection) { + return $connection; + } + } + + /** + * 返回Cache对象 + * @param AbstractWindDao $daoObject + * @return AbstractWindCache + */ + protected function createCacheHandler($daoObject) { + $_cacheClass = $daoObject->getCacheClass(); + if (!isset($this->caches[$_cacheClass])) { + $this->createWindFactory(); + $defintion = $daoObject->getCacheDefinition(); + $this->windFactory->addClassDefinitions($defintion); + $this->caches[$_cacheClass] = $this->windFactory->getInstance($defintion->getAlias()); + } + return $this->caches[$_cacheClass]; + } + + /** + * @return WindFactory + */ + private function createWindFactory() { + if ($this->windFactory === null) { + Wind::import('WIND:core.factory.WindComponentFactory'); + $this->windFactory = new WindComponentFactory(); + } + return $this->windFactory; + } + + /** + * @return the $daoResource + */ + public function getDaoResource() { + return $this->daoResource; + } + + /** + * @param field_type $daoResource + */ + public function setDaoResource($daoResource) { + $this->daoResource = $daoResource; + } +} +?> \ No newline at end of file diff --git a/wind/component/dao/listener/WindDaoCacheListener.php b/wind/component/dao/listener/WindDaoCacheListener.php new file mode 100644 index 00000000..e35b2c6b --- /dev/null +++ b/wind/component/dao/listener/WindDaoCacheListener.php @@ -0,0 +1,55 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindDaoCacheListener extends WindHandlerInterceptor { + + private $daoObject = null; + + /** + * @param AbstractWindDao $instance + */ + function __construct($instance) { + $this->daoObject = $instance; + } + + /* + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + /* @var $cacheHandler AbstractWindCache */ + $cacheHandler = $this->daoObject->getCacheHandler(); + $key = $this->generateKey(func_get_args()); + $result = $cacheHandler->get($key); + return empty($result) ? null : $result; + } + + /* + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + /* @var $cacheHandler AbstractWindCache */ + $cacheHandler = $this->daoObject->getCacheHandler(); + $key = $this->generateKey(func_get_args()); + $cacheHandler->set($key, $this->result); + } + + /** + * 返回缓存键值 + * @param array $args + * @return string + */ + private function generateKey($args) { + return $this->event[0] . '_' . $this->event[1] . '_' . (is_array($args[0]) ? $args[0][0] : $args[0]); + } +} + +?> \ No newline at end of file diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php new file mode 100644 index 00000000..42c1e939 --- /dev/null +++ b/wind/component/db/WindConnection.php @@ -0,0 +1,231 @@ + + * @version $Id$ + * @package + */ +class WindConnection extends WindComponentModule { + const DSN = 'dsn'; + const USER = 'user'; + const PWD = 'pwd'; + const CHARSET = 'charset'; + const ENABLELOG = 'enablelog'; + const DRIVER = 'driver'; + /** + * PDO 链接字符串 + * @var string + */ + private $_dsn; + private $_driverName; + private $_user; + private $_pwd; + private $_tablePrefix; + private $_charset = 'gbk'; + private $_enableLog = false; + /** + * @var array + */ + private $_attributes = array(); + /** + * @var PDO + */ + private $_dbHandle = null; + + /** + * @param string $dsn + * @param string $username + * @param string $password + */ + public function __construct($dsn = '', $username = '', $password = '') { + $this->setDsn($dsn); + $this->setUser($username); + $this->setPwd($password); + } + + /** + * 接受一条sql语句,并返回sqlStatement对象 + * @param string $sql | sql语句 + * @return WindSqlStatement + */ + public function createStatement($sql = null) { + Wind::import("WIND:component.db.WindSqlStatement"); + return new WindSqlStatement($this, $sql); + } + + /** + * @return PDO + */ + public function getDbHandle() { + return $this->_dbHandle; + } + + /** + * @param int $attribute + * @return string + * */ + public function getAttribute($attribute = '') { + if (!$attribute) return; + if ($this->getDbHandle() !== null) { + return $this->getDbHandle()->getAttribute($attribute); + } else + return isset($this->_attributes[$attribute]) ? $this->_attributes[$attribute] : ''; + } + + /** + * @param $attribute + * @param $value + * @return + * */ + public function setAttribute($attribute = '', $value = '') { + if (!$attribute) return; + if ($this->_dbHandle !== null && $this->_dbHandle instanceof PDO) { + $this->_dbHandle->setAttribute($attribute, $value); + } else + $this->_attributes[$attribute] = $value; + } + + /** + * 返回DB驱动类型 + * @return string + */ + public function getDriverName() { + if ($this->_driverName) return $this->_driverName; + if ($this->_dbHandle !== null) { + $this->setDriverName($this->_dbHandle->getAttribute(PDO::ATTR_DRIVER_NAME)); + } elseif (($pos = strpos($this->getDsn(), ':')) !== false) { + $this->setDriverName(strtolower(substr($this->getDsn(), 0, $pos))); + } else { + $this->setDriverName($this->getConfig(self::DRIVER)); + } + return $this->_driverName; + } + + /** + * @param string $driverName + */ + public function setDriverName($driverName) { + $this->_driverName = $driverName; + } + + /** + * @return the $enableLog + */ + public function getEnableLog() { + return $this->_enableLog; + } + + /** + * @param boolean $enableLog + */ + public function setEnableLog($enableLog) { + $this->_enableLog = (boolean) $enableLog; + } + + /** + * @return the $tablePrefix + */ + public function getTablePrefix() { + return $this->_tablePrefix; + } + + /** + * @param string $tablePrefix + */ + public function setTablePrefix($tablePrefix) { + $this->_tablePrefix = $tablePrefix; + } + + /** + * @return the $charset + */ + public function getCharset() { + if ($this->_charset) return $this->_charset; + $this->setCharset($this->getConfig(self::CHARSET)); + return $this->_charset; + } + + /** + * @param string $charset + */ + public function setCharset($charset) { + $this->_charset = $charset; + } + + /** + * @return the $_dsn + */ + public function getDsn() { + if ($this->_dsn) return $this->_dsn; + $this->setDsn($this->getConfig(self::DSN)); + return $this->_dsn; + } + + /** + * @param string $dsn + */ + public function setDsn($dsn) { + $this->_dsn = $dsn; + } + + /** + * @return the $_user + */ + public function getUser() { + if ($this->_user) return $this->_user; + $this->_user = $this->getConfig(self::USER); + return $this->_user; + } + + /** + * @param string $userName + */ + public function setUser($userName) { + $this->_user = $userName; + } + + /** + * @return the $_pwd + */ + public function getPwd() { + if ($this->_pwd) return $this->_pwd; + $this->setPwd($this->getConfig(self::PWD)); + return $this->_pwd; + } + + /** + * @param string $_pwd + */ + public function setPwd($_pwd) { + $this->_pwd = $_pwd; + } + + /** + * 初始化DB句柄 + * @throws Exception + * @return + */ + public function init() { + if ($this->_dbHandle !== null) return; + try { + Wind::log("component.db.WindConnection._init() Initialize DB handle, set default attributes and charset.", WindLogger::LEVEL_INFO); + $driverName = $this->getDriverName(); + if ($driverName) { + $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; + $dbHandleClass = Wind::import($dbHandleClass); + } else + $dbHandleClass = 'PDO'; + if (!$dbHandleClass) { + throw new WindDbException('The db handle class path \'' . $dbHandleClass . '\' is not exist.'); + } + $this->_dbHandle = new $dbHandleClass($this->getDsn(), $this->getUser(), $this->getPwd(), (array) $this->_attributes); + $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->_dbHandle->setCharset($this->getCharset()); + Wind::log("component.db.WindConnection._init() \r\n dsn: " . $this->getDsn() . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, WindLogger::LEVEL_DEBUG); + } catch (PDOException $e) { + Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", WindLogger::LEVEL_TRACE); + throw new WindDbException($e->getMessage()); + } + } +} +?> \ No newline at end of file diff --git a/wind/component/db/WindConnectionManager.php b/wind/component/db/WindConnectionManager.php new file mode 100644 index 00000000..9a25ac50 --- /dev/null +++ b/wind/component/db/WindConnectionManager.php @@ -0,0 +1,18 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindConnectionManager extends WindComponentModule { + + /** + * @param string $dsn + * @param string $username + * @param string $password + */ + public function __construct($dsn = '', $username = '', $password = '') { + + } +} \ No newline at end of file diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php new file mode 100644 index 00000000..9b8f04df --- /dev/null +++ b/wind/component/db/WindResultSet.php @@ -0,0 +1,103 @@ + + * @version $Id$ + * @package + */ +class WindResultSet { + /** + * @var PDOStatement + */ + private $_statement = null; + /** + * PDO fetchMode, default fetchMode PDO::FETCH_ASSOC + * @var number + */ + private $_fetchMode = PDO::FETCH_ASSOC; + /** + * PDO fetchType, default fetchType PDO::FETCH_ORI_FIRST + * @var number + */ + private $_fetchType = PDO::FETCH_ORI_FIRST; + + /** + * @param WindSqlStatement $sqlStatement + */ + public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { + $this->_statement = $sqlStatement->getStatement(); + if ($fetchMode != 0) $this->_fetchMode = $fetchMode; + if ($fetchType != 0) $this->_fetchType = $fetchType; + } + + /** + * @param $fetchMode + * @return + */ + public function setFetchMode($fetchMode) { + $fetchMode = func_get_args(); + call_user_func_array(array( + $this->_statement, + 'setFetchMode'), $fetchMode); + } + + /** + * 返回结果集的条数 + * @return number + */ + public function columnCount() { + return $this->_statement->columnCount(); + } + + /** + * Fetches the next row from a result set + * @return array + */ + public function fetch() { + return $this->_fetch($this->_fetchMode, $this->_fetchType); + } + + /** + * @param $fetchMode + * @param $fetchType + */ + private function _fetch($fetchMode, $fetchType) { + return $this->_statement->fetch($fetchMode, $fetchType); + } + + /** + * @return boolean | 成功返回true失败返回false + */ + public function nextRowset() { + return $this->_statement->nextRowset(); + } + + /** + * 返回所有的查询结果 + * @return array + */ + public function fetchAll() { + return $this->_statement->fetchAll(); + } + + /** + * @param int $index + * @return string + */ + public function fetchColumn($index = 0) { + return $this->_statement->fetchColumn($index); + } + + /** + * Fetches the next row and returns it as an object + * @param string $className + * @param array $ctor_args + * @return array + */ + public function fetchObject($className = '', $ctor_args = array()) { + if ($className === '') + return $this->_statement->fetchObject(); + else + return $this->_statement->fetchObject($className, $ctor_args); + } +} +?> \ No newline at end of file diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php new file mode 100644 index 00000000..64526821 --- /dev/null +++ b/wind/component/db/WindSqlStatement.php @@ -0,0 +1,199 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindSqlStatement { + /** + * @var WindConnection + */ + private $_connection; + /** + * @var PDOStatement + */ + private $_statement = null; + /** + * sql语句字符串 + * + * @var string + */ + private $_queryString; + /** + * PDO类型映射 + * + * @var array + */ + private $_typeMap = array( + 'boolean' => PDO::PARAM_BOOL, + 'integer' => PDO::PARAM_INT, + 'string' => PDO::PARAM_STR, + 'NULL' => PDO::PARAM_NULL); + + /** + * @param WindConnection $connection + * @param string $query + */ + public function __construct($connection, $query) { + $this->_connection = $connection; + $this->setQueryString($query); + } + + /** + * 参数绑定 + * @param string $parameter + * @param string $variable + * @param string $data_type + * @param int $length + * @param $driver_options + * @return + */ + public function bindParam($parameter, $variable, $data_type = null, $length = null, $driver_options = null) { + try { + Wind::log("component.db.WindSqlStatement.bindParam. parameter:" . $parameter . " variable:" . $variable, WindLogger::LEVEL_INFO, "component.db"); + $this->init(); + if ($data_type === null) { + $data_type = $this->_getPdoDataType($variable); + } + if ($length === null) + $this->getStatement()->bindParam($parameter, $variable, $data_type); + else + $this->getStatement()->bindParam($parameter, $variable, $data_type, $length, $driver_options); + return $this; + } catch (PDOException $e) { + Wind::log("component.db.WindSqlStatement.bindParam. exception message:" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); + throw new WindDbException($e->getMessage()); + } + } + + /** + * @param string $parameter + * @param string $value + * @param int $data_type + * @return + */ + public function bindValue($parameter, $value, $data_type = null) { + try { + Wind::log("component.db.WindSqlStatement.bindValue. parameter:" . $parameter . " variable:" . $value, WindLogger::LEVEL_INFO, "component.db"); + $this->init(); + if ($data_type === null) { + $data_type = $this->_getPdoDataType($value); + } + $this->getStatement()->bindValue($parameter, $value, $data_type); + return $this; + } catch (PDOException $e) { + Wind::log("component.db.WindSqlStatement.bindValue. exception message:" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); + throw new WindException($e->getMessage()); + } + } + + /** + * @param array $values + */ + public function bindValues($values) { + foreach ($values as $key => $value) { + $this->bindValue($key, $value, $this->_getPdoDataType($value)); + } + return $this; + } + + /** + * 执行SQL语句,并返回查询结果 + * @param array $params + * @param int $fetchMode + * @param int $fetchType + * @return WindResultSet + */ + public function query($params = array(), $fetchMode = 0, $fetchType = 0) { + $this->execute($params, false); + return new WindResultSet($this, $fetchMode, $fetchType); + } + + /** + * 执行sql,$params为变量信息,并返回结果集 + * @param array $params + * @param boolean $rowCount + * @return rowCount + */ + public function execute($params = array(), $rowCount = true) { + try { + $this->init(); + Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); + if (empty($params)) { + $this->getStatement()->execute(); + } else + $this->getStatement()->execute($params); + $_result = $rowCount ? $this->getStatement()->rowCount() : true; + Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); + return $_result; + } catch (PDOException $e) { + Wind::log("component.db.WindSqlStatement.execute throw exception,exception message: " . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); + throw new WindDbException($e->getMessage()); + } + } + + /** + * @param string $queryString + * @return WindSqlStatement + */ + public function setQueryString($queryString) { + if (!$queryString) return $this; + if ($_prefix = $this->getConnection()->getTablePrefix()) { + $queryString = preg_replace('/{{(.*?)}}/', $_prefix . '\1', $queryString); + } + $this->_queryString = $queryString; + return $this; + } + + /** + * @return the $_queryString + */ + public function getQueryString() { + return $this->_queryString; + } + + /** + * @return WindConnection + */ + public function getConnection() { + return $this->_connection; + } + + /** + * @return PDOStatement + */ + public function getStatement() { + return $this->_statement; + } + + /** + * @return + */ + public function init() { + if ($this->_statement === null) { + try { + Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. ", WindLogger::LEVEL_INFO, "component.db"); + Wind::profileBegin("component.db.WindSqlStatement._init", " SQL: " . $this->getQueryString(), "component.db"); + $this->getConnection()->init(); + $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString()); + Wind::profileEnd('component.db.WindSqlStatement._init'); + Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. This statement is " . get_class($this->_statement), WindLogger::LEVEL_DEBUG, "component.db"); + } catch (PDOException $e) { + Wind::log("Component.db.WindSqlStatement._init Initialize DBStatement + failed.", WindLogger::LEVEL_TRACE, "component.db"); + throw new WindDbException("Initialization WindSqlStatement failed."); + } + } + } + + /** + * @param variable + * @param data_type + */ + private function _getPdoDataType($variable) { + return isset($this->_typeMap[gettype($variable)]) ? $this->_typeMap[gettype($variable)] : PDO::PARAM_STR; + } +} +?> \ No newline at end of file diff --git a/wind/component/db/drivers/mssql/WindMsSql.php b/wind/component/db/drivers/mssql/WindMsSql.php new file mode 100644 index 00000000..af1e8674 --- /dev/null +++ b/wind/component/db/drivers/mssql/WindMsSql.php @@ -0,0 +1,159 @@ + 2010-11-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.drivers.AbstractWindDbAdapter'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMsSql extends AbstractWindDbAdapter { + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#connect() + */ + protected function connect() { + if (!is_resource($this->connection) || ($this->config[IWindDbConfig::FORCE])) { + $host = isset($this->config[IWindDbConfig::PORT]) ? $this->config[IWindDbConfig::HOST] . ':' . $this->config[IWindDbConfig::PORT] : $this->config[IWindDbConfig::HOST]; + $user = $this->config[IWindDbConfig::USER]; + $pass = $this->config[IWindDbConfig::PASS]; + $pconnect = ('true' === $this->config[IWindDbConfig::PCONNECT] ); + $this->connection = $pconnect ? mssql_pconnect($host, $user, $pass) : mssql_connect($host, $user, $pass, $this->config[IWindDbConfig::FORCE]); + $this->changeDB($this->config[IWindDbConfig::NAME]); + } + return $this->connection; + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#query() + */ + public function query($sql) { + $this->query = mssql_query($sql, $this->connection); + $this->error($sql); + return true; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getAffectedRows() + */ + public function getAffectedRows() { + $this->query('SELECT @@ROWCOUNT AS affectedRow'); + $row = $this->getRow(); + return (int) $row['affectedRow']; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getLastInsertId() + */ + public function getLastInsertId() { + $this->query('SELECT @@IDENTITY as insertId'); + $row = $this->getRow(); + return (int) $row['insertId']; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getMetaTables() + */ + public function getMetaTables($schema = '') { + $schema = $schema ? $schema : $this->getSchema(); + if (empty($schema)) { + throw new WindSqlException('', WindSqlException::DB_EMPTY); + } + $this->query("SELECT name,object_id FROM {$schema}.sys.all_objects WHERE type = 'U'"); + return $this->getAllRow(IWindDbConfig::ASSOC); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getMetaColumns() + */ + public function getMetaColumns($table) { + if (empty($table)) { + throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); + } + $this->query('SELECT b.name Field,b.max_length,b.precision,b.scale,b.is_nullable,b.is_identity FROM sys.objects a + INNER JOIN sys.all_columns b ON a.object_id = b.object_id + INNER JOIN sys.types c ON b.system_type_id = c.system_type_id where a.name = ' . $this->escapeString($table)); + return $this->getAllRow(IWindDbConfig::ASSOC); + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#getAllRow() + */ + public function getAllRow($resultIndex = null,$fetch_type = IWindDbConfig::ASSOC) { + if (!is_resource($this->query)) { + throw new WindSqlException('', WindSqlException::DB_QUERY_LINK_EMPTY); + } + if (!in_array($fetch_type, array(1, 2, 3))) { + throw new WindSqlException('', WindSqlException::DB_QUERY_FETCH_ERROR); + } + $result = array(); + while (false !== ($record = mssql_fetch_array($this->query, $fetch_type))) { + if($resultIndex && isset($record[$resultIndex])){ + $result[$record[$resultIndex]] = $record; + }else{ + $result[] = $record; + } + } + return $result; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getRow() + */ + public function getRow($fetch_type = IWindDbConfig::ASSOC) { + return mssql_fetch_array($this->query, $fetch_type); + } + + /** + *@see wind/component/db/base/WindDbAdapter#beginTrans() + */ + public function beginTrans() { + + } + + /** + * @see wind/component/db/base/WindDbAdapter#commitTrans() + */ + public function commitTrans() { + + } + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#close() + */ + public function close() { + if (is_resource($this->connection)) { + mssql_close($this->connection); + } + } + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#dispose() + */ + public function dispose() { + $this->close($this->connection); + $this->connection = null; + $this->query = null; + } + + /** + * 切换数据库 + * @see wind/base/WDbAdapter#changeDB() + * @param string $databse 要切换的数据库 + * @param string|int|resource $key 数据库连接标识 + * @return boolean + */ + public function changeDB($database) { + return mssql_select_db($database, $this->connection); + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#error() + */ + protected function error($sql) { + $this->last_sql = $sql; + return true; + } +} \ No newline at end of file diff --git a/wind/component/db/drivers/mssql/WindMsSqlBuilder.php b/wind/component/db/drivers/mssql/WindMsSqlBuilder.php new file mode 100644 index 00000000..096d0bb4 --- /dev/null +++ b/wind/component/db/drivers/mssql/WindMsSqlBuilder.php @@ -0,0 +1,93 @@ + 2010-11-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.db.drivers.AbstractWindSqlBuilder'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMsSqlBuilder extends AbstractWindSqlBuilder { + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getInsertSql() + */ + public function getInsertSql() { + $sql = sprintf('INSERT %s(%s) VALUES %s', $this->buildFrom(), $this->buildField(), $this->buildData()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getUpdateSql() + */ + public function getUpdateSql() { + $sql = sprintf('UPDATE %s SET %s%s%s', $this->buildFrom(), $this->buildSet(), $this->buildWhere(), $this->buildOrder()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getDeleteSql() + */ + public function getDeleteSql() { + $sql = sprintf('DELETE FROM %s%s%s', $this->buildFrom(), $this->buildWhere(), $this->buildOrder()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getSelectSql() + */ + public function getSelectSql() { + $sql = sprintf('SELECT %s%s FROM %s%s%s%s%s%s', $this->buildDistinct(), $this->buildField(), $this->buildFROM(), $this->buildJoin(), $this->buildWhere(), $this->buildGroup(), $this->buildHaving(), $this->buildOrder()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getReplaceSql() { + return ''; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getLastInsertIdSql() { + return sprintf('SELECT ' . '%s', '@@IDENTITY AS insertId'); + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getAffectedSql($ifquery = true) { + return sprintf('SELECT ' . '%s', '@@ROWCOUNT AS affectedRows'); + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getMetaTableSql() + */ + public function getMetaTableSql($schema) { + $schema = $schema ? $schema . '.' : ''; + return "SELECT name,object_id FROM {$schema}sys.all_objects WHERE type = 'U'"; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindSqlBuilder#getMetaColumnSql() + */ + public function getMetaColumnSql($table) { + if (empty($table)) { + throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); + } + $sql = $this->from('sys.objects', 'a')->field('b.name Field,b.max_length,b.precision,b.scale,b.is_nullable,b.is_identity')->innerJoin('sys.all_columns', 'a.object_id = b.object_id', 'b')->innerJoin('sys.types', 'b.system_type_id = c.system_type_id', 'c')->where('a.name = ? ', $table)->getSelectSql(); + return $sql; + + } + +} \ No newline at end of file diff --git a/wind/component/db/drivers/mysql/WindMySql.php b/wind/component/db/drivers/mysql/WindMySql.php new file mode 100644 index 00000000..981d447a --- /dev/null +++ b/wind/component/db/drivers/mysql/WindMySql.php @@ -0,0 +1,207 @@ + 2010-11-11 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.db.drivers.AbstractWindDbAdapter'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMySql extends AbstractWindDbAdapter { + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#connect() + */ + protected function connect() { + if (!is_resource($this->connection) || $this->config[IWindDbConfig::FORCE]) { + $host = isset($this->config[IWindDbConfig::PORT]) ? $this->config[IWindDbConfig::HOST] . ':' . $this->config[IWindDbConfig::PORT] : $this->config[IWindDbConfig::HOST]; + $user = $this->config[IWindDbConfig::USER]; + $pass = $this->config[IWindDbConfig::PASS]; + $pconnect = ('true' === $this->config[IWindDbConfig::PCONNECT] ); + $this->connection = $pconnect ? mysql_pconnect($host, $user, $pass) : mysql_connect($host, $user, $pass, $this->config[IWindDbConfig::FORCE]); + $this->changeDB($this->config[IWindDbConfig::NAME]); + $this->setCharset($this->config[IWindDbConfig::CHARSET]); + } else { + $this->changeDB($this->config[IWindDbConfig::NAME]); + } + return $this->connection; + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#query() + */ + public function query($sql) { + $this->query = mysql_query($sql, $this->connection); + $this->error($sql); + return true; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getAffectedRows() + */ + public function getAffectedRows() { + return mysql_affected_rows($this->connection); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getLastInsertId() + */ + public function getLastInsertId() { + return mysql_insert_id($this->connection); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getMetaTables() + */ + public function getMetaTables($schema = '') { + $schema = $schema ? $schema : $this->getSchema(); + if (empty($schema)) { + throw new WindSqlException('', WindSqlException::DB_EMPTY); + } + $this->query('SHOW TABLES FROM ' . $schema); + return $this->getAllRow(IWindDbConfig::ASSOC); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getMetaColumns() + */ + public function getMetaColumns($table) { + if (empty($table)) { + throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); + } + $this->query('SHOW COLUMNS FROM ' . $table); + return $this->getAllRow(IWindDbConfig::ASSOC); + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#getAllRow() + */ + public function getAllRow($resultIndex = null,$fetch_type = IWindDbConfig::ASSOC) { + if (!is_resource($this->query)) { + throw new WindSqlException('', WindSqlException::DB_QUERY_LINK_EMPTY); + } + if (!in_array($fetch_type, array(1, 2, 3))) { + throw new WindSqlException('', WindSqlException::DB_QUERY_FETCH_ERROR); + } + $result = array(); + while (false !== ($record = mysql_fetch_array($this->query, $fetch_type))) { + if($resultIndex && isset($record[$resultIndex])){ + $result[$record[$resultIndex]] = $record; + }else{ + $result[] = $record; + } + } + return $result; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getRow() + */ + public function getRow($fetch_type = IWindDbConfig::ASSOC) { + return mysql_fetch_array($this->query, $fetch_type); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#beginTrans() + */ + public function beginTrans() { + if ($this->transCounter == 0) { + $this->query('START TRANSACTION'); + } elseif ($this->transCounter && $this->enableSavePoint) { + $savepoint = 'savepoint_' . $this->transCounter; + $this->query("SAVEPOINT `{$savepoint}`"); + array_push($this->savepoint, $savepoint); + } + ++$this->transCounter; + return true; + } + + /** + *@see wind/component/db/base/WindDbAdapter#commitTrans() + */ + public function commitTrans() { + if ($this->transCounter <= 0) { + throw new WindSqlException('', WindSqlException::DB_QUERY_TRAN_BEGIN); + } + --$this->transCounter; + if ($this->transCounter == 0) { + if ($this->last_errstr) { + $this->query('ROLLBACK'); + } else { + $this->query('COMMIT'); + } + } elseif ($this->enableSavePoint) { + $savepoint = array_pop($this->savepoint); + if ($this->last_errstr) { + $this->query("ROLLBACK TO SAVEPOINT `{$savepoint}`"); + } + } + } + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#close() + */ + public function close() { + if (is_resource($this->connection)) { + mysql_close($this->connection); + } + } + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#dispose() + */ + public function dispose() { + $this->close($this->connection); + $this->connection = null; + $this->query = null; + } + /** + * 取得mysql版本号 + * @param string|int|resource $key 数据库连接标识 + * @return string + */ + public function getVersion() { + return mysql_get_server_info($this->connection); + } + /** + * @param string $charset 字符集 + * @param string | int $key 数据库连接标识 + * @return boolean + */ + public function setCharset($charset) { + $version = (int) substr($this->getVersion(), 0, 1); + if ($version > 4) { + $this->query("SET NAMES '" . $charset . "'"); + } + return true; + } + + /** + * 切换数据库 + * @see wind/base/WDbAdapter#changeDB() + * @param string $databse 要切换的数据库 + * @param string|int|resource $key 数据库连接标识 + * @return boolean + */ + public function changeDB($database) { + return mysql_select_db($database, $this->connection); + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#error() + */ + protected function error($sql) { + $this->last_errstr = mysql_error(); + $this->last_errcode = mysql_errno(); + $this->last_sql = $sql; + if ($this->last_errstr || $this->last_errcode) { + $errInfo = 'This sql statement error has occurred:'.$this->last_sql.'.
'; + $errInfo .= 'Error Message:'.$this->last_errstr.'.
'; + throw new WindSqlException($errInfo, $this->last_errcode); + } + return true; + } + +} \ No newline at end of file diff --git a/wind/component/db/drivers/mysql/WindMySqlBuilder.php b/wind/component/db/drivers/mysql/WindMySqlBuilder.php new file mode 100644 index 00000000..3eebd80f --- /dev/null +++ b/wind/component/db/drivers/mysql/WindMySqlBuilder.php @@ -0,0 +1,99 @@ + 2010-11-11 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.db.drivers.AbstractWindSqlBuilder'); +/** + * mysql常用sql语句组装器 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +final class WindMySqlBuilder extends AbstractWindSqlBuilder { + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getInsertSql() + */ + public function getInsertSql() { + $sql = sprintf('INSERT %s(%s) VALUES %s', $this->buildFrom(), $this->buildField(), $this->buildData()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getUpdateSql() + */ + public function getUpdateSql() { + $sql = sprintf('UPDATE %s SET %s%s%s%s', $this->buildFrom(), $this->buildSet(), $this->buildWhere(), $this->buildOrder(), $this->buildLimit()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getDeleteSql() + */ + public function getDeleteSql() { + $sql = sprintf('DELETE FROM %s%s%s%s', $this->buildFrom(), $this->buildWhere(), $this->buildOrder(), $this->buildLimit()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getSelectSql() + */ + public function getSelectSql() { + $sql = sprintf('SELECT %s%s FROM %s%s%s%s%s%s%s', $this->buildDistinct(), $this->buildField(), $this->buildFROM(), $this->buildJoin(), $this->buildWhere(), $this->buildGroup(), $this->buildHaving(), $this->buildOrder(), $this->buildLimit()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getReplaceSql() { + $sql = sprintf('REPLACE %s(%s) VALUES %s', $this->buildFROM(), $this->buildField(), $this->buildData()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getLastInsertIdSql() { + return sprintf('SELECT ' . '%s', 'LAST_INSERT_ID() AS insertId'); + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getAffectedSql($ifquery = true) { + $rows = $ifquery ? 'FOUND_ROWS()' : 'ROW_COUNT()'; + return sprintf('SELECT ' . '%s', "$rows AS afftectedRows"); + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getMetaTableSql() + */ + public function getMetaTableSql($schema) { + if (empty($schema)) { + throw new WindSqlException('', WindSqlException::DB_EMPTY); + } + return 'SHOW TABLES FROM ' . $schema; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindSqlBuilder#getMetaColumnSql() + */ + public function getMetaColumnSql($table) { + if (empty($table)) { + throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); + } + return 'SHOW COLUMNS FROM ' . $table; + } + +} + diff --git a/wind/component/db/exception/WindDbException.php b/wind/component/db/exception/WindDbException.php new file mode 100644 index 00000000..17a5813e --- /dev/null +++ b/wind/component/db/exception/WindDbException.php @@ -0,0 +1,123 @@ + + * @version $Id$ + * @package + */ +class WindDbException extends WindException { + + /** + * 连接相关的异常 + * @var unknown_type + */ + const DB_CONN_EMPTY = 200; + + const DB_CONN_FORMAT = 201; + + const DB_CONN_NOT_EXIST = 202; + + const DB_CONN_EXIST = 203; + + const DB_CONNECT_NOT_EXIST = 204; + + /** + * 查讯 相关的异常 + * @var unknown_type + */ + const DB_QUERY_EMPTY = 210; + + const DB_QUERY_LINK_EMPTY = 211; + + const DB_QUERY_FIELD_EMPTY = 212; + + const DB_QUERY_FIELD_EXIST = 213; + + const DB_QUERY_FIELD_FORMAT = 214; + + const DB_QUERY_INSERT_DATA = 215; + + const DB_QUERY_UPDATE_DATA = 216; + + const DB_QUERY_CONDTTION_FORMAT = 217; + + const DB_QUERY_GROUP_MATCH = 218; + + const DB_QUERY_LOGIC_MATCH = 219; + + const DB_QUERY_FETCH_ERROR = 220; + + const DB_QUERY_TRAN_BEGIN = 221; + + const DB_QUERY_COMPARESS_ERROR = 222; + + const DB_QUERY_COMPARESS_EXIST = 223; + + const DB_QUERY_WHERE_ERROR = 224; + + const DB_QUERY_JOIN_TYPE_ERROR = 225; + + /** + * 字段异常 + * @var unknown_type + */ + const DB_TABLE_EMPTY = 240; + + const DB_EMPTY = 241; + + const DB_DRIVER_NOT_EXIST = 242; + + const DB_DRIVER_EXIST = 243; + + const DB_BUILDER_NOT_EXIST = 250; + + const DB_BUILDER_EXIST = 251; + + const DB_DRIVER_BUILDER_NOT_MATCH = 252; + + const DB_ADAPTER_NOT_EXIST = 260; + + const DB_ADAPTER_EXIST = 261; + + /** + * 重定义异常类型 + * + * @see WindException::messageMapper() + * @param int $code 异常号 + * @return string 最终输出异常信息的原型 + */ + protected function messageMapper($code) { + $messages = array(self::DB_CONN_EMPTY => 'Database configuration is empty. \'$message\' ', + self::DB_CONN_FORMAT => 'Database configuration format is incorrect. \'$message\' ', + self::DB_CONN_NOT_EXIST => '\'$message\' The identify of the database connection does not exist. ', + self::DB_CONN_EXIST => '\'$message\' The identify of the database connection is aleady exist.', + self::DB_CONNECT_NOT_EXIST => '\'$message\' The database connection does not exist.', + self::DB_QUERY_EMPTY => 'Query is empty. \'$message\'', + self::DB_QUERY_LINK_EMPTY => '\'$message\' Query link is not a validate resource.', + self::DB_QUERY_FIELD_EMPTY => '\'$message\' Query field is empty.', + self::DB_QUERY_FIELD_EXIST => '\'$message\' Query field is not exist.', + self::DB_QUERY_FIELD_FORMAT => 'Inside the field in the query not formatted correctly. \'$message\'', + self::DB_QUERY_INSERT_DATA => 'The new data is empty. \'$message\'', + self::DB_QUERY_UPDATE_DATA => 'The Updated data is empty. \'$message\'', + self::DB_QUERY_CONDTTION_FORMAT => 'The conditions of query are not right. \'$message\'', + self::DB_QUERY_GROUP_MATCH => '\'$message\' Query group does not match.', + self::DB_QUERY_LOGIC_MATCH => '\'$message\' Query logic does not match.', + self::DB_QUERY_FETCH_ERROR => 'The wrong way to obtain the result set. \'$message\'', + self::DB_QUERY_TRAN_BEGIN => 'Transaction has not started. \'$message\'', + self::DB_QUERY_COMPARESS_ERROR => 'Query comparison is incorrect conversion or assembly. \'$message\'', + self::DB_QUERY_COMPARESS_EXIST => 'Comparison does not exist query. \'$message\'', + self::DB_QUERY_WHERE_ERROR => 'Query where is Error. \'$message\'', + self::DB_QUERY_JOIN_TYPE_ERROR => 'The database is wrong type of join query. \'$message\'', + self::DB_TABLE_EMPTY => 'Table is empty. \'$message\'', + self::DB_EMPTY => 'Database is empty. \'$message\'', + self::DB_DRIVER_NOT_EXIST => 'The database driver does not exist. \'$message\'', + self::DB_DRIVER_EXIST => 'The database driver is aleady exist. \'$message\'', + self::DB_BUILDER_NOT_EXIST => 'The database builder does not exist. \'$message\'', + self::DB_BUILDER_EXIST => 'The database builder is aleady exist. \'$message\'', + self::DB_ADAPTER_NOT_EXIST => 'The database adapter does not exist. \'$message\'', + self::DB_ADAPTER_EXIST => 'The database adapter is aleady exist. \'$message\'', + self::DB_DRIVER_BUILDER_NOT_MATCH => '\'$message\' The database driver does not match with the builder. '); + return isset($messages[$code]) ? $messages[$code] : '$message'; + } +} +?> \ No newline at end of file diff --git a/wind/component/db/mysql/WindMysqlPdoAdapter.php b/wind/component/db/mysql/WindMysqlPdoAdapter.php new file mode 100644 index 00000000..b4b1b27d --- /dev/null +++ b/wind/component/db/mysql/WindMysqlPdoAdapter.php @@ -0,0 +1,15 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindMysqlPdoAdapter extends PDO { + + public function setCharset($charset) { + if (!$charset) $charset = 'gbk'; + $this->query("set names " . $this->quote($charset) . ";"); + } +} +?> \ No newline at end of file diff --git a/wind/component/http/cookie/WindCookie.php b/wind/component/http/cookie/WindCookie.php new file mode 100644 index 00000000..7a32ef33 --- /dev/null +++ b/wind/component/http/cookie/WindCookie.php @@ -0,0 +1,94 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * cookie设置操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindCookie{ + + /** + * 设置cookie + * @param string $name cookie名称 + * @param string $value cookie值 + * @param string|int $expires 过期时间 + * @param string $path cookie路径 + * @param strint $domain cookie cookie域 + * @param boolean $encode 使用 MIME base64 对数据进行编码 + * @param boolean $serialize 是否序列化 + * @param string $prefix cookie前缀 + * @param boolean $secure 是否安全连接 + * @param boolean $httponly 是否可以访问脚本设置的cookie + * @return string|string + */ + public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ + if(empty($name)){ + return false; + } + $name = $prefix ? $prefix.$name : $name; + $value = $serialize ? serialize($value) : $value; + $value = $encode ? base64_encode($value) : $value; + $path = $path ? $path : '/'; + $expires = is_int($expires) ? time()+$expires : strtotime($expires); + setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); + return true; + } + + + /** + * 删除cookie + * @param string $name cookie名称 + * @param string $prefix cookie前缀 + * @return boolean + */ + public static function remove($name,$prefix=null){ + $name = $prefix ? $prefix.$name : $name; + if(self::exist($name)){ + self::set($name,'',time()-3600); + unset($_COOKIE[$name]); + } + return true; + } + + /** + * 取得指定名称的cookie + * @param string $name cookie名称 + * @param boolean $encode 是否对cookie值进行过转码 + * @param boolean $encode 是否对cookie值进行过序列化 + * @param string $prefix cookie前缀 + * @return string|boolean + */ + public static function get($name,$encode = false,$serialize = false,$prefix=null){ + $name = $prefix ? $prefix.$name : $name; + if(self::exist($name)){ + $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; + $value = $encode ? base64_decode($value):$value; + return $serialize ? unserialize($value) : $value; + } + return false; + } + + /** + *移除全部cookie + */ + public static function removeAll(){ + $_COOKIE = array(); + } + + /** + * 判断cookie是否存在 + * @param string $name cookie名称 + * @param string $prefix cookie前缀 + */ + public static function exist($name,$prefix=null){ + return isset($_COOKIE[$prefix ? $prefix.$name : $name]); + } +} \ No newline at end of file diff --git a/wind/component/http/cookie/WindCookieObject.php b/wind/component/http/cookie/WindCookieObject.php new file mode 100644 index 00000000..3b774ff1 --- /dev/null +++ b/wind/component/http/cookie/WindCookieObject.php @@ -0,0 +1,185 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 将cookie作为对象操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindCookieObject{ + + /** + * @var string cookie前缀 + */ + public $prefix; + /** + * Cookie 名称 + * + * @var string + */ + protected $name; + + /** + * Cookie 值 + * + * @var string + */ + protected $value; + + /** + * Cookie 过期时间 + * + * @var int + */ + protected $expires; + + /** + * Cookie 域 + * + * @var string + */ + protected $domain; + + /** + * Cookie 路径 + * + * @var string + */ + protected $path; + + /** + * 是否安全套接字 + * + * @var boolean + */ + protected $secure; + /** + * 是否启用编码 + * + * @var boolean + */ + protected $encode; + + /** + * @var string httponly + */ + protected $httponly; + + /** + * @param string $name + * @param string $value + * @param string $domain + * @param int $expires + * @param string $path + * @param bool $secure + * @param bool $httponly + * @param int $prefix + * @param bool $encode + */ + public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ + + $this->name = (string) $name; + $this->value = (string) $value; + $this->domain = (string) $domain; + $this->expires = (null === $expires ? null : (int) $expires); + $this->path = ($path ? $path : '/'); + $this->secure = $secure; + $this->httponly = $httponly; + $this->prefix = (string)$prefix; + $this->encode = $encode; + } + /** + * 获取cookie的名称 + * @return string + */ + public function getName(){ + return $this->prefix ? $this->prefix.$this->name : $this->prefix; + } + /** + *获取cookie值 + * @return string + */ + public function getValue(){ + return $this->value; + } + + /** + * 获取cookie的域 + * @return string + */ + public function getDomain(){ + return $this->domain; + } + /** + * 获取cookie的路径 + * @return string + */ + public function getPath(){ + return $this->path; + } + /** + *获取cookie的过期时间 + * @return int|null + */ + public function getExpirs(){ + return $this->expires; + } + /** + *是否是安全套接字 + * @return boolean + */ + public function isSecure(){ + return $this->secure; + } + /** + * 验证cookie是否过期 + * @param int|null $now 比较时间 + * @return boolean + */ + public function isExpired($now = null){ + return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; + } + + /** + *是否是session cookie + * @return boolean + */ + public function isSessionCookie(){ + return null === $this->expires; + } + + /** + * @return string + */ + public function __toString(){ + return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; + } + + public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ + $cookie = explode(';',$cookiestr); + list($name,$value) = explode('=',array_shift($cookie)); + if(empty($name)){ + return null; + } + $domain=$expires =$path = null; + $httponly = $secure = false; + foreach($cookie as $_cookie){ + list($key,$_value) = explode('=',$_cookie); + switch($key){ + case 'domain':$domain=$_value;break; + case 'path':$path=$_value;break; + case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; + case 'httponly':$httponly=(bool)$_value;break; + case 'secure':$secure=(bool)$_value;break; + } + } + return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); + } +} \ No newline at end of file diff --git a/wind/component/http/session/AbstractWindUserSession.php b/wind/component/http/session/AbstractWindUserSession.php new file mode 100644 index 00000000..a3da2a70 --- /dev/null +++ b/wind/component/http/session/AbstractWindUserSession.php @@ -0,0 +1,57 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 用户定义session存储机制 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +abstract class AbstractWindUserSession { + + /** + * 打开会话存储机制 + * @param string $savePath + * @param string $sessionName + * @return bollean + */ + public static abstract function open($savePath, $sessionName); + /** + * 关闭会话存储存储机制 + * @return bollean + */ + public static abstract function close(); + /** + * 将sessionID对应的数据写到存储 + * @param string $name + * @param mixed $value + */ + public static abstract function write($name,$value); + /** + * 从存储中装载session数据 + * @param mixed $sessid + */ + public static abstract function read($name); + /** + * 对存储系统中的数据进行垃圾收集 + * @param mixed $maxlifetime + */ + public static abstract function gc($maxlifetime); + /** + * 破坏与指定的会话ID相关联的数据 + * @param mixed $name + */ + public static abstract function destroy($name); + + public static function callUserSessionHandler(){ + $className = get_class($this); + session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); + } +} + diff --git a/wind/component/http/session/WindDbSession.php b/wind/component/http/session/WindDbSession.php new file mode 100644 index 00000000..7c1591ae --- /dev/null +++ b/wind/component/http/session/WindDbSession.php @@ -0,0 +1,42 @@ + 2011-3-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.http.session.AbstractWindUserSession'); +/** + * 数据库会话存储机制,可以实现统一登陆 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindDbSession extends AbstractWindUserSession { + + public static function open($savePath, $sessionName){ + return true; + } + + public static function close(){ + return true; + } + + public static function write($name,$value){ + + } + + public static function read($name){ + + } + + public static function gc($maxlifetime){ + + } + + public static function destroy($name){ + + } +} + diff --git a/wind/component/http/session/WindSession.php b/wind/component/http/session/WindSession.php new file mode 100644 index 00000000..1a22ebbd --- /dev/null +++ b/wind/component/http/session/WindSession.php @@ -0,0 +1,370 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * Session会话操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSession implements IteratorAggregate, ArrayAccess, Countable { + /** + * @var boolean 是否自动启动session + */ + public $autostart = false; + /** + * @var int 没有启用cookie传用sessionid + */ + const COOKIE_MODE_NONE = 1; + /** + * @var int 仅仅启用cookiew传递sessionid + */ + const COOKIE_MODE_ONLY = 2; + /** + * @var int 启用cookie传用sessionid + */ + const COOKIE_MODE_ALLOW = 3; + + /** + * @var string 以files格式将session在服务端的保存 + */ + const SESSION_SAVE_FILES = 'files'; + /** + * @var string 以user(用户自定义)格式将session在服务端的保存 + */ + const SESSION_SAVE_USER = 'user'; + + /** + * @var array $read 只读session + */ + public static $read = array(); + /** + * @var array $write 只写session + */ + public static $write = array(); + + public function __construct($autostart = false) { + $this->autostart = $autostart; + } + + public function start() { + if (!$this->isStart() && !$this->getAutoStart()) { + $this->autostart ? $this->setAutoStart(1) : session_start(); + } + } + + /** + * session是否开启 + * @return boolean + */ + public function isStart() { + return '' !== $this->getSessionId(); + } + + /** + * 写入和结束session + */ + public function close() { + if ($this->isStart()) { + session_write_close(); + } + } + + /** + * 获取session + * @param string $name session名称 + * @return string + */ + public function get($name) { + return isset($_SESSION[$name]) ? $_SESSION[$name] : null; + } + + /** + * 设置一个会话 + * @param string $name session名称 + * @param string $value $name对应的值 + * @return string + */ + public function set($name, $value) { + if (empty($name) && empty($value)) { + return false; + } + $_SESSION[$name] = $value; + return true; + } + + /** + * 删除一个会话 + * @param string $name session名称 + * @return string + */ + public function remove($name) { + if (isset($_SESSION[$name])) { + $sessionValue = $_SESSION[$name]; + unset($_SESSION[$name]); + return $sessionValue; + } + return null; + } + + /** + * 判断一个session是否存在 + * @param string $name session名称 + * @return string + */ + public function exist($name) { + return isset($_SESSION[$name]); + } + + /** + * 销毁当前所有会话 + * @return string + */ + public function destroy() { + if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { + setcookie($name, '', time() - 3600); + } + session_unset(); + session_destroy(); + return true; + } + + /** + * 获取当前会话名称 + * @return string + */ + public function getSessionName() { + return session_name(); + } + /** + * 设置当前会话名称 + * @return string $name + */ + public function setSessionName($name) { + return session_name($name); + } + + /** + * 获取当前会话 id + * @return string + */ + public function getSessionId() { + return session_id(); + } + + /** + * 设置当前会话 id + * @param string $id + * @return string + */ + public function setSessionId($id) { + return session_id($id); + } + + /** + * 如果session在服务端的以files方式保存,获取session在服务器端存储路径 + * @return string + */ + public function getSavePath() { + return session_save_path(); + } + + /** + * 如果session在服务端的以files方式保存,设置session在服务器端存储路径 + * @param string $path + * @return string + */ + public function setSavePath($path) { + if (is_dir($path)) { + session_save_path($path); + return true; + } + return false; + } + + /** + * 获取session在服务端的保存方式 + * @return string + */ + public function getSessionSaveMode() { + return session_module_name(); + } + + /** + * 定义session在服务端的保存方式,files意为把sesion保存到一个临时文件里,如果我们想自定义别的方式保存(比如用数据库),则需要把该项设置为user; + * @param unknown_type $mode + * @return string + */ + public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { + return session_module_name($mode); + } + + /** + * 取得session相关的cookie参数 + * @return array + */ + public function getCookieParams() { + return session_get_cookie_params(); + } + + /** + * 设置session相关的cookie参数 + * @param array $cookie + * @return string + */ + public function setCookieParams($cookie = array()) { + extract($this->getCookieParams()); + extract($cookie); + if (isset($httponly)) { + session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); + } else { + session_set_cookie_params($lifetime, $path, $domain, $secure); + } + return true; + } + + /** + * 取得cookie传递sessionid的模式 + * @return number + */ + public function getCookieMode() { + if ('0' === ini_get('session.use_cookies')) { + self::COOKIE_MODE_NONE; + } else if ('0' === ini_get('session.use_only_cookies')) { + return self::COOKIE_MODE_ALLOW; + } else { + return self::COOKIE_MODE_ONLY; + } + return false; + } + + /** + * 设置cookie传递sessionid的模式 + * @param int $mode + * @return string + */ + public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { + if (self::COOKIE_MODE_NONE === $mode) { + ini_set('session.use_cookies', '0'); + } else if (self::COOKIE_MODE_ALLOW === $mode) { + ini_set('session.use_cookies', '1'); + ini_set('session.use_only_cookies', '0'); + } else if (self::COOKIE_MODE_ONLY === $mode) { + ini_set('session.use_cookies', '1'); + ini_set('session.use_only_cookies', '1'); + } else { + return false; + } + return true; + } + + /** + * 获取session进行清理的概率 + * @return number + */ + public function getGCProbability() { + return (int) ini_get('session.gc_probability'); + } + + /** + * 设置session进行清理的概率 + * @param int $probability 概率数 + * @return string|string + */ + public function setGCProbability($probability) { + if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { + return false; + } + ini_set('session.gc_probability', $probability); + ini_set('session.gc_divisor', '100'); + return true; + } + + /** + * 是否允许sessionid通过url参数传递 + * @return boolean + */ + public function getTransSessionID() { + return '1' === ini_get('session.use_trans_sid'); + } + + /** + * 设置是否允许sessionid通过url参数传递 + * @param int $ifTrans + * @return string + */ + public function setTransSessionID($ifTrans = 0) { + return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); + } + + /** + * 获取session存活时间 + * @return number + */ + public function getSessionLifeTime() { + return (int) ini_get('session.gc_maxlifetime'); + } + + /** + * 设置session存活时间 + * @param int $time + * @return number + */ + public function setSessionLifeTime($time = 0) { + return (int) ini_set('session.gc_maxlifetime', (int) $time); + } + + /** + * 是否自动启动session + * @return boolean + */ + public function getAutoStart() { + return '1' === ini_get('session.auto_start'); + } + + /** + * 设置自动启动 + * @param boolean $autostart 是否自动启动 + * @return string + */ + public function setAutoStart($autostart) { + return ini_set('session.auto_start', $autostart ? '1' : '0'); + } + + /** + * 获取当前session的文件名 + * @return string + */ + public function getCurrentSessionFileName(){ + return $this->getSavePath().'/sess_'.$this->getSessionId(); + } + + public function offsetExists($offset) { + $this->exist($offset); + } + + public function offsetSet($offset, $value) { + $this->set($offset, $value); + } + + public function offsetGet($offset) { + $this->get($offset); + } + public function offsetUnset($offset) { + $this->remove($offset); + } + + public function getIterator($name = null) { + return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); + } + + public function count() { + return count($_SESSION); + } +} \ No newline at end of file diff --git a/wind/component/http/transfer/AbstractWindHttp.php b/wind/component/http/transfer/AbstractWindHttp.php new file mode 100644 index 00000000..67996671 --- /dev/null +++ b/wind/component/http/transfer/AbstractWindHttp.php @@ -0,0 +1,280 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +abstract class AbstractWindHttp { + + /** + * @var WindHttp 单例 对象 + */ + protected static $instance = null; + + /** + * @var resource http连接句柄 + */ + protected $httpResource = null; + + /** + * @var string 发送的cookie + */ + protected $cookie = array(); + /** + * @var array 发送的http头 + */ + protected $header = array(); + /** + * @var array 访问的URL地址 + */ + protected $url = ''; + /** + * @var array 发送的数据 + */ + protected $data = array(); + + /** + * @var string 错误信息 + */ + protected $err = ''; + /** + * @var string 错误编码 + */ + protected $eno = 0; + + /** + * @var string 超时时间 + */ + protected $timeout = 0; + + /** + * @var strint 指向$cookie属性 + */ + const _COOKIE = 'cookie'; + /** + * @var string 指向$header属性 + */ + const _HEADER = 'header'; + /** + * @var string 指定$data属性 + */ + const _DATA = 'data'; + + const GET = 'GET'; + const POST = 'POST'; + /** + * 声明受保护的构造函数,避免在类的外界实例化 + * @param string $url + */ + protected function __construct($url = '', $timeout = 5) { + $this->url = $url; + $this->timeout = $timeout; + } + + /** + * 发送post请求 + * @param string $url 请求的url + * @param array $data 请求的数据 + * @param array $header 发送请求的头 + * @param array $cookie 发送的cookie + * @param array $options 额外的请求头 + * @return string 返回页根据请求的响应页面 + */ + public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); + /** + * get方式传值 + * @param string $url 请求的url + * @param array $data 请求的数据 + * @param array $header 发送请求的头 + * @param array $cookie 发送的cookie + * @param array $options 额外的请求头 + * @return string 返回页根据请求的响应页面 + */ + public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); + /** + * 发送请求底层操作 + * @param string $method 请求方式 + * @param array $options 额外的主求参数 + * @return string 返回页根据请求的响应页面 + */ + public abstract function send($method = self::GET, $options = array()); + + /** + * 打开一个http请求 + * @return httpResource http请求指针 + */ + public abstract function open(); + /** + * 发送请求 + * @param string $key 请求的名称 + * @param string $value 请求的值 + * @return boolean + */ + public abstract function request($key, $value = null); + /** + * 以数组格式请求 + * @param array $request + * @return boolean + */ + public abstract function requestByArray($request = array()); + /** + * 响应用户的请求 + * @return string 返回响应 + */ + public abstract function response(); + /** + *响应用户请求,只返回一行数据 + *@return string + */ + public abstract function resonseLine(); + /** + * + * 关闭请求 + */ + public abstract function close(); + /** + * 取得http通信中的错误 + */ + public abstract function getError(); + + /** + * 获取http单例对象,对象唯一访问入口 + * @param string $url 请求的url + * @return WindHttp + */ + public static abstract function getInstance($url = ''); + + /** + * 防止克隆 + */ + protected function __clone() {} + + /** + * 设置url + * @param string|array $url + */ + public function setUrl($url) { + $url && $this->url = $url; + } + /** + * 设置http头 + * @param string $key + * @param string $value + */ + public function setHeader($key, $value) { + $this->header[$key] = $value; + } + /** + * 批量设置http头 + * @param array $datas 实际的http头,数组的值基于key/value形式 + * @return boolean + */ + public function setHeaders($headers = array()) { + return $this->setPropertityValue(self::_HEADER, $headers); + } + /** + * 设置cookie + * @param string $key + * @param string $value + */ + public function setCookie($key, $value) { + $this->cookie[$key] = $value; + } + /** + * 批量设置要传送的cookie + * @param array $cookies 要传送的cookie,数组的值基于key/value形式 + * @return boolean + */ + public function setCookies($cookies = array()) { + return $this->setPropertityValue(self::_COOKIE, $cookies); + } + /** + * 设置data + * @param string $key + * @param string $value + */ + public function setData($key, $value) { + $this->data[$key] = $value; + } + /** + * 批量设置要传送的数据 + * @param array $datas 要传送的数据,数组的值基于key/value形式 + * @return boolean + */ + public function setDatas($datas = array()) { + return $this->setPropertityValue(self::_DATA, $datas); + } + /** + *请空数据,重新发送请求 + */ + public function clear() { + $this->url = array(); + $this->header = array(); + $this->cookie = array(); + $this->data = array(); + } + + /** + * 构请查询字符串 + * @param array $query 查询的关联数组 + * @param string $sep 分隔符 + * @return string + */ + public static function buildQuery($query, $sep = '&') { + if (!is_array($query)) { + return ''; + } + $_query = ''; + foreach ($query as $key => $value) { + $tmp = rawurlencode($key) . '=' . rawurlencode($value); + $_query .= $_query ? $sep . $tmp : $tmp; + } + return $_query; + } + /** + * 以指定分隔符的形式来将数组转化成字符串 + * @param array $array 关联数组 + * @param strin $sep 分隔符 + * @return string + */ + public static function buildArray($array, $sep = ':') { + if (!is_array($array)) { + return array(); + } + $_array = array(); + foreach ($array as $key => $value) { + $_array[] = $key . $sep . $value; + } + return $_array; + } + + /** + * 增量式设置对象的属性的值 + * @param string $propertity 要设置的对象的属性 + * @param array $value 要设置属性的值 + * @return boolean + */ + private function setPropertityValue($propertity, $value = array()) { + if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { + return false; + } + if (!is_array($value)) { + return false; + } + if (empty($this->$propertity)) { + $this->$propertity = $value; + } else { + foreach ($value as $key => $_value) { + $this->$propertity[$key] = $_value; + } + } + return true; + } +} \ No newline at end of file diff --git a/wind/component/http/transfer/WindHttpCurl.php b/wind/component/http/transfer/WindHttpCurl.php new file mode 100644 index 00000000..fe0b5ffd --- /dev/null +++ b/wind/component/http/transfer/WindHttpCurl.php @@ -0,0 +1,147 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +final class WindHttpCurl extends AbstractWindHttp { + + protected function __construct($url = '', $timeout = 5) { + parent::__construct($url, $timeout); + } + + /* + * @see wind/component/http/base/WindHttp#open() + */ + public function open() { + if (null === $this->httpResource) { + $this->httpResource = curl_init(); + } + return $this->httpResource; + } + + /* + * @see wind/component/http/base/WindHttp#request() + */ + public function request($name, $value = null) { + return curl_setopt($this->httpResource, $name, $value); + } + + /* + * @see wind/component/http/base/WindHttp#requestByArray() + */ + public function requestByArray($opt = array()) { + return curl_setopt_array($this->httpResource, $opt); + } + + /* + * @see wind/component/http/base/WindHttp#response() + */ + public function response() { + return curl_exec($this->httpResource); + } + + /** + * @see wind/component/http/base/WindHttp#resonseLine() + */ + public function resonseLine(){ + return ''; + } + + /** + * 释放资源 + */ + public function close() { + if ($this->httpResource) { + curl_close($this->httpResource); + $this->httpResource = null; + } + } + + /* + * @see wind/component/http/base/WindHttp#getError() + */ + public function getError() { + $this->err = curl_error($this->httpResource); + $this->eno = curl_errno($this->httpResource); + return $this->err ? $this->eno . ':' . $this->err : ''; + } + + /* + * @see wind/component/http/base/WindHttp#post() + */ + public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::POST, $option); + } + /* + * @see wind/component/http/base/WindHttp#get() + */ + public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::GET, $option); + } + /* + * @see wind/component/http/base/WindHttp#send() + */ + public function send($method = self::GET, $options = array()) { + if (null === $this->httpResource) { + $this->open(); + } + $this->request(CURLOPT_HEADER, 0); + $this->request(CURLOPT_FOLLOWLOCATION, 1); + $this->request(CURLOPT_RETURNTRANSFER, 1); + $this->request(CURLOPT_TIMEOUT, $this->timeout); + if ($options && is_array($options)) { + $this->requestByArray($options); + } + if (self::GET === $method && $this->data) { + $get = self::buildQuery($this->data, '&'); + $url = parse_url($this->url); + $sep = isset($url['query']) ? '&' : '?'; + $this->url .= $sep . $get; + } + if (self::POST === $method && $this->data) { + $this->request(CURLOPT_POST, 1); + $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); + } + if ($this->cookie && $this->cookie) { + $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); + } + if (empty($this->header)) { + $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); + } + $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); + $this->request(CURLOPT_URL, $this->url); + return $this->response(); + } + + /* + * @see wind/component/http/base/WindHttp#requestByArray() + */ + public static function getInstance($url = '') { + if (null === self::$instance || false === (self::$instance instanceof self)) { + self::$instance = new self($url); + } + return self::$instance; + } + + public function __destruct() { + $this->close(); + } +} + diff --git a/wind/component/http/transfer/WindHttpSocket.php b/wind/component/http/transfer/WindHttpSocket.php new file mode 100644 index 00000000..1eea5979 --- /dev/null +++ b/wind/component/http/transfer/WindHttpSocket.php @@ -0,0 +1,166 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +/** + * socket操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +final class WindHttpSocket extends AbstractWindHttp { + + private $host = ''; + private $port = 0; + private $path = ''; + private $query = ''; + + protected function __construct($url = '', $timeout = 5) { + parent::__construct($url, $timeout); + } + + /* + * @see wind/component/http/base/WindHttp#open() + */ + public function open() { + if (null === $this->httpResource) { + $url = parse_url($this->url); + $this->host = $url['host']; + $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; + $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; + $this->path .= $url['query'] ? '?' . $url['query'] : ''; + $this->query = $url['query']; + $this->httpResource = fsockopen($this->host, $this->port, &$this->eno, &$this->err, $this->timeout); + } + return $this->httpResource; + } + + /* + * @see wind/component/http/base/WindHttp#request() + */ + public function request($name, $value = null) { + return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); + } + + /* + * @see wind/component/http/base/WindHttp#requestByArray() + */ + public function requestByArray($request = array()) { + $_request = ''; + foreach ($request as $key => $value) { + if (is_string($key)) { + $_request .= $key . ': ' . $value; + } + if (is_int($key)) { + $_request .= $value; + } + $_request .= "\n"; + } + fputs($this->httpResource, $_request); + } + /* + * @see wind/component/http/base/WindHttp#resonseLine() + */ + public function response() { + $response = ''; + while (!feof($this->httpResource)) { + $response .= fgets($this->httpResource); + } + return $response; + } + + /** + * @see wind/component/http/base/WindHttp#response() + */ + public function resonseLine(){ + return feof($this->httpResource) ? '' : fgets($this->httpResource); + } + + /* + * @see wind/component/http/base/WindHttp#close() + */ + public function close() { + if ($this->httpResource) { + fclose($this->httpResource); + $this->httpResource = null; + } + } + + /* + * @see wind/component/http/base/WindHttp#getError() + */ + public function getError() { + return $this->err ? $this->eno . ':' . $this->err : ''; + } + /* + * @see wind/component/http/base/WindHttp#post() + */ + public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::POST, $option); + } + /* + * @see wind/component/http/base/WindHttp#get() + */ + public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::GET, $option); + } + /* + * @see wind/component/http/base/WindHttp#send() + */ + public function send($method = self::GET, $options = array()) { + if (self::GET === $method && $this->data) { + $url = parse_url($this->url); + $get = self::buildQuery($this->data, '&'); + $this->url .= ($url['query'] ? '&' : '?') . $get; + } + $this->open(); + $this->setHeader("Host", $this->host); + $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); + if ($this->cookie && $this->cookie) { + $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); + } + if (self::POST === $method && $this->data) { + $data = self::buildQuery($this->data, '&'); + $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); + $this->setHeader('Content-Length', strlen($data)); + } + if ($options) { + $this->setHeaders($options); + } + $this->setHeader('Connection', 'Close'); + $this->request($method . " " . $this->path . " HTTP/1.1"); + $this->requestByArray($this->header); + if ($data) { + $this->request("\n" . $data); + } + $this->request("\n"); + return $this->response(); + } + + /* + * @see wind/component/http/base/WindHttp#getInstance() + */ + public static function getInstance($url = '') { + if (null === self::$instance || false === (self::$instance instanceof self)) { + self::$instance = new self($url); + } + return self::$instance; + } + + public function __destruct() { + $this->close(); + } +} \ No newline at end of file diff --git a/wind/component/http/transfer/WindHttpStream.php b/wind/component/http/transfer/WindHttpStream.php new file mode 100644 index 00000000..abee1faa --- /dev/null +++ b/wind/component/http/transfer/WindHttpStream.php @@ -0,0 +1,178 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +final class WindHttpStream extends AbstractWindHttp { + const HTTP = 'http'; + const HTTPS = 'https'; + const FTP = 'ftp'; + const FTPS = 'ftp'; + const SOCKET = 'socket'; + + /** + * @var string 字节流对象 + */ + private $context = null; + /** + * @var string 通信协议 + */ + private $wrapper = self::HTTP; + protected function __construct($url = '', $timeout = 5) { + parent::__construct($url, $timeout); + $this->context = stream_context_create(); + } + + /** + * 设置通信协议 + * @param string $wrapper + */ + public function setWrapper($wrapper = self::HTTP) { + $this->wrapper = $wrapper; + } + + /* + * @see wind/component/http/base/WindHttp#open() + */ + public function open() { + if (null === $this->httpResource) { + $this->httpResource = fopen($this->url, 'r', false, $this->context); + } + return $this->httpResource; + } + + /* + * @see wind/component/http/base/WindHttp#request() + */ + public function request($name, $value = null) { + return stream_context_set_option($this->context, $this->wrapper, $name, $value); + } + + /* + * @see wind/component/http/base/WindHttp#requestByArray() + */ + public function requestByArray($opt = array()) { + foreach ($opt as $key => $value) { + if (false === $this->request($key, $value)) { + return false; + } + } + return true; + } + + /* + * @see wind/component/http/base/WindHttp#response() + */ + public function response() { + $response = ''; + while (!feof($this->httpResource)) { + $response .= fgets($this->httpResource); + } + return $response; + } + + /** + * @see wind/component/http/base/WindHttp#resonseLine() + */ + public function resonseLine(){ + return feof($this->httpResource) ? '' : fgets($this->httpResource); + } + + /** + * 释放资源 + */ + public function close() { + if ($this->httpResource) { + fclose($this->httpResource); + $this->httpResource = null; + $this->context = null; + } + } + + /* + * @see wind/component/http/base/WindHttp#getError() + */ + public function getError() { + return $this->err ? $this->eno . ':' . $this->err : ''; + } + + /* + * @see wind/component/http/base/WindHttp#post() + */ + public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::POST, $option); + } + /* + * @see wind/component/http/base/WindHttp#get() + */ + public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::GET, $option); + } + /* + * @see wind/component/http/base/WindHttp#send() + */ + public function send($method = self::GET, $options = array()) { + $url = parse_url($this->url); + if (self::GET === $method && $this->data) { + $get = self::buildQuery($this->data, '&'); + $this->url .= ($url['query'] ? '&' : '?') . $get; + } + if (self::POST === $method && $this->data) { + $data = self::buildQuery($this->data, '&'); + $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); + $this->setHeader('Content-Length', strlen($data)); + } + $this->setHeader("Host", $url['host']); + $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); + if ($this->cookie) { + $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); + } + $this->setHeader('Connection', 'Close'); + $this->request('method', $method); + $this->request('timeout', $this->timeout); + + if ($this->header) { + $header = ''; + foreach ($this->header as $key => $value) { + $header .= $key . ': ' . $value . "\n"; + } + $this->request('header', $header); + } + $data && $this->request('content', $data); + $options && is_array($options) && $this->requestByArray($options); + $this->open(); + return $this->response(); + } + + /** + * @see wind/component/http/base/WindHttp#getInstance() + * + */ + public static function getInstance($url = '') { + if (null === self::$instance || false === (self::$instance instanceof self)) { + self::$instance = new self($url); + } + return self::$instance; + } + + public function __destruct() { + $this->close(); + } +} \ No newline at end of file diff --git a/wind/component/log/WindDebug.php b/wind/component/log/WindDebug.php new file mode 100644 index 00000000..6eb0963d --- /dev/null +++ b/wind/component/log/WindDebug.php @@ -0,0 +1,175 @@ + 2010-11-3 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +defined('RUNTIME_START') or define('RUNTIME_START', microtime(true)); +defined('USEMEM_START') or define('USEMEM_START', memory_get_usage()); +/** + * 调试工具 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindDebug { + + /** + * @var array 调试点 + */ + private static $breakpoint = array(); + /** + * @var int 保留的小数位数 + */ + const DECIMAL_DIGITS = 4; + + /** + * @var int 记录内存使用标记 + */ + const MEMORY = 'mem'; + /** + * @var int 记录程序运行时时间使用标记 + */ + const RUN_TIME = 'time'; + /** + * 设置调试点 + * @param string $point 调试点 + */ + public static function setBreakPoint($point = '') { + if (isset(self::$breakpoint[$point])) + return false; + self::$breakpoint[$point][self::RUN_TIME] = microtime(true); + self::$breakpoint[$point][self::MEMORY] = memory_get_usage(); + return true; + } + /** + * 移除调试点 + * @param string $point 调试点 + */ + public static function removeBreakPoint($point = '') { + if ($point) { + if (isset(self::$breakpoint[$point])) + unset(self::$breakpoint[$point]); + } else { + self::$breakpoint = array(); + } + } + + /** + * 取得系统运行所耗内存 + */ + public static function getMemUsage() { + $useMem = memory_get_usage() - USEMEM_START; + return $useMem ? round($useMem / 1024, self::DECIMAL_DIGITS) : 0; + } + + /** + * 取得系统运行所耗时间 + */ + public static function getExecTime() { + $useTime = microtime(true) - RUNTIME_START; + return $useTime ? round($useTime, self::DECIMAL_DIGITS) : 0; + } + + /** + * 获取调试点 + * @param $point + * @param $label + */ + public static function getBreakPoint($point, $label = '') { + if (!isset(self::$breakpoint[$point])) + return array(); + return $label ? self::$breakpoint[$point][$label] : self::$breakpoint[$point]; + } + + /** + * 调试点之间系统运行所耗内存 + * @param string $beginPoint 开始调试点 + * @param string $endPoint 结束调试点 + * @return float + */ + public static function getMemUsageOfp2p($beginPoint, $endPoint = '') { + if (!isset(self::$breakpoint[$beginPoint])) + return 0; + $endMemUsage = isset(self::$breakpoint[$endPoint]) ? self::$breakpoint[$endPoint][self::MEMORY] : memory_get_usage(); + $useMemUsage = $endMemUsage - self::$breakpoint[$beginPoint][self::MEMORY]; + return round($useMemUsage / 1024, self::DECIMAL_DIGITS); + } + + /** + * 调试点之间的系统运行所耗时间 + * @param string $beginPoint 开始调试点 + * @param string $endPoint 结束调试点 + * @return float + */ + public static function getExecTimeOfp2p($beginPoint, $endPoint = '') { + if (!isset(self::$breakpoint[$beginPoint])) + return 0; + $endTime = self::$breakpoint[$endPoint] ? self::$breakpoint[$endPoint][self::RUN_TIME] : microtime(true); + $useTime = $endTime - self::$breakpoint[$beginPoint][self::RUN_TIME]; + return round($useTime, self::DECIMAL_DIGITS); + } + + /** + * 堆栈情况 + * @param array $trace 堆栈引用,如异常 + * @return array + */ + public static function trace($trace = array()) { + $debugTrace = $trace ? $trace : debug_backtrace(); + $traceInfo = array(); + foreach ($debugTrace as $info) { + $info['args'] = self::traceArgs($info['args']); + $file = isset($info['file']) ? $info['file'] : ''; + $line = isset($info['line']) ? $info['line'] : ''; + $str = '[' . date("Y-m-d H:i:m") . '] ' . $file . ' (line:' . $line . ') '; + $str .= $info['class'] . $info['type'] . $info['function'] . '('; + $str .= implode(', ', $info['args']); + $str .= ")"; + $traceInfo[] = $str; + } + return $traceInfo; + } + /** + * 获取系统所加载的文件 + */ + public static function loadFiles() { + return get_included_files(); + } + + public static function debug($message = '', $trace = array(), $begin = '', $end = '') { + $runtime = self::getExecTime(); + $useMem = self::getMemUsage(); + $separate = "
"; + $trace = implode("{$separate}", self::trace($trace)); + $debug = ''; + $debug .= "{$message}{$separate}"; + $debug .= "Runtime:{$runtime}s{$separate}"; + $debug .= "Memory consumption:{$useMem}byte{$separate}"; + $debug .= "Stack conditions:{$separate}{$trace}{$separate}"; + if ($begin && $end) { + $PointUseTime = self::getExecTimeOfp2p($begin, $end); + $PointUseMem = self::getMemUsageOfp2p($begin, $end); + $debug .= "Between points {$begin} and {$end} debugging system conditions:{$separate}"; + $debug .= "Runtime:{$PointUseTime}s{$separate}"; + $debug .= "Memory consumption:{$PointUseMem}byte{$separate}"; + } + return $debug; + } + + private static function traceArgs($args = array()) { + foreach ($args as $key => $arg) { + if (is_array($arg)) + $args[$key] = 'array(' . implode(',', $arg) . ')'; + elseif (is_object($arg)) + $args[$key] = 'class ' . get_class($arg); + else + $args[$key] = $arg; + } + return $args; + } + +} +?> \ No newline at end of file diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php new file mode 100644 index 00000000..8a2ee87f --- /dev/null +++ b/wind/component/log/WindLogger.php @@ -0,0 +1,332 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +class WindLogger extends WindComponentModule { + const LEVEL_INFO = 1; + const LEVEL_TRACE = 2; + const LEVEL_DEBUG = 3; + const LEVEL_ERROR = 4; + const LEVEL_PROFILE = 5; + const TOKEN_BEGIN = 'begin:'; + const TOKEN_END = 'end:'; + /** + * 每次当日志数量达到100的时候,就写入文件一次 + * @var int + */ + private $_autoFlush = 1000; + private $_logs = array(); + private $_logCount = 0; + private $_profiles = array(); + private $_logFile; + private $_maxFileSize = 100; + + /** + * 添加info级别的日志信息 + * @param string $msg + */ + public function info($msg, $type = 'wind.system') { + $this->log($msg, self::LEVEL_INFO, $type); + } + + /** + * 添加trace级别的日志信息 + * @param string $msg + */ + public function trace($msg, $type = 'wind.system') { + $this->log($msg, self::LEVEL_TRACE, $type); + } + + /** + * 添加debug的日志信息 + * @param string $msg + */ + public function debug($msg, $type = 'wind.system') { + $this->log($msg, self::LEVEL_DEBUG, $type); + } + + /** + * 添加Error级别的日志信息 + * @param string $msg + */ + public function error($msg, $type = 'wind.core') { + $this->log($msg, self::LEVEL_ERROR, $type); + } + + /** + * @param $msg + * @param $type + */ + public function profileBegin($msg, $type = 'wind.core') { + $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type); + } + + /** + * @param $msg + * @param $type + */ + public function profileEnd($msg, $type = 'wind.core') { + $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type); + } + + /** + * 记录日志信息,但不写入文件 + * @param string $msg 日志信息 + * @param const $logType 日志类别 + */ + public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { + $this->_logCount >= $this->_autoFlush && $this->flush(); + if ($level === self::LEVEL_PROFILE) + $this->_logs[] = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); + elseif ($level === self::LEVEL_DEBUG) + $this->_logs[] = $this->_build($msg, $level, $type, microtime(true)); + else + $this->_logs[] = $this->_build($msg, $level, $type); + $this->_logCount++; + } + + /** + * 将记录的日志列表信息写入文件 + * @param string $dst 日志被记录于何处 + * @return boolean + */ + public function flush() { + if (empty($this->_logs)) return false; + if (!$fileName = $this->_getFileName()) return false; + Wind::import('WIND:component.utility.WindFile'); + WindFile::write($fileName, join("", $this->_logs), 'a'); + $this->_logs = array(); + $this->_logCount = 0; + return true; + } + + /** + * 返回内存使用量 + * @param $peak | 是否是内存峰值 + * @return int + */ + public function getMemoryUsage($peak = true) { + if ($peak && function_exists('memory_get_peak_usage')) + return memory_get_peak_usage(); + elseif (function_exists('memory_get_usage')) + return memory_get_usage(); + $pid = getmypid(); + if (strncmp(PHP_OS, 'WIN', 3) === 0) { + exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); + return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; + } else { + exec("ps -eo%mem,rss,pid | grep $pid", $output); + $output = explode(" ", $output[0]); + return isset($output[1]) ? $output[1] * 1024 : 0; + } + } + + /** + * 组装日志信息 + * @param string $msg 日志信息 + * @param const $logType 日志类别 + * @return string + */ + private function _build($msg, $level, $type, $timer = 0, $mem = 0) { + $msg = stripslashes(str_replace("
", "\r\n", trim($msg))); + switch ($level) { + case self::LEVEL_INFO: + $msg .= "\t(" . $type . ")"; + $result = $this->_buildInfo($msg); + break; + case self::LEVEL_ERROR: + $msg .= "\t(" . $type . ")"; + $result = $this->_buildError($msg); + break; + case self::LEVEL_DEBUG: + $msg .= "\t(" . $type . " timer: " . sprintf('%0.5f', ($timer - DEBUG_TIME)) . ")\r\n"; + $result = $this->_buildDebug($msg); + break; + case self::LEVEL_TRACE: + $msg .= "\t(" . $type . ")"; + $result = $this->_buildTrace($msg); + break; + case self::LEVEL_PROFILE: + $result = $this->_buildProfile($msg, $type, $timer, $mem); + break; + default: + break; + } + return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; + } + + /** + * @param $msg + * @param $type + * @param $timer + * @param $mem + */ + private function _buildProfile($msg, $type, $timer, $mem) { + $_msg = ''; + if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { + $_token = substr($msg, strlen(self::TOKEN_BEGIN)); + $_token = substr($_token, 0, strpos($_token, ':')); + $this->_profiles[] = array( + $_token, + substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), + $type, + $timer, + $mem); + } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { + $_msg = "PROFILE! Message: \r\n"; + $_token = substr($msg, strlen(self::TOKEN_END)); + $_token = substr($_token, 0, strpos($_token, ':')); + foreach ($this->_profiles as $key => $profile) { + if ($profile[0] !== $_token) continue; + if ($profile[1]) + $_msg .= $profile[1] . "\r\n"; + else + $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; + $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; + break; + } + unset($this->_profiles[$key]); + } + return $_msg; + } + + /** + * 组装info级别的信息输出格式 + * + * [2011-01-24 10:00:00] INFO! Message: $msg + * + * @param string $msg + * @return string + */ + private function _buildInfo($msg) { + return "INFO! Message: " . $msg; + } + + /** + * 组装堆栈trace的信息输出格式 + * + * [2011-01-24 10:00:00] TRACE! Message: $msg + * #1 trace1 + * #2 trace2 + * + * @param string $msg + * @return string + */ + private function _buildTrace($msg) { + return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); + } + + /** + * 组装debug信息输出 + * + * [2011-01-24 10:00:00] DEBUG! Message: $msg + * #1 trace1 + * #2 trace2 + * + * @param string $msg + * @return string + */ + private function _buildDebug($msg) { + return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); + } + + /** + *组装Error信息输出 + * + * [2011-01-24 10:00:00] ERROR! Message: $msg + * #1 trace1 + * #2 trace2 + * + * @param string $msg + * @return string + */ + private function _buildError($msg) { + return 'ERROR! Message: ' . $msg; + } + + /** + * 错误堆栈信息的获取及组装输出 + * + * #1 trace + * #2 trace + * + * @return string + */ + private function _getTrace() { + $num = 0; + $info[] = 'Stack trace:'; + $traces = debug_backtrace(false); + foreach ($traces as $traceKey => $trace) { + if ($num >= 7) break; + if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; + $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; + $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; + if ($function == 'WindBase::log') continue; + $args = array_map(array( + $this, + '_buildArg'), $trace['args']); + $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; + } + return $info; + } + + /** + * 组装输出的trace中的参数组装 + * @param mixed $arg + */ + private function _buildArg($arg) { + switch (gettype($arg)) { + case 'array': + return 'Array'; + break; + case 'object': + return 'Object ' . get_class($arg); + break; + default: + return "'" . $arg . "'"; + break; + } + } + + /** + * 取得日志文件名 + * @return string + */ + private function _getFileName() { + $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; + $_logfile = $this->_logFile; + if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { + $counter = 0; + do { + $counter ++; + $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); + } while (is_file($_newFile)); + @rename($_logfile, $_newFile); + } + return $_logfile; + } + + public function __destruct() { + $this->flush(); + } + + /** + * @param field_type $_logFile + */ + public function setLogFile($logFile) { + $this->_logFile = $logFile; + } + + /** + * @param field_type $_maxFileSize + */ + public function setMaxFileSize($maxFileSize) { + $this->_maxFileSize = (int)$maxFileSize; + } +} + + \ No newline at end of file diff --git a/wind/component/mail/WindMail.php b/wind/component/mail/WindMail.php new file mode 100644 index 00000000..b3116b3f --- /dev/null +++ b/wind/component/mail/WindMail.php @@ -0,0 +1,898 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 邮件发送类 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMail { + + /** + * @var string 邮件内容仅文本 + */ + const ONLYTEXT = 1; + /** + * @var string 邮件内容仅HTML + */ + const ONLYHTML = 2; + /** + * @var string 邮件内容是文本和HTML + */ + const TEXTHTML = 3; + /** + * @var string 邮件内容有附件 + */ + const ATTACH = 4; + /** + * @var string 无邮件内容 + */ + const NONE = 5; + + /** + * @var array 邮件收件人 + */ + private $recipients = array(); + /** + * @var array 邮件头 + */ + private $mailHeader = array(); + /** + * @var array 邮件边界线 + */ + private $boundary = ''; + /** + * @var array 邮件附件 + */ + private $attachment = array(); + /** + * @var string 邮件字符集 + */ + private $charSet = 'gbk'; + + /** + * @var string 邮件mime类型 + */ + private $contentType = self::MIME_TEXT; + /** + * @var string 邮件消息体html展现方式 + */ + private $bodyHtml = ''; + /** + * @var string 邮件消息体文本展现方式 + */ + private $bodyText = ''; + /** + * @var string 是否是内嵌资源 + */ + private $embed = false; + /** + * @var string 邮件编码方式 + */ + private $encode = self::ENCODE_BASE64; + //常用邮件MIME + const CRLF = "\n"; + const TO = 'To'; + const CC = 'Cc'; + const BCC = 'Bcc'; + const FROM = 'From'; + const SUBJECT = 'Subject'; + const MESSAGEID = 'Message-Id'; + const CONTENTTYPE='Content-Type'; + const CONTENTENCODE = 'Content-Transfer-Encoding'; + const CONTENTID = 'Content-ID'; + const CONTENTPOSITION = 'Content-Disposition'; + const CONTENTDESCRIPT = 'Content-Description'; + const CONTENTLOCATION = 'Content-Location'; + const CONTENTLANGUAGE='Content-Language'; + const DATE = 'Date'; + //邮件MIME类型 + const MIME_OCTETSTREAM = 'application/octet-stream'; + const MIME_TEXT = 'text/plain'; + const MIME_HTML = 'text/html'; + const MIME_ALTERNATIVE = 'multipart/alternative'; + const MIME_MIXED = 'multipart/mixed'; + const MIME_RELATED = 'multipart/related'; + //邮件编码 + const ENCODE_7BIT = '7bit'; + const ENCODE_8BIT = '8bit'; + const ENCODE_QP = 'quoted-printable'; + const ENCODE_BASE64 = 'base64'; + const ENCODE_BINARY = 'binary'; + + const DIS_ATTACHMENT = 'attachment'; + const DIS_INLINE = 'inline'; + const LINELENGTH = 72; + + const SEND_SMTP = 'smtp'; + const SEND_PHP = 'php'; + const SEND_SEND = 'send'; + + public function send($type = self::SEND_SMTP,$config = array()){ + if(!in_array($type,array(self::SEND_SMTP,self::SEND_PHP,self::SEND_SEND))){ + throw new WindException('There is no way that you want to send e-mail'); + } + $class = Wind::import('Wind:component.mail.sender.Wind'.ucfirst($type).'Mail'); + /* @var $sender IWindSendMail */ + $sender = new $class($config); + $sender->send($this); + return true; + } + /** + * 创建邮件头 + * @return string + */ + public function createHeader(){ + $header = ''; + if(!isset($this->mailHeader[self::CONTENTTYPE])){ + $this->setContentType(null); + } + foreach($this->mailHeader as $key=>$value){ + $header .= $this->headerLine($key,$value); + } + return $header.self::CRLF; + } + + /** + * 创建邮件消息体 + * @return string + */ + public function createBody(){ + $mime = $this->getMimeType(); + if(self::ONLYTEXT === $mime){ + return self::encode($this->getBodyText(),$this->encode); + }elseif(self::ONLYHTML === $mime){ + return $body .= self::encode($this->getBodyHtml(),$this->encode).self::CRLF; + }elseif(self::TEXTHTML === $mime){ + $boundary = $this->boundaryLine(); + $body = $boundary.$this->getTextHeader().self::encode($this->getBodyText(),$this->encode).self::CRLF; + $body .= $boundary.$this->getHtmlHeader().self::encode($this->getBodyHtml(),$this->encode).self::CRLF; + return $body .= $this->boundaryEndLine(); + }elseif(self::ATTACH === $mime){ + $boundary = $this->boundaryLine(); + $body = ''; + if('' != ($text = $this->getBodyText())){ + $body .= $boundary.$this->getTextHeader().self::encode($text,$this->encode).self::CRLF; + } + if('' != ($html = $this->getBodyHtml())){ + $body .= $boundary.$this->getHtmlHeader().self::encode($html,$this->encode).self::CRLF; + } + $body .= $this->attach().self::CRLF; + return $body .= $this->boundaryEndLine(); + } + return ''; + } + + + + /** + * 设置邮件头 + * @param string $name 邮件头名称 + * @param string $value 邮件头对应的值 + * @param boolean $append 是否是追加 + * @return boolean + */ + public function setMailHeader($name, $value,$append = true) { + $value = is_array($value) ? $value : array($value); + if(false === $append){ + $this->mailHeader[$name] = $value; + return true; + } + if (!isset($this->mailHeader[$name])) { + $this->mailHeader[$name] = $value; + }else{ + foreach($value as $key=>$value){ + if(is_string($key)){ + $this->mailHeader[$name][$key]=$value; + }else{ + $this->mailHeader[$name][]=$value; + } + } + } + return true; + } + + /** + * 设置发件人 + * @param string $email 发件人邮箱 + * @param string $name 发件人姓名 + */ + public function setFrom($email, $name = null) { + $value = $name ? array($name => $email) : array($email); + $this->setMailHeader(self::FROM, $value,false); + } + + /** + * 设置收件人 + * @param string $email 收件人邮箱 + * @param string $name 收件人姓名 + */ + public function setTo($email, $name = null) { + $value = $name ? array($name => $email) : array($email); + $this->setMailHeader(self::TO, $value); + } + /** + * 设置抄送人 + * @param string $email 抄送人邮箱 + * @param string $name 抄送人姓名 + */ + public function setCc($email, $name = null) { + $value = $name ? array($name => $email) : array($email); + $this->setMailHeader(self::CC, $value); + } + /** + * 设置暗送人 + * @param string $email 暗送人邮箱 + * @param string $name 暗送人姓名 + */ + public function setBcc($email, $name = null) { + $value = $name ? array($name => $email) : array($email); + $this->setMailHeader(self::BCC, $value); + } + + /** + * 设置邮件主题 + * @param string $subject 主题 + */ + public function setSubject($subject) { + $this->setMailHeader(self::SUBJECT, $subject,false); + } + + /** + * 设置邮件日期 + * @param boolean $ifchinese 是否是中国日期 + */ + public function setDate($date = null,$ifchinese = true){ + if(!$date){ + Wind::import ( 'WIND:component.utility.date.WindDate' ); + $date = $ifchinese ? WindDate::getChinaDate() : WindDate::getRFCDate(); + } + $this->setMailHeader(self::DATE,$date ); + } + + /** + *设置邮件消息ID + */ + public function setMessageId() { + $this->setMailHeader(self::MESSAGEID, '<' . $this->createMessageId() . '>'); + } + + /** + * 设置邮件html展示内容 + * @param string $bodyHtml + */ + public function setBodyHtml($bodyHtml){ + $this->bodyHtml = $bodyHtml; + } + /** + * 设置邮件文本展示内容 + * @param string $bodyText + */ + public function setBodyText($bodyText){ + $this->bodyText = $bodyText; + } + + /** + * 设置邮件类型 + * @param string $type + */ + public function setContentType($type = null){ + if(!$type){ + $mime = $this->getMimeType(); + if(self::ONLYTEXT === $mime){ + $type = self::MIME_TEXT; + }elseif(self::ONLYHTML === $mime){ + $type = self::MIME_HTML; + }elseif(self::TEXTHTML === $mime){ + $type = self::MIME_ALTERNATIVE; + }elseif(self::ATTACH === $mime && $this->embed){ + $type = self::MIME_RELATED; + }elseif(self::ATTACH === $mime && !$this->embed){ + $type = self::MIME_MIXED; + }else{ + $type = self::MIME_TEXT; + } + } + if(self::MIME_TEXT == $type || self::MIME_HTML == $type){ + $contentType = sprintf("%s; charset=\"%s\"", $type, $this->charSet); + }elseif(self::MIME_RELATED == $type){ + $this->setBoundary(); + $contentType = sprintf("%s;%s type=\"text/html\";%s boundary=\"%s\"", self::MIME_RELATED, self::CRLF, self::CRLF, $this->getBoundary()); + }else{ + $this->setBoundary(); + $contentType = sprintf("%s;%s boundary=\"%s\"",$type,self::CRLF,$this->getBoundary()); + } + $this->contentType = $type; + $this->setMailHeader(self::CONTENTTYPE,$contentType,false); + } + + /** + * 设置是否是内嵌资源 + * @param boolean $embed + */ + public function setEmbed($embed = false){ + $this->embed = $embed; + } + + /** + * 设置邮件编码 + * @param string $encode + */ + public function setContentEncode($encode = self::ENCODE_BASE64){ + $this->encode = $encode; + $this->setMailHeader(self::CONTENTENCODE,$encode); + } + + /** + * 设置邮件字符 + * @param string $charset + */ + public function setCharset($charset){ + $this->charSet = $charset; + } + + /** + * 设置附件 + * @param string $stream 附件名或者附件内容 + * @param string $mime 附件类型 + * @param string $disposition 附件展现方式 + * @param string $encode 附件编码 + * @param string $filename 文件名 + * @param string $cid 内容ID + */ + public function setAttachment($stream, $mime = self::MIME_OCTETSTREAM, $disposition = self::DIS_ATTACHMENT, $encode = self::ENCODE_BASE64,$filename = null,$cid = 0){ + + $this->attachment[] = array( + $stream, + $mime, + $disposition, + $encode, + $filename, + $cid + ); + } + + /** + * 设置边界线 + */ + public function setBoundary() { + $this->boundary = '==_' . md5(microtime(true) . uniqid()); + } + + public function getMailHeader($name = null,$subname = null){ + if(!$name){ + return $this->mailHeader; + } + if(!isset($this->mailHeader[$name])){ + return ''; + } + $header = $this->mailHeader[$name]; + if(!$subname || !isset($header[$subname])){ + return $header; + } + return $header[$subname]; + } + + /** + * 取得发件人 + * @return array + */ + public function getFrom() { + if(isset($this->mailHeader[self::FROM])){ + $from = $this->mailHeader[self::FROM]; + return is_array($from) ? array_shift($from) : $from; + } + return ''; + } + /** + * 取得收件人 + * @return array + */ + public function getTo() { + return isset($this->mailHeader[self::TO]) ? $this->mailHeader[self::TO] : array(); + } + + /** + * 取得抄送的对象 + * @return array + */ + public function getCc() { + return isset($this->mailHeader[self::CC]) ? $this->mailHeader[self::CC] : array(); + } + + /** + * 取得暗送对象 + * @return array + */ + public function getBcc() { + return isset($this->mailHeader[self::BCC]) ? $this->mailHeader[self::BCC] : array(); + } + + /** + * 取得邮件主题 + * @return array + */ + public function getSubject() { + if(isset($this->mailHeader[self::SUBJECT])){ + $subject = $this->mailHeader[self::SUBJECT]; + return is_array($subject) ? array_shift($subject) : $subject; + } + return ''; + } + + /** + * 取得边界符 + * @return array + */ + public function getBoundary() { + return $this->boundary; + } + + /** + * 取得mime类型 + * @return string + */ + public function getMimeType(){ + if('' != $this->getBodyText() && '' == $this->getBodyHtml() && false == $this->hasAttachment()){ + return self::ONLYTEXT; + }elseif('' == $this->getBodyText() && '' != $this->getBodyHtml() && false == $this->hasAttachment()){ + return self::ONLYHTML; + }elseif('' != $this->getBodyText() && '' != $this->getBodyHtml() && false == $this->hasAttachment()){ + return self::TEXTHTML; + }elseif($this->hasAttachment()){ + return self::ATTACH; + }else{ + return self::NONE; + } + return 0; + } + + /** + * 取得真实的收件人 + * @return array + */ + public function getRecipients() { + $this->buildRecipients($this->getTo()); + $this->buildRecipients($this->getCc()); + $this->buildRecipients($this->getBcc()); + return $this->recipients; + } + + /** + * 取得消息中的html + * @return string + */ + public function getBodyHtml(){ + return trim($this->bodyHtml); + } + + /** + * 取得消息中的文本 + * @return string + */ + public function getBodyText(){ + return trim($this->bodyText); + } + + /** + * 取得文本头 + * @return string + */ + public function getTextHeader(){ + $textHeader = self::CONTENTTYPE.': text/plain; charset='.$this->charSet.self::CRLF; + return $textHeader .= self::CONTENTENCODE.': '.$this->encode.self::CRLF; + } + + /** + * 取得html头 + * @return string + */ + public function getHtmlHeader(){ + $htmlHeader = self::CONTENTTYPE.': text/html; charset='.$this->charSet.self::CRLF; + return $htmlHeader .= self::CONTENTENCODE.': '.$this->encode.self::CRLF.self::CRLF; + } + + /** + * 取得附件的头 + * @param string $mime mime头类型 + * @param string $name 文件名 + * @param string $encode 编码 + * @param string $disposition 附件展现方式 + * @param string $cid 内容ID + * @return string + */ + public function getAttachHeader($mime,$name,$encode = self::ENCODE_BASE64,$disposition = 'attachment',$cid = 0){ + $attachHeader = sprintf(self::CONTENTTYPE.": %s; name=\"%s\"%s", $mime, $name, self::CRLF); + $attachHeader .= sprintf(self::CONTENTENCODE.": %s%s", $encode, self::CRLF); + if($disposition == 'inline') { + $attachHeader .= sprintf(self::CONTENTID.": <%s>%s", $cid, self::CRLF); + } + return $attachHeader .= sprintf(self::CONTENTPOSITION.": %s; filename=\"%s\"%s%s", $disposition, $name, self::CRLF,self::CRLF); + } + + /** + * 获到文件中的内容 + * @param string $file 文件名 + * @param string $encode 编码方式 + * @return string + */ + public function getStreamFromFile ($file, $encode = self::ENCODE_BASE64) { + $fp = fopen($file, 'rb'); + $magic_quotes = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + $steam = fread($fp,filesize($file)); + fclose($fp); + set_magic_quotes_runtime($magic_quotes); + return $steam; + } + + /** + * 上传附件 + * @return string + */ + public function attach() { + $attach = ''; + foreach($this->attachment as $key => $value){ + list($stream,$mime,$disposition,$encode,$filename,$cid) = $value; + $filename = $filename ? $filename : (is_file($stream) ? $stream : 'attachment_'.$key); + $attachHeader = $this->getAttachHeader($mime,$filename,$encode,$disposition,$cid); + $boundary = $this->boundaryLine(); + if(is_file($stream)){ + $stream = $this->getStreamFromFile($stream); + } + $attach .= $boundary.$attachHeader.$this->encode($stream,$encode).self::CRLF; + } + return $attach; + } + + /** + * 过滤mime头 + * @param string $header + * @return string + */ + public function filterHeader($header) { + return strtr(trim($header),array("\r"=>'',"\n"=>'',"\r\n"=>'')); + } + + /** + * 获取边界线 + * @return string + */ + public function boundaryLine() { + return self::CRLF . '--' . $this->getBoundary() . self::CRLF; + } + + /** + * 获取结束边界线 + * @return string + */ + public function boundaryEndLine() { + return self::CRLF . '--' . $this->getBoundary() . '--' . self::CRLF; + } + + /** + * 对字符进行编码 + * @param string $string 要编码的字符串 + * @param string $encode 编码的方式 + * @return string + */ + public function encode($string,$encode = self::ENCODE_BASE64){ + switch($encode) { + case self::ENCODE_BASE64: return self::encodeBase64($string); + case self::ENCODE_7BIT: + case self::ENCODE_8BIT: + case self::ENCODE_BINARY:return $string; + case self::ENCODE_QP:return self::EncodeQP($string); + default:return $string; + } + return $string.self::CRLF; + } + + /** + * 对mime头进行编码 + * @param string $string 要编码的字符串 + * @param string $encode 编码的方式 + * @return string + */ + public function encodeHeader($header,$encode=self::ENCODE_BASE64){ + switch($encode) { + case self::ENCODE_BASE64: return self::encodeBase64Header($this->filterHeader($header),$this->charSet); + case self::ENCODE_7BIT: + case self::ENCODE_8BIT: + case self::ENCODE_BINARY:return $header; + case self::ENCODE_QP:return self::encodeQpHeader($this->filterHeader($header),$this->charSet); + default:return $header; + } + return $header; + } + /** + * 对mime头进行quoted-printable编码 + * @param string $string 要编码的字符串 + * @param string $chunklen 分割字符串中每块的长度 + * @param string $end 每个字符块后面的填充符 + * @return string + */ + public static function encodeQpHeader($string, $charset,$chunkLen = self::LINELENGTH,$end = self::CRLF){ + $prefix = sprintf('=?%s?Q?', $charset); + $chunkLen = $chunkLen-strlen($prefix)-3; + $string = self::_encodeQp($string); + $string = strtr($string,array('_'=>'5F',' '=>'=20','?'=>'=3F')); + $lines[] = $tmp = ''; + while(strlen($string) > 0) { + $culLen = max(count($lines)-1, 0); + $token = self::getNextQpToken($string); + $string = substr($string, strlen($token)); + $tmp .= $token; + if('=20' == $token) { + if(strlen($lines[$culLen].$tmp) > $chunkLen) { + $lines[$culLen+1] = $tmp; + } else { + $lines[$culLen] .= $tmp; + } + $tmp = ''; + } + if(0 == strlen($string)) { + $lines[$culLen] .= $tmp; + } + } + for($i = 0; $i < count($lines); $i++) { + $lines[$i] = ' '.$prefix.$lines[$i].'?='; + } + return trim(implode($end, $lines)); + } + /** + * 对mime头进行base64编码 + * @param string $string 要编码的字符串 + * @param string $chunklen 分割字符串中每块的长度 + * @param string $end 每个字符块后面的填充符 + * @return string + */ + public static function encodeBase64Header($string,$charset, $chunkLen = self::LINELENGTH,$end = self::CRLF){ + $prefix = '=?' . $charset . '?B?'; + $suffix = '?='; + $length = $chunkLen - strlen($prefix) - strlen($suffix); + $encodedString = self::encodeBase64($string, $length, $end); + $encodedString = $prefix . strtr($encodedString,array($end=>$suffix . $end . ' ' . $prefix)) . $suffix; + return $encodedString; + } + /** + * quoted-printable编码 + * @param string $string 要编码的字符串 + * @param string $chunklen 分割字符串中每块的长度 + * @param string $end 每个字符块后面的填充符 + * @return string + */ + public static function encodeQp($string, $chunklen = self::LINELENGTH,$end = self::CRLF){ + $endodeString = ''; + $string = self::_encodeQp($string); + while ($string) { + $plen = $chunklen < ($plen = strlen($string)) ? $chunklen : $plen; + if (false !== ($pos = strrpos(substr($string, 0, $plen), '=')) && $pos >= $plen - 2) { + $plen = $pos; + } + 0 < $plen && ' ' == $string[$plen - 1] && --$plen; + $endodeString .= substr($string, 0, $plen) . '=' . $end; + $string = substr($string, $plen); + } + $endodeString = rtrim($endodeString, $end); + $endodeString = rtrim($endodeString, '='); + return $endodeString; + } + /** + * base64编码 + * @param string $string 要编码的字符串 + * @param string $chunklen 分割字符串中每块的长度 + * @param string $end 每个字符块后面的填充符 + * @return string quoted-printable + */ + public static function encodeBase64($string,$chunklen = self::LINELENGTH,$end = self::CRLF){ + return chunk_split(base64_encode($string), $chunklen, $end); + } + /** + * quoted-printable 对照表 + * @return string + */ + public static function getQpTable(){ + return array( + "\x00"=>"=00","\x01"=>"=01","\x02"=>"=02","\x03"=>"=03", + "\x04"=>"=04","\x05"=>"=05","\x06"=>"=06","\x07"=>"=07", + "\x08"=>"=08","\x09"=>"=09","\x0A"=>"=0A","\x0B"=>"=0B", + "\x0C"=>"=0C","\x0D"=>"=0D","\x0E"=>"=0E","\x0F"=>"=0F", + "\x10"=>"=10","\x11"=>"=11","\x12"=>"=12","\x13"=>"=13", + "\x14"=>"=14","\x15"=>"=15","\x16"=>"=16","\x17"=>"=17", + "\x18"=>"=18","\x19"=>"=19","\x1A"=>"=1A","\x1B"=>"=1B", + "\x1C"=>"=1C","\x1D"=>"=1D","\x1E"=>"=1E","\x1F"=>"=1F", + "\x7F"=>"=7F","\x80"=>"=80","\x81"=>"=81","\x82"=>"=82", + "\x83"=>"=83","\x84"=>"=84","\x85"=>"=85","\x86"=>"=86", + "\x87"=>"=87","\x88"=>"=88","\x89"=>"=89","\x8A"=>"=8A", + "\x8B"=>"=8B","\x8C"=>"=8C","\x8D"=>"=8D","\x8E"=>"=8E", + "\x8F"=>"=8F","\x90"=>"=90","\x91"=>"=91","\x92"=>"=92", + "\x93"=>"=93","\x94"=>"=94","\x95"=>"=95","\x96"=>"=96", + "\x97"=>"=97","\x98"=>"=98","\x99"=>"=99","\x9A"=>"=9A", + "\x9B"=>"=9B","\x9C"=>"=9C","\x9D"=>"=9D","\x9E"=>"=9E", + "\x9F"=>"=9F","\xA0"=>"=A0","\xA1"=>"=A1","\xA2"=>"=A2", + "\xA3"=>"=A3","\xA4"=>"=A4","\xA5"=>"=A5","\xA6"=>"=A6", + "\xA7"=>"=A7","\xA8"=>"=A8","\xA9"=>"=A9","\xAA"=>"=AA", + "\xAB"=>"=AB","\xAC"=>"=AC","\xAD"=>"=AD","\xAE"=>"=AE", + "\xAF"=>"=AF","\xB0"=>"=B0","\xB1"=>"=B1","\xB2"=>"=B2", + "\xB3"=>"=B3","\xB4"=>"=B4","\xB5"=>"=B5","\xB6"=>"=B6", + "\xB7"=>"=B7","\xB8"=>"=B8","\xB9"=>"=B9","\xBA"=>"=BA", + "\xBB"=>"=BB","\xBC"=>"=BC","\xBD"=>"=BD","\xBE"=>"=BE", + "\xBF"=>"=BF","\xC0"=>"=C0","\xC1"=>"=C1","\xC2"=>"=C2", + "\xC3"=>"=C3","\xC4"=>"=C4","\xC5"=>"=C5","\xC6"=>"=C6", + "\xC7"=>"=C7","\xC8"=>"=C8","\xC9"=>"=C9","\xCA"=>"=CA", + "\xCB"=>"=CB","\xCC"=>"=CC","\xCD"=>"=CD","\xCE"=>"=CE", + "\xCF"=>"=CF","\xD0"=>"=D0","\xD1"=>"=D1","\xD2"=>"=D2", + "\xD3"=>"=D3","\xD4"=>"=D4","\xD5"=>"=D5","\xD6"=>"=D6", + "\xD7"=>"=D7","\xD8"=>"=D8","\xD9"=>"=D9","\xDA"=>"=DA", + "\xDB"=>"=DB","\xDC"=>"=DC","\xDD"=>"=DD","\xDE"=>"=DE", + "\xDF"=>"=DF","\xE0"=>"=E0","\xE1"=>"=E1","\xE2"=>"=E2", + "\xE3"=>"=E3","\xE4"=>"=E4","\xE5"=>"=E5","\xE6"=>"=E6", + "\xE7"=>"=E7","\xE8"=>"=E8","\xE9"=>"=E9","\xEA"=>"=EA", + "\xEB"=>"=EB","\xEC"=>"=EC","\xED"=>"=ED","\xEE"=>"=EE", + "\xEF"=>"=EF","\xF0"=>"=F0","\xF1"=>"=F1","\xF2"=>"=F2", + "\xF3"=>"=F3","\xF4"=>"=F4","\xF5"=>"=F5","\xF6"=>"=F6", + "\xF7"=>"=F7","\xF8"=>"=F8","\xF9"=>"=F9","\xFA"=>"=FA", + "\xFB"=>"=FB","\xFC"=>"=FC","\xFD"=>"=FD","\xFE"=>"=FE", + "\xFF"=>"=FF" + ); + } + /** + * 在quoted-printable编码中过滤等号 + * @param string $string 取得编码的字符串 + * @return string + */ + public static function _encodeQp($string){ + $string = strtr($string,array('='=>'=3D')); + return strtr($string,self::getQpTable()); + } + /** + * 生成mime邮件头的消息ID + * @return string + */ + public function createMessageId() { + if (array() != ($from = $this->getFrom())) { + $user = is_array($from) ? $from[0] : $from; + } elseif (isset($_SERVER['REMOTE_ADDR'])) { + $user = $_SERVER['REMOTE_ADDR']; + } else { + $user = getmypid(); + } + $rand = mt_rand(); + if ($this->recipients) { + $recipient = array_rand($this->recipients); + } else { + $recipient = 'No recipient'; + } + if (isset($_SERVER["SERVER_NAME"])) { + $host = $_SERVER["SERVER_NAME"]; + } else { + $host = php_uname('n'); + } + return sha1(time() . $user . $rand . $recipient) . '@' . $host; + } + + /** + * 清空邮件头 + * @param string $header + */ + public function clearMailHeader($header = null){ + if($header){ + if(isset($this->mailHeader[$header])){ + unset($this->mailHeader[$header]); + } + }else{ + $this->mailHeader = array(); + } + } + /** + * 清空附件 + */ + public function clearAttachment(){ + $this->attachment = array(); + } + + /** + * 清空收件人 + */ + public function clearRecipients(){ + $this->recipients = array(); + } + + /** + * 清空边界线 + */ + public function clearBoundary(){ + $this->boundary = ''; + } + + /** + * 清空html格式的邮件正文 + */ + public function clearBodyHtml(){ + $this->bodyHtml = ''; + } + + /** + * 清空text格式的邮件正文 + */ + public function clearBodyText(){ + $this->bodyText = ''; + } + + /** + * 清空邮件头、附件、收件人、边界线、html和text格式的邮件正文; + */ + public function clearAll(){ + $this->clearMailHeader(); + $this->clearRecipients(); + $this->clearAttachment(); + $this->clearBoundary(); + $this->clearBodyHtml(); + $this->clearBodyText(); + } + /** + * 构建收件人列表 + * @param string $data + * @return array(); + */ + private function buildRecipients($data = array()) { + if(empty($data) || !is_array($data)){ + return array(); + } + foreach ($data as $key => $value) { + if (is_string($key)) { + $this->recipients[] = $value.' '.$key; + } else { + $this->recipients[] = $value; + } + } + return $this->recipients; + } + + /** + * 生成mime邮件头 + * @param string $name mime头 + * @param string $value mime值 + * @return string + */ + private function headerLine($name,$value){ + if(is_array($value)){ + $tmp = ''; + foreach($value as $key=>$_value){ + $_value = is_string($key) ? $key.' '.$_value : $_value; + $tmp .= $tmp ? ','.$_value : $_value; + } + return $name.': '.$tmp.self::CRLF; + + }else{ + return $name .': '.$value.self::CRLF; + } + return ''; + } + + /** + * 判断邮件是否有附件 + * @return boolean + */ + private function hasAttachment(){ + return count($this->attachment) > 0; + } + + /** + * 取得下一个quoted-printable + * @param string $string + * @return string + */ + private static function getNextQpToken($string){ + return '=' == substr($string, 0, 1) ? substr($string, 0, 3) : substr($string, 0, 1); + } +} \ No newline at end of file diff --git a/wind/component/mail/protocol/WindImap.php b/wind/component/mail/protocol/WindImap.php new file mode 100644 index 00000000..2e0dd161 --- /dev/null +++ b/wind/component/mail/protocol/WindImap.php @@ -0,0 +1,663 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.mail.protocol.WindSocket'); +/** + * imap协议封装 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindImap { + const CRLF = "\r\n"; + /** + * @var string w命令标签 + */ + const TAG = 'Tag'; + + /*--------imap中邮件标记---------*/ + + /** + * @var string 已被阅读 + */ + const SEEN = '\seen'; + /** + * @var string 已被回复 + */ + const ANSWERED = '\Answered'; + + /** + * @var string 标识为紧急 + */ + const FLAGGED = '\Flagged'; + /** + * @var string 标识为已删除 + */ + const DELETED = '\Deleted'; + /** + * @var string 草稿 + */ + const DRAFT = '\Draft'; + /** + * @var string 新邮件 + */ + const RECENT = '\Recent'; + /*--------imap中邮件标记--------*/ + + /*---------imap中邮件标记类型(store/stripstore方法flags参数)--------*/ + /** + * @var string 邮件的一组标志 + */ + const FLAGS = 'FLAGS'; + /** + * @var string 表示一组邮件的标志 + */ + const SLIENT = 'FLAGS.SLIENT'; + /*---------imap中邮件标记类型(store/stripstore方法flags参数)--------*/ + + /*--------fetch函数中参数$dataname的值---------*/ + /** + * @var string 按照一定格式的邮件摘要,包括邮件标志、RFC822.SIZE、自身的时间和信封信息。 + */ + const ALL = 'ALL'; + /** + * @var string 返回邮件体文本格式和大小的摘要信息 + */ + const BODY = 'BODY'; + /** + * @var string 返回邮件的一些摘要,包括邮件标志、RFC822.SIZE、和自身的时间 + */ + const FAST = 'FAST'; + /** + * @var string 要信息,包括邮件标志、RFC822.SIZE、自身的时间和BODYSTRUCTURE的信息。 + */ + const FULL = 'FULL'; + + /** + * @var string 此邮件的标志 + */ + const FLAG = 'FLAGS'; + /** + * @var string 邮件的[MIME-IMB]的体结构。 + */ + const BODYSTRUCTUR = 'BODYSTRUCTUR'; + /** + * @var string 自身的时间。 + */ + const INTERNALDATE = 'INTERNALDATE'; + /** + * @var string 等同于BODY[]。 + */ + const RFC822 = 'RFC822'; + /** + * @var string 邮件的[RFC-2822]大小 + */ + const RFC822SIZE = 'RFC822.SIZE'; + /** + * @var string 等同于BODY.PEEK[HEADER], + */ + const RFC822HEADER = 'RFC822.HEADER'; + /** + * @var string 功能上等同于BODY[TEXT] + */ + const RFC822TEXT = 'RFC822.TEXT'; + /** + * @var string 返回邮件的UID号,UID号是唯一标识邮件的一个号码。 + */ + const UID = 'UID'; + /*--------fetch函数中参数$dataname的值---------*/ + + /*--------header中的field--------*/ + /** + * @var string 日期 + */ + const DATE = 'Date'; + /** + * @var string 发件人 + */ + const FROM = 'From'; + /** + * @var string 收件人 + */ + const TO = 'To'; + /** + * @var string 抄送地址 + */ + const CC = 'Cc'; + /** + * @var string 抄送地址 + */ + const BCC = 'Bcc'; + /** + * @var string 发送地址 + */ + const DELIVERED = 'Delivered-To'; + /** + * @var string 回复地址 + */ + const REPLY = 'Reply-To'; + /** + * @var string 主题 + */ + const SUBEJCT = 'Subject'; + /** + * @var string MIME内容的类型 + */ + const CONTENTTYPE = 'Content-Type'; + /** + * @var string 内容的传输编码方式 + */ + const CONTENTENCODE = 'Content-Transfer-Encoding'; + /** + * @var string MIME版本 + */ + const MIMEVERSION = 'MIME-Version'; + /** + * @var string 消息ID + */ + const MESSAGEID = 'Message-Id'; + + /** + * @var string 传输路径 + */ + const RECEIVED = 'Received'; + /** + * @var string 回复地址 + */ + const RETURNPATH = 'Return-Path'; + /*--------header中的field--------*/ + + /*--------status命令中所用参数--------*/ + /** + * @var string 邮箱中的邮件总数 + */ + const S_MESSAGES = 'MESSAGES'; + /** + * @var string 邮箱中标志为\RECENT的邮件数 + */ + const S_RECENT = 'RECENT'; + /** + * @var string 可以分配给新邮件的下一个UID + */ + const S_UIDNEXT = 'UIDNEXT'; + /** + * @var string 邮箱的UID有效性标志 + */ + const S_UIDVALIDITY = 'UIDVALIDITY'; + /** + * @var string 邮箱中没有被标志为\UNSEEN的邮件数 + */ + const S_UNSEEN = 'UNSEEN'; + /*--------status命令中所用参数--------*/ + + /*--------search命令中所用参数--------*/ + /** + * @var string 返回所有的匹配 + */ + CONST SH_ALL = 'ALL'; + /** + * @var string 返回新的邮件 + */ + CONST SH_NEW = 'NEW'; + /** + * @var string 返回邮件中打了\Answered标记的邮件 + */ + CONST SH_ANSWERED = 'ANSWERED'; + /** + * @var string 返回邮件中指字暗送的邮件 + */ + CONST SH_BCC = 'BCC'; + /** + * @var string 返回指定日期已前的邮件 + */ + CONST SH_BEFORE = 'BEFORE'; + /** + * @var string 返回有主体的邮件 + */ + CONST SH_BODY = 'BODY'; + /** + * @var string 返回邮件中打了\Deleted标记的邮件 + */ + CONST SH_DELETED = 'DELETED'; + /** + * @var string 返回邮件中打了\Flagged标记的邮件 + */ + CONST SH_FLAGGED = 'FLAGGED'; + /** + * @var string 返回指定发件人字段的邮件 + */ + CONST SH_FROM = 'FROM'; + /** + * @var string 返回邮件消息中指定keywork的邮件 + */ + CONST SH_KEYWORD = 'KEYWORD'; + /** + * @var string 返回邮件中打了\Recent标记的邮件 + */ + CONST SH_RECENT = 'RECENT'; + /** + * @var string 返回邮件中打了\Seen标记的邮件 + */ + CONST SH_SEEN = 'SEEN'; + /** + * @var string 返回指定日期之后的邮件 + */ + CONST SH_SINCE = 'SINCE'; + /** + * @var string 返回邮件中文本指定字符串的邮件 + */ + CONST SH_TEXT = 'TEXT'; + /** + * @var string 返回指定收件人字段的邮件 + */ + CONST SH_TO = 'TO'; + /** + * @var string 返回邮件中没有打\Answered标记的邮件 + */ + CONST SH_UNANSWERED = 'UNANSWERED'; + /** + * @var string 返回邮件中没有打\Deleted标记的邮件 + */ + CONST SH_UNDELETED = 'UNDELETED'; + /** + * @var string 返回邮件中没有指定关键字的邮件 + */ + CONST SH_UNKEYWORD = 'UNKEYWORD'; + /** + * @var string 返回邮件中没有打\Seen标记的邮件 + */ + CONST SH_UNSEEN = 'UNSEEN'; + /** + * @var string 返回邮件中没有打\UNFLAGGED标记的邮件 + */ + CONST SH_UNFLAGGED = 'UNFLAGGED'; + /*--------search命令中所用参数--------*/ + + /******body中的section********/ + const TEXT = 'TEXT'; + const HEADER = 'HEADER'; + /******body中的section********/ + /** + * @var WindSocket imap邮件服务器 + */ + protected $imap = null; + protected $seperate = ' '; + protected $request = array(); + protected $resonse = array(); + + private $tag = 0; + public function __construct($host, $port) { + $this->imap = new WindSocket($host, $port); + } + + /** + * 打开一个imap连接 + * @return string + */ + public function open() { + $this->imap->open(); + return $this->response('*'); + } + + /** + * 登陆 + * @param string $username + * @param string $password + * @return string + */ + public function login($username, $password) { + return $this->communicate("LOGIN {$username} {$password}"); + } + + /** + * 创建指定名字的新邮箱。邮箱名称通常是带路径的文件夹全名。 + * @param string $folder; + * @param string + */ + public function create($folder) { + return $this->communicate("CREATE {$folder}"); + } + + /** + * 除指定名字的文件夹。文件夹名字通常是带路径的文件夹全名, + * 当邮箱被删除后,其中的邮件也不复存在。 + * @param string $folder + * @return string + */ + public function delete($folder) { + return $this->communicate("DELETE {$folder}"); + } + + /** + * RENAME命令可以修改文件夹的名称,它使用两个参数:当前邮箱名和新邮箱名, + * 两个参数的命名符合标准路径命名规则。 + * @param string $old 当前邮箱名 + * @param string $new 新邮箱名, + * @return string + */ + public function rename($old, $new) { + return $this->communicate("RENAME {$old} {$new}"); + } + + /** + * LIST命令用于列出邮箱中已有的文件夹,有点像操作系统的列目录命令 + * @param string $base 用户登陆目录 + * @param string $template 显示的邮箱名。可以使用通配符"*"。 + * @return string + */ + public function folderOfmail($base = '', $template = '*') { + return $this->communicate("LIST {$base} {$template}"); + } + + /** + * 选定某个邮箱(Folder),表示即将对该邮箱(Folder)内的邮件作操作。 + * 邮箱标志的当前状态也返回给了用户,同时返回的还有一些关于邮件和邮箱的附加信息。 + * @param string $folder + */ + public function select($folder) { + return $this->communicate("SELECT $folder"); + } + /** + * 读取邮件的文本信息,且仅用于显示的目的。 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param string $datanames + */ + public function fetch($mail, $datanames = self::ALL) { + return $this->communicate("FETCH {$mail} {$datanames}"); + } + + /** + * 读取邮件的头信息 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @return string + */ + public function fetchHeader($mail) { + return $this->communicate("FETCH {$mail} BODY[HEADER]"); + } + /** + * 读取邮件的头的字段信息,可能造成不安全,慎用 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param string $field 头字段(DATE\SUBJECT\FROM\TO\MESSAGEID\CONTENTTYPE) + * @return string + */ + public function fetchHeaderFields($mail, $field = self::DATE) { + $field = is_array($field) ? implode(' ', $field) : $field; + return $this->communicate("FETCH {$mail} BODY[HEADER.FIELDS ({$field})]"); + } + /** + * 读取邮件的头已排除字段信息 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param string $field 头字段(DATE\SUBJECT\FROM\TO\MESSAGEID\CONTENTTYPE) + * @return string + */ + public function fetchHeaderNotFields($mail, $field = self::DATE) { + $field = is_array($field) ? implode(' ', $field) : $field; + return $this->communicate("FETCH {$mail} BODY[HEADER.FIELDS.NOT ({$field})]"); + } + /** + * 读取邮件的MIME + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @return string + */ + public function fetchMime($mail) { + return $this->communicate("FETCH {$mail} BODY[MIME]"); + } + /** + * 读取邮件的Text + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @return string + */ + public function fetchText($mail) { + return $this->communicate("FETCH {$mail} BODY[TEXT]"); + } + + /** + * 返回邮件的中的某一指定部分,返回的部分用section来表示, + * section部分包含的信息通常是代表某一部分的一个数字或者是下面的某一个部分: + * HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。 + * 如果section部分是空的话,那就代表返回全部的信息,包括头信息。 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param int|string $section 返回的部分 + * @return string + */ + public function fetchBySection($mail, $section = self::TEXT) { + return $this->communicate("FETCH {$mail} BODY[$section]"); + } + + /** + * 返回邮件的中的某一指定部分,返回的部分用section来表示, + * section部分包含的信息通常是代表某一部分的一个数字或者是下面的某一个部分: + * HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。 + * 如果section部分是空的话,那就代表返回全部的信息,包括头信息。 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param int $start 返回的部分的开始 + * @param int $end 返回的部分的结束 + * @param int:string $section 返回的部分 + * @return string + */ + public function fetchPartialOfSection($mail, $start, $end, $section = self::TEXT) { + return $this->communicate("FETCH {$mail} BODY[$section]<{$start}.{$end}>"); + } + + /** + * 修改指定邮件的属性,包括给邮件打上已读标记、删除标记等 + * @param INT|string $mail + * @param string $flags imap中的邮件标记,值为SLIENT和FLAGS两种类型 + * @param STRING|ARRAY $attribute 标记属性(DELETED\ANSWERED\RECENT\DRAFT\FLAGGED) + * @reutrn string + */ + public function store($mail, $flags = self::FLAGS, $attribute = self::ANSWERED) { + $attribute = is_array($attribute) ? implode(' ', $attribute) : $attribute; + return $this->communicate("STORE {$mail} +" . self::FLAGS . " ($attribute)"); + } + /** + * 修改指定邮件的属性,包括给邮件打上已读标记、删除标记等 + * @param INT|string $mail + * @param string $flags imap中的邮件标记,值为SLIENT和FLAGS两种类型 + * @param STRING|ARRAY $attribute 标记属性(DELETED\ANSWERED\RECENT\DRAFT\FLAGGED) + * @reutrn string + */ + public function stripStore($mail, $flags = self::FLAGS, $attribute = self::DELETED) { + $attribute = is_array($attribute) ? implode(' ', $attribute) : $attribute; + return $this->communicate("STORE {$mail} -" . self::FLAGS . " ($attribute)"); + } + /** + * 结束对当前Folder(文件夹/邮箱)的访问, + * 关闭邮箱该邮箱中所有标志为DELETED的邮件就被从物理上删除 + */ + public function close() { + return $this->communicate("CLOSE"); + } + + /** + * 不关闭邮箱的情况下删除所有的标志为、DELETED的邮件。 + * EXPUNGE删除的邮件将不可以恢复。 + */ + public function expunge() { + return $this->communicate("EXPUNGE"); + } + /** + * 以只读方式打开邮箱 + * @param string $mailbox 邮箱 + * @return string + */ + public function examine($mailbox) { + return $this->communicate("EXAMINE $mailbox"); + } + + /** + * 在客户机的活动邮箱列表中增加一个邮箱 + * @param string $mailbox 希望添加的邮箱名。 + */ + public function subscribe($mailbox) { + return $this->communicate("SUBSCRIBE $mailbox"); + } + + /** + * 来从活动列表中去掉一个邮箱 + * @param string $mailbox 希望去掉的邮箱名。 + */ + public function unsubscribe($mailbox) { + return $this->communicate("UNSUBSCRIBE $mailbox"); + } + + /** + * 修正了LIST命令,LIST返回用户$HOME目录下所有的文件, + * 但LSUB命令只显示那些使用SUBSCRIBE命令设置为活动邮箱的文件 + * @param string $folder 邮箱路径 + * @param string $mailbox 邮箱名。 + * @return string + */ + public function lsub($folder, $mailbox) { + return $this->communicate("LSUB {$mailbox} {$mailbox}"); + } + + /** + * 查询邮箱的当前状态 + * @param string $mailbox 需要查询的邮箱名 + * @param string $params 客户机需要查询的项目列表,S_MESSAGES\S_RECENT\S_UIDNEXT\S_UIDVALIDITY\S_UNSEEN + * @return string + */ + public function status($mailbox, $params = self::S_MESSAGES) { + + $params = is_array($params) ? implode(' ', $params) : $params; + return $this->communicate("STATUS {$mailbox} ({$params})"); + } + + /** + * 在邮箱设置一个检查点,确保内存中的磁盘缓冲数据都被写到了磁盘上。 + */ + public function check() { + return $this->communicate("CHECK"); + } + + /** + * 根据搜索条件在处于活动状态的邮箱中搜索邮件,然后显示匹配的邮件编号。 + * @param string $criteria 查询条件参数,明确查询的关键字 + * @param string $value 查询条件参数,明确查询的关键字的值 + * @param string $charset 字符集标志,缺省的标志符是US-ASCⅡ + * @return string + */ + public function search($criteria = self::SH_ALL, $value = null) { + $search = $criteria; + if ($value) { + $search .= ' ' . $value; + } + return $this->communicate("SEARCH {$search}"); + } + + /** + * UID号是唯一标识邮件系统中邮件的32位证书。 + * 通常这些命令都使用顺序号来标识邮箱中的邮件, + * 使用UID可以使IMAP客户机记住不同IMAP会话中的邮件。 + */ + public function uid() { + return $this->communicate("UID"); + } + + /** + * 把邮件从一个邮箱复制到另一个邮箱 + * @param int $soruce 希望从活动邮箱中复制的邮件的标号 + * @param string $dst 望邮件被复制到的邮箱 + * @return string + */ + public function copy($soruce, $dst) { + return $this->communicate("COPY {$soruce} {$dst}"); + } + + /** + * 返回IMAP服务器支持的功能列表, + * 服务器收到客户机发送的CAPABILITY命令后将返回该服务器所支持的功能。 + */ + public function capability() { + return $this->communicate("CAPABILITY"); + } + /** + * 结束本次IMAP会话。 + */ + public function logout() { + $this->communicate("LOGOUT"); + } + + /** + * 发送imap会话请求命令 + * @param string $request + */ + public function request($request) { + $this->request[] = $request; + $this->setTag(); + return $this->imap->request($this->getTag() . ' ' . $request . self::CRLF); + } + /** + * imap会话响应请求 + * @param int $timeout + */ + public function responseLine($timeout = null) { + if (null !== $timeout) { + $this->imap->setSocketTimeOut((int) $timeout); + } + return $this->imap->responseLine(); + } + + /** + * 验证请求 + * @param boolean $multi + * @param int $timeout + * @return string + */ + public function response($endTag = '*', $timeout = null) { + $response = ''; + while ('' != ($_response = $this->responseLine($timeout))) { + list($tag, $status, $info) = explode(' ', $_response, 3); + if (in_array($status, array('NO', "BAD"))) { + throw new WindException($_response); + } + $response .= $_response; + $this->resonse[] = $_response; + if ($endTag == $tag) { + break; + } + } + if (empty($response)) throw new WindException('No response'); + return $response; + } + + /** + * 一次imap会号 + * @param string $request 请求 + * @param string $response 响应 + * @return string + */ + public function communicate($request, &$response = null) { + $this->request($request); + return $response = $this->response($this->getTag()); + } + /** + * 在imap会话中设置新标答 + */ + public function setTag() { + $this->tag++; + } + /** + * 取得imap会号中的标签 + * @return string + */ + public function getTag() { + return self::TAG . $this->tag; + } + + public function __destruct() { + if ($this->imap) { + $this->logout(); + $this->imap->close(); + $this->imap = null; + } + } + +} \ No newline at end of file diff --git a/wind/component/mail/protocol/WindPop3.php b/wind/component/mail/protocol/WindPop3.php new file mode 100644 index 00000000..6a807a87 --- /dev/null +++ b/wind/component/mail/protocol/WindPop3.php @@ -0,0 +1,260 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import ( 'WIND:component.mail.protocol.WindSocket' ); +/** + * pop3协议 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPop3 { + const CRLF = "\r\n"; + /** + * @var WindSocket pop3邮件服务器 + */ + protected $pop3 = null; + protected $seperate = ' '; + protected $request = array(); + protected $resonse = array(); + + public function __construct($host, $port) { + $this->pop3 = new WindSocket($host, $port); + } + + /** + * 打开pop3服务器,建立连接 + * @return string + */ + public function open() { + $this->pop3->open(); + return $this->response(); + } + + /** + * 登陆pop3 + * @param string $username 用户名 + * @param string $password 密码 + * @return string + */ + public function login($username, $password) { + $this->communicate("USER $username"); + return $this->communicate("PASS $password"); + } + + /** + * 处理请求 server 回送邮箱统计资料,如邮件数、 邮件总字节数 + * @return string + */ + public function stat() { + return $this->communicate('STAT', false, true); + } + + /** + * 处理 server 返回用于该指定邮件的唯一标识, 如果没有指定,返回所有的。 + * @param int $n 指定邮件 + * @return string + */ + public function uidl($n = null) { + $request = $n ? "UIDL $n" : 'UIDL'; + $ifmulti = $n ? false : true; + return $this->communicate($request, $ifmulti, true); + } + + /** + * 处理 server 返回指定邮件的大小等 + * @param int $n 指定邮件 + * @return string + */ + public function getList($n = null) { + $request = $n ? "LIST $n" : 'LIST'; + $ifmulti = $n ? false : true; + return $this->communicate($request, $ifmulti, true); + } + + /** + * 处处理 server 返回邮件的全部文本 + * @param int $n 指定邮件 + * @return string + */ + public function retr($n) { + return $this->communicate("RETR $n", true); + } + /** + * 处理 server 标记删除,QUIT 命令执行时才真正删除 + * @param int $n 指定邮件 + * @return string + */ + public function dele($n) { + return $this->communicate("DELE $n"); + } + /** + * 处理撤消所有的 DELE 命令 + * @return string + */ + public function rset() { + return $this->communicate("RSET"); + } + + /** + * 处理 返回 n 号邮件的前 m 行内容,m 必须是自然数 + * @param int $n 指定邮件 + * @param int $m 指定邮件前多少行 + * @return string + */ + public function top($n, $m = null) { + $request = $m ? 'TOP ' . (int) $n . ' ' . (int) $m : 'TOP ' . (int) $n; + return $this->communicate($request, true); + } + + /** + * 处理 server 返回一个肯定的响应 + * @return string + */ + public function noop() { + return $this->communicate("NOOP"); + } + + /** + * 希望结束会话。如果 server 处于"处理" 状态, + * 则现在进入"更新"状态,删除那些标记成删除的邮件。 + * 如果 server 处于"认可"状态,则结束会话时 server + * 不进入"更新"状态 。 + * @return string + */ + public function quit() { + return $this->communicate("QUIT"); + } + + /** + * 结否会话,关闭pop3服务器 + */ + public function close() { + $this->quit(); + $this->pop3->close(); + $this->pop3 = null; + } + /** + * pop3响应请求 + * @param int $timeout + */ + public function responseLine($timeout = null) { + if (null !== $timeout) { + $this->pop3->setSocketTimeOut((int) $timeout); + } + return $this->pop3->responseLine(); + } + + /** + * 外理响应内容 + * @param string $response + * @return Array + */ + public function buildResponse($response) { + if (empty($response)) { + return array(); + } + $response = explode("\n", $response); + $_response = array(); + foreach ($response as $line) { + if (empty($line)) { + continue; + } + list($key, $value) = explode($this->seperate, trim($line), 2); + $key ? $_response[(int) $key] = $value : $_response[] = $value; + } + return $_response; + } + + /** + * 进行一次网络传输通信 + * @param string $request 发竤的请求命令 + * @param boolean $ifmulti 是否返回多行响应文本,否则为一行 + * @param baoolean $ifbuild 是否对响应进行处理 + * @return array + */ + public function communicate($request, $ifmulti = false, $ifbuild = false) { + $this->request($request); + return $ifbuild ? $this->buildResponse($this->response($ifmulti)) : $this->response($ifmulti); + } + + /** + * 发送pop3命令 + * @param string $request + */ + public function request($request) { + $this->request[] = $request; + return $this->pop3->request($request . self::CRLF); + } + + /** + * 验证请求 + * @param boolean $multi + * @param int $timeout + * @return string + */ + public function response($multi = false, $timeout = null) { + $ok = $this->responseLine($timeout); + if (empty($ok) || !is_string($ok)) { + throw new WindException('Read Failed'); + } + if ('+OK' !== substr($ok, 0, 3)) { + throw new WindException('Request Failed!Pleae See Failed Info:' . $ok); + } + if (true === $multi) { + $response = ''; + while ('' != ($_response = $this->responseLine($timeout))) { + if ('.' === trim($_response)) { + break; + } + $response .= $_response; + $this->resonse[] = $_response; + } + } else { + $this->resonse[] = $ok; + if (strpos($ok, $this->seperate)) { + list(, $response) = explode($this->seperate, $ok, 2); + } else { + $response = $ok; + } + } + if(empty($response)) throw new WindException('No response'); + return $response; + } + + /** + * 获取解析后的内容 + * @param $content + * @param $sep + */ + public function getMailContent($content,$sep = "\n\n"){ + $content = explode($sep,$content); + $content[0] = explode("\n",$content[0]); + $headers = array(); + foreach($content[0] as $value){ + $_value = explode(':',$value); + $headers[$_value[0]] = trim($_value[1]); + } + $encode = $headers['Content-Transfer-Encoding']; + if('base64' == $encode){ + $content = base64_decode($content[1]); + }else{ + $content = $content[1]; + } + return array($headers,$content); + } + + public function __destruct() { + if ($this->pop3) { + $this->close(); + } + } + +} +?> \ No newline at end of file diff --git a/wind/component/mail/protocol/WindSmtp.php b/wind/component/mail/protocol/WindSmtp.php new file mode 100644 index 00000000..895387b8 --- /dev/null +++ b/wind/component/mail/protocol/WindSmtp.php @@ -0,0 +1,211 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import ( 'WIND:component.mail.protocol.WindSocket' ); +/** + * 邮件传输协议操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSmtp { + const CRLF = "\r\n"; + /** + * @var WindSocket + */ + protected $smtp = null; + protected $request = array(); + protected $resonse = array(); + + public function __construct($host, $port,$timeout = 60) { + $this->smtp = new WindSocket($host, $port ,$timeout); + } + + /** + * 打开smtp服务器,建立连接 + * @return string + */ + public function open() { + $this->smtp->open(); + return $this->checkResponse(220); + } + + /** + * 向服务器标识用户身份 + * @param string $host 身份 + * @return string + */ + public function ehlo($host) { + $this->request('EHLO ' . $host); + return $this->checkResponse(250); + } + + /** + * 进行用户身份认证 + * @param string $username 用户名 + * @param string $password 密码 + * @return string + */ + public function authLogin($username, $password) { + $this->request('AUTH LOGIN'); + $this->checkResponse(array(334)); + $this->request(base64_encode($username)); + $this->checkResponse(array(334)); + $this->request(base64_encode($password)); + return $this->checkResponse(array(235)); + } + + /** + * 指定的地址是发件人地址 + * @param string $from 邮件发送者 + * @return string + */ + public function mailFrom($from) { + $this->request('MAIL FROM:' . '<' . $from . '>'); + return $this->checkResponse(250); + } + /** + * 指定的地址是收件人地址 + * @param string $to 邮件发送者 + * @return string + */ + public function rcptTo($to) { + $this->request('RCPT TO:' . '<' . $to . '>'); + return $this->checkResponse(array(250, 251)); + } + + /** + * 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令 + * @param string $user + * @return string + */ + public function very($user) { + $this->request('VRFY ' . $user); + return $this->checkResponse(array(250, 251, 252)); + } + /** + * 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用 + * @param string $name + * @return string + */ + public function expn($name) { + $this->request('EXPN ' . $name); + $response = $this->checkResponse(250); + $entries = explode(self::CRLF, $response); + while (list(, $l) = each($entries)) { + $list[] = substr($l, 4); + } + return $list; + } + + /** + * 无操作,服务器应响应 OK + * @return string + */ + public function noop() { + $this->request('NOOP'); + return $this->checkResponse(250); + } + + /** + * 在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以 CRLF.CRLF 结束 + * @param string $data 发送的数据 + * @return string + */ + public function data($data) { + $this->request('DATA'); + $this->checkResponse(354); + $data = str_replace("\r\n", "\n", $data); + $data = str_replace("\r", "\n", $data); + $lines = explode("\n", $data); + foreach ($lines as $line) { + if (0 === strpos($line, '.')) { + $line = '.' . $line; + } + $this->request($line); + } + $this->request('.'); + return $this->checkResponse(250); + } + /** + * 重置会话,当前传输被取消 + * @return string + */ + public function rset() { + $this->request('RSET'); + return $this->checkResponse(array(250, 220)); + } + /** + * 结束会话 + * @return string + */ + public function quit() { + $this->request('QUIT'); + return $this->checkResponse(221); + } + + /** + * 关闭smtp服务器 + */ + public function close() { + $this->smtp->close(); + $this->smtp = null; + } + + /** + * smtp响应请求 + * @param int $timeout + */ + public function responseLine($timeout = null) { + if (null !== $timeout) { + $this->smtp->setSocketTimeOut((int) $timeout); + } + return $this->smtp->responseLine(); + } + + /** + * 发送smtp命令 + * @param string $request + */ + public function request($request) { + $this->request[] = $request.self::CRLF; + return $this->smtp->request($request . self::CRLF); + } + + /** + * 验证请求 + * @param string $expect + * @param int $timeout + * @return string + */ + public function checkResponse($expect, $timeout = null) { + $response = ''; + $expect = is_array($expect) ? $expect : array($expect); + while ('' != ($_response = $this->responseLine($timeout))) { + $response .= $_response; + $this->resonse[] = $_response; + list($code, $info) = preg_split('/([\s-]+)/', $_response, 2); + if(null === $code || !in_array($code, $expect)) throw new WindException($info); + if (" " == substr($_response, 3, 1)) { + break; + } + } + if(empty($response)) throw new WindException('No response'); + return $response; + } + + + + public function __destruct() { + if ($this->smtp) { + $this->close(); + } + } + +} \ No newline at end of file diff --git a/wind/component/mail/protocol/WindSocket.php b/wind/component/mail/protocol/WindSocket.php new file mode 100644 index 00000000..c54a09af --- /dev/null +++ b/wind/component/mail/protocol/WindSocket.php @@ -0,0 +1,121 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * socket套接字操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSocket { + + protected $host = '127.0.0.1'; + protected $port = 80; + protected $timeout = 5; + protected $errno = 0; + protected $errstr = ''; + protected $socket = null; + + public function __construct($host = '127.0.0.1', $port = 80, $timeout = 5) { + $this->setHost($host); + $this->setPort($port); + $this->setTimeout($timeout); + } + + /** + * 打开一个连接 + */ + public function open() { + if (null == $this->socket) { + $this->socket = fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout); + } + } + + /** + * 发送请求 + * @param string $request + */ + public function request($request) { + return fputs($this->socket, $request); + } + + /** + * 响应请求 + * @return string + */ + public function response() { + $response = ''; + while (!feof($this->socket)) { + $response .= fgets($this->socket); + } + return $response; + } + + /** + * 响应请求,只返回一行 + * @return string + */ + public function responseLine() { + return feof($this->socket) ? '' : fgets($this->socket); + } + + /** + *关闭连接 + */ + public function close() { + if ($this->socket) { + fclose($this->socket); + $this->socket = null; + } + return true; + } + /** + * 获取请求中的错误 + * @return string + */ + public function getError() { + return $this->errstr ? $this->errno . ':' . $this->errstr : ''; + } + + /** + * 取得socket操作对象 + * @return resource + */ + public function getSocket(){ + return $this->socket; + } + + /** + * 设置主机 + * @param string $host + */ + public function setHost($host) { + $this->host = $host; + + } + /** + * 设置端口 + * @param string $port + */ + public function setPort($port) { + $this->port = $port; + } + /** + * 设置超时 + * @param int $timeout + */ + public function setTimeout($timeout) { + $this->timeout = $timeout; + } + + public function setSocketTimeOut($timeout) { + return stream_set_timeout($this->socket, $timeout); + } +} \ No newline at end of file diff --git a/wind/component/mail/sender/IWindSendMail.php b/wind/component/mail/sender/IWindSendMail.php new file mode 100644 index 00000000..2ca37f43 --- /dev/null +++ b/wind/component/mail/sender/IWindSendMail.php @@ -0,0 +1,15 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +interface IWindSendMail{ + /** + * 发送邮件 + * @param WindMail $mail 邮件消息封装对象 + */ + public function send(WindMail $mail); +} \ No newline at end of file diff --git a/wind/component/mail/sender/WindPhpMail.php b/wind/component/mail/sender/WindPhpMail.php new file mode 100644 index 00000000..04f69ade --- /dev/null +++ b/wind/component/mail/sender/WindPhpMail.php @@ -0,0 +1,34 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.mail.sender.IWindSendMail'); +/** + * 使用php内部函数发送邮件 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPhpMail implements IWindSendMail{ + + public function send(WindMail $mail){ + $recipients = $mail->getRecipients(); + $to = $this->getToAsString($recipients); + return mail($to,$mail->getSubject(),$mail->createBody(),$mail->createHeader()); + } + + public function getToAsString($recipients = array()){ + $to = ''; + foreach($recipients as $key=>$value){ + $_value = is_string($key) ? $key.' '.$_value : $_value; + $to .= $to ? ', '.$_value : $_value; + } + return $to; + + } +} \ No newline at end of file diff --git a/wind/component/mail/sender/WindSendMail.php b/wind/component/mail/sender/WindSendMail.php new file mode 100644 index 00000000..e6f98882 --- /dev/null +++ b/wind/component/mail/sender/WindSendMail.php @@ -0,0 +1,85 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.mail.sender.IWindSendMail'); +/** + * 使用sendmail发送邮件 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSendMail implements IWindSendMail{ + /** + * @var string sendmail命令路径 + */ + private $sendMail = '/usr/sbin/sendmail'; + /** + * @var string 发送者 + */ + private $sender = ''; + /** + * @var string 工作进程 + */ + private $process = null; + /** + * @param string $sendMail 工作进程 + * @param string $sender 发送者 + */ + public function __construct(array $config=null){ + if(isset($config['sendMail'])){ + $this->sendMail = $config['sendMail']; + } + if(isset($config['sender'])){ + $this->sender = $config['sender']; + } + } + /** + * 发送邮件 + * @param WindMail $mail mail信息封装对象 + * @return string + */ + public function send(WindMail $mail) { + $this->open(); + $this->transData($mail->createHeader()); + $this->transData($mail->createBody()); + return $this->close() ? false : true; + } + /** + * 开启一个sendmail进进程 + */ + public function open(){ + if($this->sender){ + $mailCmd = sprintf("%s -oi -f %s -t", escapeshellcmd($this->sendMail), escapeshellarg($this->sender)); + }else{ + $mailCmd = sprintf("%s -oi -t", escapeshellcmd($this->sendMail)); + } + $this->process = popen($mailCmd, 'w'); + } + + /** + * 传输数据 + * @param string $data 数据 + */ + public function transData($data){ + fputs($this->process,$data); + } + + + /** + * 关闭一个进程 + * @return number + */ + public function close(){ + return pclose($this->process); + } + + public function __destruct(){ + $this->process = null; + } +} \ No newline at end of file diff --git a/wind/component/mail/sender/WindSmtpMail.php b/wind/component/mail/sender/WindSmtpMail.php new file mode 100644 index 00000000..d645702d --- /dev/null +++ b/wind/component/mail/sender/WindSmtpMail.php @@ -0,0 +1,92 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.mail.sender.IWindSendMail'); +Wind::import ( 'WIND:component.mail.protocol.WindSmtp' ); +/** + * 邮件发送 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSmtpMail implements IWindSendMail{ + /** + * @var WindSmtp 邮件发送服务器 + */ + protected $smtp = null; + /** + * @var boolean 是否启用验证 + */ + protected $auth = true; + /** + * @var string 邮件主机名 + */ + protected $name = 'localhost'; + /** + * @var string 邮件用户名 + */ + protected $username = ''; + /** + * @var string 邮件密码 + */ + protected $password = ''; + + public function __construct(array $config){ + $defautConfig = array('host'=>'127.0.0.1','port'=>'25','name'=>'localhost','auth'=>true); + $config = array_merge($defautConfig,$config); + if(!isset($config['host']) || !isset($config['port'])){ + throw new WindException('The mail host or port is not exist'); + } + if($config['auth'] && (!isset($config['user']) || !isset($config['password']))){ + throw new WindException('In the verification mode, the user name and password is blank or wrong'); + } + $this->auth = $config['auth']; + $this->name = $config['name']; + $this->smtp = new WindSmtp($config['host'],$config['port']); + $this->smtp->open(); + $this->setAuthParams($config['user'],$config['password']); + } + + /** + * 发送邮件 + * @param WindMail $mail 邮件消息封装对象 + */ + public function send(WindMail $mail){ + $this->smtp->ehlo($this->name); + if($this->auth){ + $this->smtp->authLogin($this->username,$this->password); + } + $this->smtp->mailFrom($mail->getFrom()); + foreach($mail->getRecipients() as $rcpt){ + $this->smtp->rcptTo($rcpt); + } + $header = $mail->createHeader(); + $body = $mail->createBody(); + $data = $header.$body; + $this->smtp->data($header.$body); + $this->smtp->quit(); + } + + /** + * 设置验证参数 + * @param string $username 用户名 + * @param string $password 密码 + */ + public function setAuthParams($username,$password){ + $this->username = $username; + $this->password = $password; + } + + + + public function __destruct(){ + $this->smtp->close(); + $this->smtp = null; + } +} \ No newline at end of file diff --git a/wind/component/parser/WindIniParser.php b/wind/component/parser/WindIniParser.php new file mode 100644 index 00000000..91997407 --- /dev/null +++ b/wind/component/parser/WindIniParser.php @@ -0,0 +1,147 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * ini 格式文件解析 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindIniParser { + + /** + * @var string 分割数组标识 + */ + protected $separator = '.'; + + /** + * 解析数据 + * @param string $filename ini格式文件 + * @param boolean $process 处理指令 + * @param boolean $build 是否按指定格式返回 + * @return boolean + */ + public function parse($filename, $process = true, $build = true) { + if (!is_file($filename)) { + return array(); + } + $data = parse_ini_file($filename, $process); + return $build ? $this->buildData($data) : $data; + } + + /** + * 构建数据 + * @param array $data + * @return array + */ + public function buildData(&$data) { + foreach ((array)$data as $key => $value) { + if (is_array($value)) { + $data[$key] = $this->formatDataArray($value); + } else { + $this->formatDataFromString($key, $value, $data); + } + } + return $data; + } + + /** + * 将每行ini文件转换成数组 + * @param string $key ini文件中的键 + * @param string $value ini文件中的值 + * @param array $data + * @return array + */ + public function toArray($key, $value, &$data = array()) { + if (empty($key) && empty($value)) return array(); + if (strpos($key, $this->separator)) { + $start = substr($key, 0, strpos($key, $this->separator)); + $end = substr($key, strpos($key, $this->separator) + 1); + $data[$start] = array(); + $this->toArray($end, $value, $data[$start]); + } else { + $data[$key] = $value; + } + return $data; + } + + /** + * 解析ini格式文件成数组 + * @param array $original 原始数组 + * @param array $data 解析后的数组 + * @return array + */ + public function formatDataArray(&$original, &$data = array()) { + foreach ((array)$original as $key => $value) { + $tmp = $this->toArray($key, $value); + foreach ($tmp as $tkey => $tValue) { + if (is_array($tValue)) { + if (!isset($data[$tkey])) { + $data[$tkey] = array(); + } + $this->formatDataArray($tValue, &$data[$tkey]); + } else { + $data[$tkey] = $tValue; + } + } + } + return $data; + } + + /** + * 从字符串中合并数组 + * @param string $key + * @param string $value + * @param array $data + * return array + */ + public function formatDataFromString($key, $value, &$data) { + $tmp = $this->toArray($key, $value); + if(false == strpos($key, $this->separator)){ + return $tmp; + } + $start = substr($key, 0, strpos($key, $this->separator)); + if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { + $data[$start] = $tmp[$start]; + } else { + foreach ($data as $d_key => $d_value) { + if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { + continue; + } + foreach ($tmp[$d_key] as $a => $b) { + $this->merge($a, $b, $data[$start]); + } + } + } + unset($data[$key]); + return $data; + } + + /** + * 合并格式化的数组 + * @param string $key + * @param mixed $value + * @param array $data + * @return array + */ + private function merge($key, $value, &$data = array()) { + if (is_array($value)) { + $v_key = array_keys($value); + $c_key = $v_key[0]; + if (is_array($value[$c_key])) { + $this->merge($c_key, $value[$c_key], $data[$key]); + } else { + $data[$key][$c_key] = $value[$c_key]; + } + } else { + $data[$key] = $value; + } + return $data; + } +} \ No newline at end of file diff --git a/wind/component/parser/WindPropertiesParser.php b/wind/component/parser/WindPropertiesParser.php new file mode 100644 index 00000000..9f4f7a65 --- /dev/null +++ b/wind/component/parser/WindPropertiesParser.php @@ -0,0 +1,210 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * properties格式文件解析 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPropertiesParser { + + const COMMENT = '#'; + const LPROCESS = '['; + const RPROCESS = ']'; + private $separator = '.'; + + public function __construct() { + + } + + /** + * 解析properties文件里的内容 + * @param string $filename 文件名 + * @param boolean $process 是否处理指令 + * @param boolean $build 是否按格式解析数据 + * @return array + */ + public function parse($filename, $process = true, $build = true) { + $data = $this->parse_properties_file($filename, $process); + return $build ? $this->buildData($data) : $data; + } + + /** + * 载入一个由 filename 指定的 properties 文件, + * 并将其中的设置作为一个联合数组返回。 + * 如果将最后的 process参数设为 TRUE, + * 将得到一个多维数组,包括了配置文件中每一节的名称和设置。 + * process_sections 的默认值是 true。 + * @param string $filename 文件名 + * @param unknown_type $process 是否处理指令 + * @return array + */ + public function parse_properties_file($filename, $process = true) { + if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { + return array(); + } + $fp = fopen($filename, 'r'); + $content = fread($fp, filesize($filename)); + fclose($fp); + $content = explode("\n", $content); + $data = array(); + $last_process = $current_process = ''; + foreach ($content as $key => $value) { + $value = str_replace(array("\n", "\r"), '', trim($value)); + if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { + continue; + } + $tmp = explode('=', $value); + if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { + if ($process) { + $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); + $data[$current_process] = array(); + $last_process = $current_process; + } + continue; + } + $tmp[0] = trim($tmp[0]); + $tmp[1] = trim($tmp[1]); + + if ($last_process) { + count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; + } else { + count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; + } + } + return $data; + + } + + /** + * 解析数据 + * @param array $data + * @return array + */ + public function buildData(&$data) { + foreach ((array)$data as $key => $value) { + if (is_array($value)) { + $data[$key] = $this->formatDataArray($value); + } else { + $this->formatDataFromString($key, $value, $data); + } + } + return $data; + } + + /** + * 将proterties文件每行转换成数组 + * @param string $key ini文件中的键 + * @param string $value ini文件中的值 + * @param array $data + * @return array + */ + public function toArray($key, $value, &$data = array()) { + if (empty($key) && empty($value)) return array(); + if (strpos($key, $this->separator)) { + $start = substr($key, 0, strpos($key, $this->separator)); + $end = substr($key, strpos($key, $this->separator) + 1); + $data[$start] = array(); + $this->toArray($end, $value, $data[$start]); + } else { + $data[$key] = $value; + } + return $data; + } + + /** + * 将原始数组合并成新的数组 + * @param array $original 原始数组 + * @param array $data 合并后的数组 + * @return array + */ + public function formatDataArray(&$original, &$data = array()) { + foreach ((array)$original as $key => $value) { + $tmp = $this->toArray($key, $value); + foreach ($tmp as $tkey => $tValue) { + if (is_array($tValue)) { + if (!isset($data[$tkey])) { + $data[$tkey] = array(); + } + $this->formatDataArray($tValue, &$data[$tkey]); + } else { + $data[$tkey] = $tValue; + } + } + } + return $data; + } + + /** + * 从字符串中合并数组 + * @param string $key + * @param string $value + * @param array $data + * return array + */ + public function formatDataFromString($key, $value, &$data) { + $tmp = $this->toArray($key, $value); + if(false == strpos($key, $this->separator)){ + return $tmp; + } + $start = substr($key, 0, strpos($key, $this->separator)); + if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { + $data[$start] = $tmp[$start]; + } else { + foreach ($data as $d_key => $d_value) { + if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { + continue; + } + foreach ($tmp[$d_key] as $a => $b) { + $this->merge($a, $b, $data[$start]); + } + } + } + unset($data[$key]); + return $data; + } + + /** + * 合并格式化的数组 + * @param string $key + * @param mixed $value + * @param array $data + * @return array + */ + private function merge($key, $value, &$data = array()) { + if (is_array($value)) { + $v_key = array_keys($value); + $c_key = $v_key[0]; + if (is_array($value[$c_key])) { + $this->merge($c_key, $value[$c_key], $data[$key]); + } else { + $data[$key][$c_key] = $value[$c_key]; + } + } else { + $data[$key] = $value; + } + return $data; + } + + /** + * 去除字符串头和尾中指定字符 + * @param string $str + * @param mixed $char + * @return string + */ + private function trimChar($str, $char = ' ') { + $char = is_array($char) ? $char : array($char); + foreach ($char as $value) { + $str = trim($str, $value); + } + return $str; + } + +} \ No newline at end of file diff --git a/wind/component/parser/WindXmlParser.php b/wind/component/parser/WindXmlParser.php new file mode 100644 index 00000000..1df04590 --- /dev/null +++ b/wind/component/parser/WindXmlParser.php @@ -0,0 +1,106 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * xml文件解析 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindXmlParser { + + /** + * @var string 节点名称 + */ + const NAME = 'name'; + + /** + * @var Domdocument DOM解析器 + */ + private $dom = null; + + /** + * @param string $version xml版本 + * @param string $encode xml编码 + */ + public function __construct($version = '1.0', $encode = 'utf-8') { + if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); + $this->dom = new DOMDocument($version, $encode); + } + + /** + * @param string $filename xml 文件名 + * @param int $option 解析选项 + * @return array + */ + public function parse($filename, $option = null) { + if (!is_file($filename)) return array(); + $this->dom->load($filename, $option); + return $this->getChilds($this->dom->documentElement); + } + + /** + * 获得节点的所有子节点 + * + * 子节点包括属性和子节点(及文本节点), + * 子节点的属性将会根据作为该节点的一个属性元素存放,如果该子节点中含有标签列表,则会进行一次合并。 + * 每个被合并的列表项都作为一个单独的数组元素存在。 + * + * @param DOMElement $node 要解析的XMLDOM节点 + * @return array 返回解析后该节点的数组 + */ + public function getChilds($node) { + if (!$node instanceof DOMElement) return array(); + $childs = array(); + foreach ($node->childNodes as $node) { + $tempChilds = $attributes = array(); + ($node->hasAttributes()) && $attributes = $this->getAttributes($node); + (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; + if (1 !== $node->nodeType) continue; + + $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; + $tempChilds = $this->getChilds($node); + $tempChilds = array_merge($attributes, $tempChilds); + if (empty($tempChilds)) $tempChilds = ''; + + $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; + if (!isset($childs[$nodeName])) { + $childs[$nodeName] = $tempChilds; + continue; + } else { + $element = $childs[$nodeName]; + $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( + $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); + continue; + } + } + return $childs; + } + + /** + * 获得节点的属性 + * + * 该属性将不包含属性为name的值--规则(name的值将作为解析后数组的key值索引存在) + * + * @param DOMElement $node + * @return array 返回属性数组 + */ + public function getAttributes($node) { + if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); + $attributes = array(); + foreach ($node->attributes as $attribute) { + if (self::NAME != $attribute->nodeName) { + $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; + } + } + return $attributes; + } +} +?> \ No newline at end of file diff --git a/wind/component/upload/AbstractWindUpload.php b/wind/component/upload/AbstractWindUpload.php new file mode 100644 index 00000000..2220c26b --- /dev/null +++ b/wind/component/upload/AbstractWindUpload.php @@ -0,0 +1,23 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import ( 'WIND:component.utility.Security' ); +Wind::import ( 'WIND:component.utility.WindFile' ); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +abstract class AbstractWindUpload{ + /** + * @param string $name + * @param string $newName + * @param string $path + */ + public abstract function upload($name, $newName, $path); +} \ No newline at end of file diff --git a/wind/component/upload/WindCurlUpload.php b/wind/component/upload/WindCurlUpload.php new file mode 100644 index 00000000..317830ac --- /dev/null +++ b/wind/component/upload/WindCurlUpload.php @@ -0,0 +1,16 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +class WindCurlUpload extends AbstractWindUpload{ + + public function upload($name, $newName, $path) { + + } + + +} \ No newline at end of file diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php new file mode 100644 index 00000000..8f2d4930 --- /dev/null +++ b/wind/component/upload/WindFormUpload.php @@ -0,0 +1,24 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import ( 'WIND:component.upload.AbstractWindUpload'); + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindFormUpload extends AbstractWindUpload{ + + public function upload($name, $newName, $path) { + + } + + +} \ No newline at end of file diff --git a/wind/component/utility/WindArray.php b/wind/component/utility/WindArray.php new file mode 100644 index 00000000..6f8fe1ce --- /dev/null +++ b/wind/component/utility/WindArray.php @@ -0,0 +1,83 @@ + 2010-11-7 + *@link http://www.phpwind.com + *@copyright Copyright © 2003-2110 phpwind.com + *@license + */ + +/** + * 数组工具类 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindArray { + + /** + * 按指定key合并两个数组 + * @param string key 合并数组的参照值 + * @param array $array1 要合并数组 + * @param array $array2 要合并数组 + * @return array 返回合并的数组 + */ + public static function mergeArrayWithKey($key, array $array1, array $array2) { + if (!$key || !$array1 || !$array2) { + return array(); + } + $array1 = self::rebuildArrayWithKey($key, $array1); + $array2 = self::rebuildArrayWithKey($key, $array2); + $tmp = array(); + foreach ($array1 as $key => $array) { + if (isset($array2[$key])) { + $tmp[$key] = array_merge($array, $array2[$key]); + unset($array2[$key]); + } else { + $tmp[$key] = $array; + } + } + return array_merge($tmp, (array) $array2); + } + + /** + * 按指定key合并两个数组 + * @param string key 合并数组的参照值 + * @param array $array1 要合并数组 + * @param array $array2 要合并数组 + * @return array 返回合并的数组 + */ + public static function filterArrayWithKey($key, array $array1, array $array2) { + if (!$key || !$array1 || !$array2) { + return array(); + } + $array1 = self::rebuildArrayWithKey($key, $array1); + $array2 = self::rebuildArrayWithKey($key, $array2); + $tmp = array(); + foreach ($array1 as $key => $array) { + if (isset($array2[$key])) { + $tmp[$key] = array_merge($array, $array2[$key]); + } + } + return $tmp; + } + + /** + * 按指定KEY重新生成数组 + * @param string key 重新生成数组的参照值 + * @param array $array 要重新生成的数组 + * @return array 返回重新生成后的数组 + */ + public static function rebuildArrayWithKey($key, array $array) { + if (!$key || !$array) { + return array(); + } + $tmp = array(); + foreach ($array as $_array) { + if (isset($_array[$key])) { + $tmp[$_array[$key]] = $_array; + } + } + return $tmp; + } +} \ No newline at end of file diff --git a/wind/component/utility/WindFile.php b/wind/component/utility/WindFile.php new file mode 100644 index 00000000..2cf1795a --- /dev/null +++ b/wind/component/utility/WindFile.php @@ -0,0 +1,255 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 文件工具类 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindFile { + + /** + * @var string 以读的方式打开文件,具有较强的平台移植性 + */ + const READ = 'rb'; + + /** + * @var string 以读写的方式打开文件,具有较强的平台移植性 + */ + const READWRITE = 'rb+'; + + /** + * @var string 以写的方式打开文件,具有较强的平台移植性 + */ + const WRITE = 'wb'; + + /** + * @var string 以读写的方式打开文件,具有较强的平台移植性 + */ + const WRITEREAD = 'wb+'; + + /** + * @var string 以追加写入方式打开文件,具有较强的平台移植性 + */ + const APPEND_WRITE = 'ab'; + + /** + * @var string 以追加读写入方式打开文件,具有较强的平台移植性 + */ + const APPEND_WRITEREAD = 'ab+'; + + /** + * 保存文件 + * @param string $fileName 保存的文件名 + * @param mixed $data 保存的数据 + * @param boolean $isBuildReturn 是否组装保存的数据是return $params的格式,如果没有则以变量声明的方式保存 + * @param string $method 打开文件方式 + * @param boolean $ifLock 是否对文件加锁 + */ + public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { + Wind::import("COM:utility.WindString"); + $temp = " $value) { + if (!preg_match('/^\w+$/', $key)) continue; + $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; + } + $temp .= "\r\n?>"; + } else { + ($isBuildReturn) && $temp .= " return "; + $temp .= WindString::varToString($data) . ";\r\n?>"; + } + return self::write($fileName, $temp, $method, $ifLock); + } + + /** + * 写文件 + * + * @param string $fileName 文件绝对路径 + * @param string $data 数据 + * @param string $method 读写模式 + * @param bool $ifLock 是否锁文件 + * @param bool $ifCheckPath 是否检查文件名中的“..” + * @param bool $ifChmod 是否将文件属性改为可读写 + * @return int 返回写入的字节数 + */ + public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { + Wind::import("COM:utility.WindSecurity"); + $fileName = WindSecurity::escapePath($fileName); + touch($fileName); + if (!$handle = fopen($fileName, $method)) return false; + $ifLock && flock($handle, LOCK_EX); + $writeCheck = fwrite($handle, $data); + $method == self::READWRITE && ftruncate($handle, strlen($data)); + fclose($handle); + $ifChmod && chmod($fileName, 0777); + return $writeCheck; + } + + /** + * 读取文件 + * + * @param string $fileName 文件绝对路径 + * @param string $method 读取模式 + * @return string + */ + public static function read($fileName, $method = self::READ) { + Wind::import("COM:utility.WindSecurity"); + $fileName = WindSecurity::escapePath($fileName); + $data = ''; + if (false !== ($handle = fopen($fileName, $method))) { + flock($handle, LOCK_SH); + $data = fread($handle, filesize($fileName)); + fclose($handle); + } + return $data; + } + + /** + * 按目录删除文件 + * @param string $dir 目录 + * @param boolean $ifexpiled 是否过期 + * @return boolean + */ + public static function clearDir($dir, $ifexpiled = false) { + if (!$handle = @opendir($dir)) return false; + while (false !== ($file = readdir($handle))) { + if ('.' === $file[0] || '..' === $file[0]) continue; + $fullPath = $dir . DIRECTORY_SEPARATOR . $file; + if (is_dir($fullPath)) { + self::clearDir($fullPath, $ifexpiled); + } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { + self::delFile($fullPath); + } + } + closedir($handle); + false === $ifexpiled && rmdir($dir); + return true; + } + + /** + * 批量删除文件 + * @param string $path + * @param string $delDir + * @param int $level + * @return string + */ + public static function delFiles($path, $delDir = false, $level = 0) { + $path = rtrim($path, DIRECTORY_SEPARATOR); + if (!$handler = opendir($path)) { + return false; + } + while (false !== ($filename = readdir($handler))) { + if ("." != $filename && ".." != $filename) { + if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { + if (substr($filename, 0, 1) != '.') { + self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); + } + } else { + self::delFile($path . DIRECTORY_SEPARATOR . $filename); + } + } + } + closedir($handler); + true == $delDir && $level > 0 && rmdir($path); + return true; + } + + /** + * 取得文件的mime类型 + * @param string $fileName 文件名 + * @return string + */ + public static function getMimeType($fileName) { + $suffix = self::getFileSuffix($fileName); + $mimes = require rtrim(WIND_PATH, D_S) . D_S . 'component/utility/WindMimeTypes.php'; + if (isset($mimes[$suffix])) { + return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; + } else { + throw new WindException('Sorry, can not find the corresponding mime type of the file'); + } + return false; + } + + /** + * 取得目录的迭代 + * @param string $dir 目录名 + * @return DirectoryIterator + */ + public static function getDirectoryIterator($dir) { + return new DirectoryIterator($dir); + } + + /** + * 取得文件信息 + * @param unknown_type $fileName + * @return string|number + */ + public static function getFileInfo($fileName) { + if (false === is_file($fileName)) { + return array(); + } + $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); + $fileInfo['path'] = $fileName; + $fileInfo['size'] = filesize($fileName); + $fileInfo['ctime'] = filectime($fileName); + $fileInfo['atime'] = fileatime($fileName); + $fileInfo['mtime'] = filemtime($fileName); + $fileInfo['readable'] = is_readable($fileName); + $fileInfo['writable'] = is_writable($fileName); + $fileInfo['executable'] = is_executable($fileName); + $fileInfo['right'] = fileperms($fileName); + $fileInfo['group'] = filegroup($fileName); + $fileInfo['owner'] = fileowner($fileName); + $fileInfo['mime'] = self::getMimeType($fileName); + return $fileInfo; + } + + /** + * 取得目录信息 + * @param unknown_type $dir + * @return string|multitype: + */ + public static function getDirectoryInfo($dir) { + if (false !== is_dir($dir)) { + return array(); + } + return stat($dir); + } + + /** + * 删除文件 + * @param string $filename + * @return boolean + */ + public static function delFile($filename) { + return unlink($filename); + } + + /** + * 取得文件后缀 + * @param string $filename + * @return string + */ + public static function getFileSuffix($filename) { + $filename = explode($filename, '.'); + return $filename[count($filename) - 1]; + } + + /** + * 取得真实的目录 + * @param string $path 路径名 + * @return string + */ + public static function appendSlashesToDir($path) { + return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; + } + +} \ No newline at end of file diff --git a/wind/component/utility/WindMimeTypes.php b/wind/component/utility/WindMimeTypes.php new file mode 100644 index 00000000..d7407c27 --- /dev/null +++ b/wind/component/utility/WindMimeTypes.php @@ -0,0 +1,243 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +return $mimes = array( + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'asc' => 'text/plain', + 'au' => 'audio/basic', + 'avi' => 'video/x-msvideo', + 'bcpio' => 'application/x-bcpio', + 'bin' => 'application/macbinary', + 'bmp' => 'image/bmp', + 'c' => 'text/plain', + 'cc' => 'text/plain', + 'ccad' => 'application/clariscad', + 'cdf' => 'application/x-netcdf', + 'class' => 'application/octet-stream', + 'cpio' => 'application/x-cpio', + 'cpt' => 'application/mac-compactpro', + 'csh' => 'application/x-csh', + 'css' => 'text/css', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dms' => 'application/octet-stream', + 'doc' => 'application/msword', + 'drw' => 'application/drafting', + 'dvi' => 'application/x-dvi', + 'dwg' => 'application/acad', + 'dxf' => 'application/dxf', + 'dxr' => 'application/x-director', + 'eps' => 'application/postscript', + 'etx' => 'text/x-setext', + 'exe' => 'application/octet-stream', + 'ez' => 'application/andrew-inset', + 'f' => 'text/plain', + 'f90' => 'text/plain', + 'fli' => 'video/x-fli', + 'flv' => 'video/x-flv', + 'gif' => 'image/gif', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'h' => 'text/plain', + 'hdf' => 'application/x-hdf', + 'hh' => 'text/plain', + 'hqx' => 'application/mac-binhex40', + 'htm' => 'text/html', + 'html' => 'text/html', + 'ice' => 'x-conference/x-cooltalk', + 'ief' => 'image/ief', + 'iges' => 'model/iges', + 'igs' => 'model/iges', + 'ips' => 'application/x-ipscript', + 'ipx' => 'application/x-ipix', + 'jpe' => array( + 'image/jpeg', + 'image/pjpeg', + ), + 'jpeg' => array( + 'image/jpeg', + 'image/pjpeg', + ), + 'jpg' => array( + 'image/jpeg', + 'image/pjpeg', + ), + 'js' => 'application/x-javascript', + 'kar' => 'audio/midi', + 'latex' => 'application/x-latex', + 'lha' => 'application/octet-stream', + 'lsp' => 'application/x-lisp', + 'lzh' => 'application/octet-stream', + 'm' => 'text/plain', + 'man' => 'application/x-troff-man', + 'me' => 'application/x-troff-me', + 'mesh' => 'model/mesh', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mif' => 'application/vnd.mif', + 'mime' => 'www/mime', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp3' => array( + 'audio/mpeg', + 'audio/mpg', + ), + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpga' => 'audio/mpeg', + 'ms' => 'application/x-troff-ms', + 'msh' => 'model/mesh', + 'nc' => 'application/x-netcdf', + 'oda' => 'application/oda', + 'pbm' => 'image/x-portable-bitmap', + 'pdb' => 'chemical/x-pdb', + 'pdf' => array( + 'application/pdf', + 'application/x-download', + ), + 'pgm' => 'image/x-portable-graymap', + 'pgn' => 'application/x-chess-pgn', + 'png' => array( + 'image/png', + 'image/x-png', + ), + 'pnm' => 'image/x-portable-anymap', + 'pot' => 'application/mspowerpoint', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/mspowerpoint', + 'ppt' => array( + 'application/powerpoint', + 'application/vnd.ms-powerpoint', + ), + 'ppz' => 'application/mspowerpoint', + 'pre' => 'application/x-freelance', + 'prt' => 'application/pro_eng', + 'ps' => 'application/postscript', + 'qt' => 'video/quicktime', + 'ra' => 'audio/x-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'ras' => 'image/cmu-raster', + 'rgb' => 'image/x-rgb', + 'rm' => 'audio/x-pn-realaudio', + 'roff' => 'application/x-troff', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'rtf' => 'text/rtf', + 'rtx' => 'text/richtext', + 'scm' => 'application/x-lotusscreencam', + 'set' => 'application/set', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'silo' => 'model/mesh', + 'sit' => 'application/x-stuffit', + 'skd' => 'application/x-koan', + 'skm' => 'application/x-koan', + 'skp' => 'application/x-koan', + 'skt' => 'application/x-koan', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'snd' => 'audio/basic', + 'sol' => 'application/solids', + 'spl' => 'application/x-futuresplash', + 'src' => 'application/x-wais-source', + 'step' => 'application/STEP', + 'stl' => 'application/SLA', + 'stp' => 'application/STEP', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'swf' => 'application/x-shockwave-flash', + 't' => 'application/x-troff', + 'tar' => 'application/x-tar', + 'tcl' => 'application/x-tcl', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tr' => 'application/x-troff', + 'tsi' => 'audio/TSP-audio', + 'tsp' => 'application/dsptype', + 'tsv' => 'text/tab-separated-values', + 'txt' => 'text/plain', + 'unv' => 'application/i-deas', + 'ustar' => 'application/x-ustar', + 'vcd' => 'application/x-cdlink', + 'vda' => 'application/vda', + 'viv' => 'video/vnd.vivo', + 'vivo' => 'video/vnd.vivo', + 'vrml' => 'model/vrml', + 'wav' => 'audio/x-wav', + 'wrl' => 'model/vrml', + 'xbm' => 'image/x-xbitmap', + 'xlc' => 'application/vnd.ms-excel', + 'xll' => 'application/vnd.ms-excel', + 'xlm' => 'application/vnd.ms-excel', + 'xls' => array( + 'application/excel', + 'application/vnd.ms-excel', + 'application/msexcel', + ), + 'xlw' => 'application/vnd.ms-excel', + 'xml' => 'text/xml', + 'xpm' => 'image/x-xpixmap', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-pdb', + 'zip' => array( + 'application/x-zip', + 'application/zip', + 'application/x-zip-compressed', + ), + 'csv' => array( + 'text/x-comma-separated-values', + 'text/comma-separated-values', + 'application/octet-stream', + 'application/vnd.ms-excel', + 'text/csv', + 'application/csv', + 'application/excel', + 'application/vnd.msexcel', + ), + 'psd' => 'application/x-photoshop', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'php' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'tgz' => 'application/x-tar', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'rv' => 'video/vnd.rn-realvideo', + 'shtml' => 'text/html', + 'text' => 'text/plain', + 'log' => array( + 'text/plain', + 'text/x-log', + ), + 'xsl' => 'text/xml', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'word' => array( + 'application/msword', + 'application/octet-stream', + ), + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', +); + + diff --git a/wind/component/utility/WindPack.php b/wind/component/utility/WindPack.php new file mode 100644 index 00000000..e0b7aa6a --- /dev/null +++ b/wind/component/utility/WindPack.php @@ -0,0 +1,397 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPack { + /** + * @var string 使用正则打包 + */ + const STRIP_SELF = 'stripWhiteSpaceBySelf'; + /** + * @var string 利用php自身的函数打包 + */ + const STRIP_PHP = 'stripWhiteSpaceByPhp'; + /** + * @var string 通过token方式打包 + */ + const STRIP_TOKEN = 'stripWhiteSpaceByToken'; + private $packList = array(); + private $contentInjectionPosition; + private $contentInjectionCallBack = ''; + + /** + * 将指定文件类型且指定文件夹下的所指定文件打包成一个易阅读的文件, + * @param mixed $dir 要打包的目录 + * @param string $dst 文件名 + * @param string $packMethod 打包方式 + * @param boolean $compress 是否压缩 + * @param string $absolutePath 文件路径 + * @param array $ndir 不须要打包的目录 + * @param array $suffix 不永许打包的文件类型 + * @return string + */ + public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { + if (empty($dst) || empty($dir)) { + return false; + } + $suffix = is_array($suffix) ? $suffix : array( + $suffix); + if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { + return false; + } + $fileSuffix = WindFile::getFileSuffix($dst); + $replace = $compress ? ' ' : "\n"; + $content = implode($replace, $content); + $content = $this->callBack($content, $replace); + $content = $this->stripNR($content, $replace); + $content = $this->stripPhpIdentify($content, ''); + $content = $this->stripImport($content, ''); + $content = $this->getContentBySuffix($content, $fileSuffix, $replace); + WindFile::write($dst, $content); + return true; + } + + /** + * @param mixed $fileList + * @param string $dst + * @param method $packMethod + * @param boolean $compress + * @param string $absolutePath + * @return string|string + */ + public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { + if (empty($dst) || empty($fileList)) { + return false; + } + $content = array(); + $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); + $fileSuffix = WindFile::getFileSuffix($dst); + $replace = $compress ? ' ' : "\n"; + $content = implode($replace, $content); + $content = $this->callBack($content, $replace); + $content = $this->stripNR($content, $replace); + $content = $this->stripPhpIdentify($content, ''); + //$content = $this->stripImport($content, ''); + $content = $this->getContentBySuffix($content, $fileSuffix, $replace); + WindFile::write($dst, $content); + return true; + } + + /** + * 通过php自身方式去除指定文件的注释及空白 + * @param string $filename 文件名 + */ + public function stripWhiteSpaceByPhp($filename) { + return php_strip_whitespace($filename); + } + + /** + * 通过正则方式去除指定文件的注释及空白 + * @param string $filename + * @param boolean $compress + * @return string + */ + public function stripWhiteSpaceBySelf($filename, $compress = true) { + $content = $this->getContentFromFile($filename); + $content = $this->stripComment($content, ''); + return $this->stripSpace($content, ' '); + } + + /** + * 通过token方式去除指定文件的注释及空白 + * @param string $filename + * @return string + */ + public function stripWhiteSpaceByToken($filename) { + $content = $this->getContentFromFile($filename); + $compressContent = ''; + $lastToken = 0; + foreach (token_get_all($content) as $key => $token) { + if (is_array($token)) { + if (in_array($token[0], array( + T_COMMENT, + T_WHITESPACE, + T_DOC_COMMENT))) { + continue; + } + $compressContent .= ' ' . $token[1]; + } else { + $compressContent .= $token; + } + $lastToken = $token[0]; + } + return $compressContent; + } + + /** + * 从各个目录中取得对应的每个文件的内容 + * @param string $packMethod 打包方式 + * @param mixed $dir 目录名 + * @param string $absolutePath 绝对路径名 + * @param array $ndir 不须要打包的文件夹 + * @param array $suffix 不须要打包的文件类型 + * @param array $nfile 不须要打包的文件 + * @return array + */ + public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { + static $content = array(); + if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { + return false; + } + $dir = is_array($dir) ? $dir : array( + $dir); + foreach ($dir as $_dir) { + $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; + if (is_dir($_dir)) { + $handle = dir($_dir); + while (false != ($tmp = $handle->read())) { + $name = WindFile::appendSlashesToDir($_dir) . $tmp; + if (is_dir($name) && !in_array($tmp, $ndir)) { + $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); + } + if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { + $content[] = $this->$packMethod($name); + $this->setPackList($file, $name); + } + } + $handle->close(); + } + } + return $content; + } + + /** + * 从文件列表中取得对应的每个文件的内容 + * @param mixed $fileList + * @param method $packMethod + * @param string $absolutePath + * @return array: + */ + public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { + if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { + return array(); + } + $fileList = is_array($fileList) ? $fileList : array( + $fileList); + foreach ($fileList as $key => $value) { + if (is_array($value) && isset($value[1])) { + $parents = class_parents($value[1]); + $_fileList = $this->buildFileList($parents, $fileList); + $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); + $implements = class_implements($value[1]); + $_fileList = $this->buildFileList($implements, $fileList); + $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); + if (key_exists($key, $this->getPackList())) continue; + $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; + if (is_file($file)) { + $content[] = $this->$packMethod($file); + $this->setPackList($key, $value); + } + } + } + } + + /** + * 去除注释 + * @param string $content 要去除的内容 + * @param mixed $replace 要替换的文本 + * @return string + */ + public function stripComment($content, $replace = '') { + return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); + } + + /** + * 去除换行 + * @param string $content 要去除的内容 + * @param mixed $replace 要替换的文本 + * @return string + */ + public function stripNR($content, $replace = array('\n','\r\n','\r')) { + return preg_replace('/[\n\r]+/', $replace, $content); + } + + /** + * 去除空格符 + * @param string $content 要去除的内容 + * @param mixed $replace 要替换的文本 + * @return string + */ + public function stripSpace($content, $replace = ' ') { + return preg_replace('/[ ]+/', $replace, $content); + } + + /** + * 去除php标识 + * @param string $content + * @param mixed $replace + * @return string + */ + public function stripPhpIdentify($content, $replace = '') { + return preg_replace('/(?:<\?(?:php)*)|(\?>)/i', $replace, $content); + } + + /** + * 根据指定规则替换指定内容中相应的内容 + * @param string $content + * @param string $rule + * @param $mixed $replace + * @return string + */ + public function stripStrByRule($content, $rule, $replace = '') { + return preg_replace("/$rule/", $replace, $content); + } + + /** + * 去除多余的文件导入信息 + * @param string $content + * @param mixed $replace + * @return string + */ + public function stripImport($content, $replace = '') { + $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); + if ($matchs[1]) { + foreach ($matchs[1] as $key => $value) { + $name = substr($value, strrpos($value, '.') + 1); + if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { + $strip = str_replace(array( + '(', + ')'), array( + '\(', + '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; + $content = $this->stripStrByRule($content, $strip, $replace); + } + } + } + return $content; + } + + /** + * 取得被打包的文件列表 + * @return array: + */ + public function getPackList() { + return $this->packList; + } + + /** + *从文件读取内容 + * @param string $filename 文件名 + * @return string + */ + public function getContentFromFile($filename) { + if (is_file($filename)) { + $content = ''; + $fp = fopen($filename, "r"); + while (!feof($fp)) { + $line = fgets($fp); + if (in_array(strlen($line), array( + 2, + 3)) && in_array(ord($line), array( + 9, + 10, + 13))) continue; + $content .= $line; + } + fclose($fp); + return $content; + } + return false; + } + + /** + * 根据文件后缀得取对应的mime内容 + * @param string $content 要打包的内容内容 + * @param string $suffix 文件后缀类型 + * @param string $replace + * @return string + */ + public function getContentBySuffix($content, $suffix, $replace = ' ') { + switch ($suffix) { + case 'php': + $content = ''; + break; + default: + $content = ''; + break; + } + return $content; + } + + private function buildFileList($list, $fileList) { + $_temp = array(); + foreach ($list as $fileName) { + foreach ($fileList as $key => $value) { + if ($value[1] == $fileName) { + $_temp[$key] = $value; + break; + } + } + } + return $_temp; + } + + /** + * @param $contentInjectionCallBack the $contentInjectionCallBack to set + * @param string $position 调用位置(before|after) + * @author Qiong Wu + */ + public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { + if (!in_array($position, array( + 'before', + 'after'))) $position = 'before'; + $this->contentInjectionPosition = $position; + $this->contentInjectionCallBack = $contentInjectionCallBack; + } + + /** + * 回调函数调用 + * @param string $content + * @param string $replace + * @return string + */ + public function callBack($content, $replace = '') { + if ($this->contentInjectionCallBack !== '') { + $_content = call_user_func_array($this->contentInjectionCallBack, array( + $this->getPackList())); + if ($this->contentInjectionPosition == 'before') { + $content = $replace . $_content . $content; + } elseif ($this->contentInjectionPosition == 'after') { + $content .= $replace . $_content . $replace; + } + } + return $content; + } + + private function isValidatePackMethod($packMethod) { + return method_exists($this, $packMethod) && in_array($packMethod, array( + WindPack::STRIP_PHP, + WindPack::STRIP_SELF, + WindPack::STRIP_TOKEN)); + } + + /** + * 添加被打包的文件到列表 + * @param string $key + * @param string $value + */ + private function setPackList($key, $value) { + if (isset($this->packList[$key])) { + if (is_array($this->packList[$key])) { + array_push($this->packList[$key], $value); + } else { + $tmp_name = $this->packList[$key]; + $this->packList[$key] = array( + $tmp_name, + $value); + } + } else { + $this->packList[$key] = $value; + } + } +} diff --git a/wind/component/utility/WindSecurity.php b/wind/component/utility/WindSecurity.php new file mode 100644 index 00000000..974c76ca --- /dev/null +++ b/wind/component/utility/WindSecurity.php @@ -0,0 +1,262 @@ + 2010-12-21 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 字符、路径过滤等安全处理 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSecurity { + /** + * html转换输出 + * @param $param + * @return string + */ + public static function escapeHTML($str) { + return htmlspecialchars($str, ENT_QUOTES); + } + /** + * 过滤标签 + * @param $param + * @return string + */ + public static function stripTags($str, $allowTags = "") { + return strip_tags($str, $allowTags); + } + /** + * 路径转换 + * @param $fileName + * @param $ifCheck + * @return string + */ + public static function escapePath($fileName, $ifCheck = true) { + if (!self::_escapePath($fileName, $ifCheck)) { + throw new WindException('file name is illegal'); + } + return $fileName; + } + /** + * 目录转换 + * @param string $dir + * @return string + */ + public static function escapeDir($dir) { + $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); + return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); + } + /** + * 通用多类型转换 + * @param mixed $value + * @return mixed + */ + public static function escapeChar($value) { + if (is_array($value)) { + foreach ($value as $key => $sub) { + $value[$key] = self::escapeChar($sub); + } + } elseif (is_int($value)) { + $value = (int) $value; + } elseif (is_string($value)) { + $value = self::escapeString($value); + } + return $value; + } + /** + * 字符转换 + * @param string $string + * @return string + */ + public static function escapeString($string) { + $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', + "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', + "'" => ''')); + return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', + '&'), $string); + } + + /** + * 该函数可用于转义拥有特殊意义的字符,比如 SQL 中的 ( )、[ ] 以及 *。 + * @param string $string + * @return string + */ + public static function quotemeta($string) { + return quotemeta($string); + } + /** + * 对字符串转义 + * @param string $value + * @return string + */ + public function checkInputValue($value, $key = '') { + if (is_int($value)) { + $value = (int) $value; + } elseif (is_string($value)) { + $value = "'" . addslashes($value) . "'"; + } elseif (is_float($value)) { + $value = (float) $value; + } elseif (is_object($value) || is_array($value)) { + $value = "'" . addslashes(serialize($value)). "'"; + } + return $value; + } + /** + * 对cookie/post/get方式的值添加反斜线 + * @param string $str + * @return string + */ + public static function addSlashesForInput($str) { + if (!get_magic_quotes_gpc()) { + $str = addslashes($str); + } + return $str; + } + + /** + * 对从db或者file里面读取的内容添加反斜线 + * @return string + */ + public static function addSlashesForOutput($str) { + if (!get_magic_quotes_runtime()) { + $str = addslashes($str); + } + return $str; + } + + /** + * 添加反斜线,转义字符 + * @param mixed $value 要处理的数组 + * @param boolean $gpc 是否是get/cookie/post传递过来的值 + * @param boolean $df 是否是database/file传递过来的值 + * @return string + */ + public static function addSlashes($value, $gpc = false, $df = false) { + if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable) )) { + return $value; + } + if(is_string($value)){ + if (false === $gpc && true === $df) { + return self::addSlashesForOutput($value); + } + if (false === $df && true === $gpc) { + return self::addSlashesForInput($value); + } + return addslashes($value); + } + foreach($value as $key=>$_value){ + $value[$key] = self::addSlashes($_value,$gpc,$df); + } + return $value; + } + /** + * 去除反 斜线 + * @param mixed $array + * @return string + */ + public static function stripSlashes($value) { + if (!$value) return $value; + if (is_string($value)) return stripslashes($value); + if (!is_array($value) && !($value instanceof Traversable)) return $value; + foreach ($value as $key => $_value) { + $value[$key] = self::stripSlashes($_value); + } + return $value; + } + + /** + * 通用多类型混合转义函数 + * @param $var + * @param $strip + * @param $isArray + * @return mixture + */ + public static function sqlEscape($var, $strip = true, $isArray = false) { + if (is_array($var)) { + if (!$isArray) return " '' "; + foreach ($var as $key => $value) { + $var[$key] = trim(self::sqlEscape($value, $strip)); + } + return $var; + } elseif (is_numeric($var)) { + return " '" . $var . "' "; + } else { + return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; + } + } + /** + * 通过","字符连接数组转换的字符 + * @param $array + * @param $strip + * @return string + */ + public static function sqlImplode($array, $strip = true) { + return implode(',', self::sqlEscape($array, $strip, true)); + } + /** + * 组装单条 key=value 形式的SQL查询语句值 insert/update + * @param $array + * @param $strip + * @return string + */ + public static function sqlSingle($array, $strip = true) { + if (!is_array($array)) return ''; + $array = self::sqlEscape($array, $strip, true); + $str = ''; + foreach ($array as $key => $val) { + $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; + } + return $str; + } + /** + * 组装多条 key=value 形式的SQL查询语句 insert + * @param $array + * @param $strip + * @return string + */ + public static function sqlMulti($array, $strip = true) { + if (!is_array($array)) { + return ''; + } + $str = ''; + foreach ($array as $val) { + if (!empty($val) && is_array($val)) { + $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; + } + } + return $str; + } + /** + * 过滤SQL元数据,数据库对象(如表名字,字段等) + * @param $data 元数据 + * @param $tlists 白名单 + * @return string 经过转义的元数据字符串 + */ + public static function sqlMetadata($data ,$tlists=array()) { + if (empty($tlists) || !is_array($data , $tlists)) { + $data = str_replace(array('`', ' '), '',$data); + } + return ' `'.$data.'` '; + } + /** + * 私用路径转换 + * @param string $fileName + * @param boolean $ifCheck + * @return boolean + */ + private static function _escapePath($fileName, $ifCheck = true) { + $tmpname = strtolower($fileName); + $tmparray = array('://' => '', "\0" => ''); + $ifCheck && $tmparray['..'] = ''; + if (strtr($tmpname, $tmparray) != $tmpname) { + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/wind/component/utility/WindString.php b/wind/component/utility/WindString.php new file mode 100644 index 00000000..002a5660 --- /dev/null +++ b/wind/component/utility/WindString.php @@ -0,0 +1,234 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 字符串格式化 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindString { + const UTF8 = 'utf8'; + const GBK = 'gbk'; + /** + * 截取字符串 + * @param string $string 要截取的字符串编码 + * @param int $start 开始截取 + * @param int $length 截取的长度 + * @param string $charset 原妈编码 + * @param boolean $dot 是否显示省略号 + * @return string 截取后的字串 + */ + public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { + return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr($string, $start, $length, $dot); + } + /** + * 求取字符串长度 + * @param string $string 要计算的字符串编码 + * @param string $charset 原始编码 + * @return int + */ + public static function strlen($string, $charset = self::UTF8) { + $len = strlen($string); + $i = $count = 0; + while ($i < $len) { + ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; + $count++; + } + return $count; + } + /** + * 将变量的值转换为字符串 + * + * @param mixed $input 变量 + * @param string $indent 缩进 + * @return string + */ + public static function varToString($input, $indent = '') { + switch (gettype($input)) { + case 'string': + return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; + case 'array': + $output = "array(\r\n"; + foreach ($input as $key => $value) { + $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString($value, $indent . "\t"); + $output .= ",\r\n"; + } + $output .= $indent . ')'; + return $output; + case 'boolean': + return $input ? 'true' : 'false'; + case 'NULL': + return 'NULL'; + case 'integer': + case 'double': + case 'float': + return "'" . (string) $input . "'"; + } + return 'NULL'; + } + + public static function jsonEncode($value) { + if (!function_exists('json_encode')) { + Wind::import('Wind:component.utility.json.WindEncoder'); + return WindDecoder::decode($value); + } + return json_encode($value); + } + + public static function jsonDecode($value) { + if (!function_exists('json_decode')) { + Wind::import('Wind:component.utility.json.WindEncoder'); + return WindEncoder::encode($value); + } + return json_decode($value); + } + + public static function jsonSimpleEncode($var) { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + case 'NULL': + return 'null'; + case 'integer': + return (int) $var; + case 'double': + case 'float': + return (float) $var; + case 'string': + return '"' . addslashes(str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; + case 'array': + if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array(); + foreach ($var as $name => $value) { + $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode($value); + } + return '{' . join(',', $properties) . '}'; + } + $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); + return '[' . join(',', $elements) . ']'; + } + return false; + } + + /** + * 以utf8格式截取的字符串编码 + * @param string $string 要截取的字符串编码 + * @param int $start 开始截取 + * @param int $length 截取的长度 + * @param boolean $dot 是否显示省略号 + * @return string + */ + public static function utf8_substr($string, $start, $length = null, $dot = false) { + if (empty($string) || !is_int($start) || ($length && !is_int($length))) { + return ''; + } + $strlen = strlen($string); + $length = $length ? $length : $strlen; + $substr = ''; + $chinese = $word = 0; + for ($i = 0, $j = 0; $i < $start; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $chinese++; + $j += 2; + } else { + $word++; + } + $j++; + } + $start = $word + 3 * $chinese; + for ($i = $start, $j = $start; $i < $start + $length; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $substr .= substr($string, $j, 3); + $j += 2; + } else { + $substr .= substr($string, $j, 1); + } + $j++; + } + (strlen($substr) < $strlen) && $dot && $substr .= "..."; + return $substr; + } + /** + * 以utf8求取字符串长度 + * @param string $str 要计算的字符串编码 + * @return number + */ + public static function utf8_strlen($str) { + $i = $count = 0; + $len = strlen($str); + while ($i < $len) { + $chr = ord($str[$i]); + $count++; + $i++; + if ($i >= $len) break; + if ($chr & 0x80) { + $chr <<= 1; + while ($chr & 0x80) { + $i++; + $chr <<= 1; + } + } + } + return $count; + } + + /* 以gbk格式截取的字符串编码 + * @param string $string 要截取的字符串编码 + * @param int $start 开始截取 + * @param int $length 截取的长度 + * @param boolean $dot 是否显示省略号 + * @return string + */ + public static function gbk_substr($string, $start, $length = null, $dot = false) { + if (empty($string) || !is_int($start) || ($length && !is_int($length))) { + return ''; + } + $strlen = strlen($string); + $length = $length ? $length : $strlen; + $substr = ''; + $chinese = $word = 0; + for ($i = 0, $j = 0; $i < $start; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $chinese++; + $j++; + } else { + $word++; + } + $j++; + } + $start = $word + 2 * $chinese; + for ($i = $start, $j = $start; $i < $start + $length; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $substr .= substr($string, $j, 2); + $j++; + } else { + $substr .= substr($string, $j, 1); + } + $j++; + } + (strlen($substr) < $strlen) && $dot && $substr .= "..."; + return $substr; + } + + /** + * 以gbk求取字符串长度 + * @param string $str 要计算的字符串编码 + * @return number + */ + public static function gbk_strlen($string) { + $len = strlen($string); + $i = $count = 0; + while ($i < $len) { + ord($string[$i]) > 129 ? $i += 2 : $i++; + $count++; + } + return $count; + } +} \ No newline at end of file diff --git a/wind/component/utility/WindUtility.php b/wind/component/utility/WindUtility.php new file mode 100644 index 00000000..acaa99cd --- /dev/null +++ b/wind/component/utility/WindUtility.php @@ -0,0 +1,50 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindUtility { + + /** + * 获得随机数字符串 + * + * @param int $length + * @return string + */ + static function generateRandStr($length) { + $randstr = ""; + for ($i = 0; $i < (int) $length; $i++) { + $randnum = rand(0, 61); + if ($randnum < 10) { + $randstr .= chr($randnum + 48); + } else if ($randnum < 36) { + $randstr .= chr($randnum + 55); + } else { + $randstr .= chr($randnum + 61); + } + } + return $randstr; + } + + /** + * 通用组装测试验证规则 + * + * @param string $field | 验证字段名称 + * @param string $validator | 验证方法 + * @param array $args | 参数 + * @param string $default | 默认值 + * @param string $message | 错误信息 + * @return array + */ + static public function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { + return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, + 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); + } +} + +?> \ No newline at end of file diff --git a/wind/component/utility/WindValidator.php b/wind/component/utility/WindValidator.php new file mode 100644 index 00000000..67523f58 --- /dev/null +++ b/wind/component/utility/WindValidator.php @@ -0,0 +1,344 @@ + 2010-12-22 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindValidator { + + /** + * 验证是否是电话号码 + * 国际区号-地区号-电话号码的格式(在国际区号前可以有前导0和前导+号), + * 国际区号支持0-4位 + * 地区号支持0-6位 + * 电话号码支持4到12位 + * + * @param string $phone 被验证的电话号码 + * @return boolean + */ + public static function isTelPhone($phone) { + return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); + } + + /** + * 验证是否是手机号码 + * 国际区号-手机号码 + * + * @param string $number + * @return boolean + */ + public static function isTelNumber($number) { + return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); + } + + /** + * 验证是否是QQ号码 + * + * @param string $qq + * @return boolean + */ + public static function isQQ($qq) { + return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); + } + + /** + * 验证是否是邮政编码 + * + * @param string $zipcode + * @return boolean + */ + public static function isZipcode($zipcode) { + return 0 < preg_match('/^\d{4,8}$/', $zipcode); + } + + /** + * 验证是否是有合法的email + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasEmail($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的email + * @param string $string + * @return boolean + */ + public static function isEmail($string) { + return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); + } + + /** + * 验证是否有合法的身份证号 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasIdCard($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的身份证号 + * @param string $string + * @return boolean + */ + public static function isIdCard($string) { + return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); + } + + /** + * 验证是否有合法的URL + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasUrl($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的url + * @param string $string + * @return boolean + */ + public static function isUrl($string) { + return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); + } + + /** + * 验证是否有中文 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasChinese($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); + } + + /** + * 验证是否是中文 + * @param string $string + * @return boolean + */ + public static function isChinese($string) { + return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); + } + + /** + * 验证是否有html标记 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasHtml($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的html标记 + * @param string $string + * @return boolean + */ + public static function isHtml($string) { + return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); + } + + /** + * 验证是否有合法的ipv4地址 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasIpv4($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的IP + * @param string $string + * @return boolean + */ + public static function isIpv4($string) { + return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); + } + + /** + * 验证是否有合法的ipV6 + * + * @param string $string + * @param array $matches + * @param boolean $ifAll + * @return boolean + */ + public static function hasIpv6($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| + ::([a-f0-9]{1,4}:){5}| + ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| + (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| + (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| + (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| + (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: + )([a-f0-9]{1,4}:[a-f0-9]{1,4}| + (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} + ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) + )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| + (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: + ) + )\Z/ix', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的ipV6 + * + * @param string $string + * @return boolean + */ + public static function isIpv6($string) { + return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| + ::(?:[a-f0-9]{1,4}:){5}| + (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| + (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| + (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| + (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| + (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: + )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| + (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} + (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) + )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| + (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: + ) + )\Z/ix', $string); + } + + /** + * 验证是否有客户端脚本 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasScript($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的客户端脚本 + * @param string $string + * @return boolean + */ + public static function isScript($string) { + return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); + } + + /** + * 判断是否为空 + * @param string $value + * @return boolean + */ + public static function isEmpty($value) { + return empty($value); + } + + /** + * 验证是否是非负整数 + * @param int $number + * @return boolean + */ + public static function isNonNegative($number) { + return 0 <= (int) $number; + } + + /** + * 验证是否是正数 + * @param int $number + * @return boolean + */ + public static function isPositive($number) { + return 0 < (int) $number; + } + + /** + * 验证是否是负数 + * @param int $number + * @return boolean + */ + public static function isNegative($number) { + return 0 > (int) $number; + } + + /** + * 判断一个元素是否是数组 + * @param mixed $array + * @return boolean + */ + public static function isArray($array) { + return is_array($array); + } + + /** + * 验证是否是不能为空 + * + * @param mixed $value + * @return boolean + */ + public static function isRequired($value) { + return !self::isEmpty($value); + } + + /** + * 判断一个值是否在指定数组中 + * + * @param mixed $needle + * @param array $array + * @param boolean $strict + * @return boolean + */ + public static function inArray($needle, array $array, $strict = true) { + return in_array($needle, $array, $strict); + } + + /** + * 验证字符串的长度 + * @param string $string 要验证的字符串 + * @param string $length 指定的合法的长度 + * @param string $charset 字符编码 + * @return boolean + */ + public static function isLegalLength($string, $length, $charset = 'utf8') { + Wind::import('WIND:component.utility.WindString'); + return WindString::strlen($string, $charset) > (int) $length; + } + + /** + * 在 $string 字符串中搜索与 $regExp 给出的正则表达式相匹配的内容。 + * @param string $regExp 搜索的规则(正则) + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return number + */ + private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { + if (true === $ifAll) { + return preg_match_all($regExp, $string, $matches); + } + return preg_match($regExp, $string, $matches); + } + +} \ No newline at end of file diff --git a/wind/component/utility/date/WindDate.php b/wind/component/utility/date/WindDate.php new file mode 100644 index 00000000..7c714a28 --- /dev/null +++ b/wind/component/utility/date/WindDate.php @@ -0,0 +1,272 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * 日期的换算与计算 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindDate { + /** + * 获取时区 + * @return string + */ + public static function getTimeZone() { + return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); + } + /** + * 设置时区 + * @param string $timezone 时区 + */ + public static function setTimezone($timezone) { + function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); + } + /** + * 格式化输出 + * @param string $format 格式化 + * @param int $dateTime unix时间戳 + * @return string + */ + public static function format($format = null, $dateTime = null) { + return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); + } + /** + * 获取日期的某部分 + * @param string $interval 字符串表达式 ,时间间隔类型 + * @param mixed $dateTime 表示日期的文字 + * @return string 返回日期的某部分 + */ + public static function datePart($interval, $dateTime = null) { + return date($interval, self::getTimeStamp($dateTime)); + } + /** + * 获取两个日期的差 + * @param string $interval 返回两个日期差的间隔类型 + * @param mixed $startDateTime 开始日期 + * @param mixed $endDateTime 结束日期 + * @return string + */ + public static function dateDiff($interval, $startDateTime, $endDateTime) { + $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); + $retval = 0; + switch ($interval) { + case "y": + $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; + case "m": + $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; + case "w": + $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; + case "d": + $retval = bcdiv($diff, (60 * 60 * 24));break; + case "h": + $retval = bcdiv($diff, (60 * 60));break; + case "n": + $retval = bcdiv($diff, 60);break; + case "s": + default:$retval = $diff;break; + } + return $retval; + } + /** + * 返回向指定日期追加指定间隔类型的一段时间间隔后的日期 + * @param string $interval 字符串表达式,是所要加上去的时间间隔类型。 + * @param int $value 数值表达式,是要加上的时间间隔的数目。其数值可以为正数(得到未来的日期),也可以为负数(得到过去的日期)。 + * @param string $dateTime 表示日期的文字,这一日期还加上了时间间隔。 + * @param mixed $format 格式化输出 + * @return string 返回追加后的时间 + */ + public static function dateAdd($interval, $value, $dateTime, $format = null) { + $date = getdate(self::getTimeStamp($dateTime)); + switch ($interval) { + case "y": + $date["year"] += $value;break; + case "q": + $date["mon"] += ($value * 3);break; + case "m": + $date["mon"] += $value;break; + case "w": + $date["mday"] += ($value * 7);break; + case "d": + $date["mday"] += $value;break; + case "h": + $date["hours"] += $value;break; + case "n": + $date["minutes"] += $value;break; + case "s": + default:$date["seconds"] += $value;break; + } + return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); + } + /** + * 得到一年中每个月真实的天数 + * @param string $year 需要获得的月份天数的年份 + * @return array 每月的天数组成的数组 + */ + public static function getRealDaysInMonthsOfYear($year) { + $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + if (self::isLeapYear($year)) { + $months[1] = 29; + } + return $months; + } + /** + * 获取该月的天数 + * @param int $month 月份 + * @param int $year 年份 + * @return int + */ + public static function getDaysInMonth($month, $year) { + if (1 > $month || 12 < $month) { + return 0; + } + if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { + return 0; + } + return $daysInmonths[$month - 1]; + } + /** + * 获取该年的天数 + * @return int + */ + public static function getDaysInYear($year) { + return self::isLeapYear($year) ? 366 : 365; + } + /** + * 取得RFC格式的日期与时间 + * @return string + */ + public static function getRFCDate($date = null) { + $time = $date ? is_int($date) ? $date : strtotime($date) : time(); + $tz = date('Z', $time); + $tzs = ($tz < 0) ? '-' : '+'; + $tz = abs($tz); + $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; + return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); + } + /** + * 取得中国日期时间 + * @param int $time + * @return string + */ + public static function getChinaDate($time = null) { + list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); + return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); + } + /** + * 取得中国的星期 + * @param int $week 处国人的星期,是一个数值 + * @return string + */ + public static function getChinaWeek($week = null) { + $week = $week ? $week : (int) date('w', time()); + $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); + return $weekMap[$week]; + } + /** + * 取得一天中的时段 + * @param int $hour 小时 + * @return string + */ + public static function getPeriodOfTime($hour = null) { + $hour = $hour ? $hour : (int) date('G', time()); + $period = ''; + if (0 <= $hour && 6 > $hour) { + $period = '凌晨'; + } elseif (6 <= $hour && 8 > $hour) { + $period = '早上'; + } elseif (8 <= $hour && 11 > $hour) { + $period = '上午'; + } elseif (11 <= $hour && 13 > $hour) { + $period = '中午'; + } elseif (13 <= $hour && 15 > $hour) { + $period = '响午'; + } elseif (15 <= $hour && 18 > $hour) { + $period = '下午'; + } elseif (18 <= $hour && 20 > $hour) { + $period = '傍晚'; + } elseif (20 <= $hour && 22 > $hour) { + $period = '晚上'; + } elseif (22 <= $hour && 23 >= $hour) { + $period = '深夜'; + } + return $period; + } + /** + * 获取UTC日期格式 + * @param mixed $dateTime + * @return string + */ + public static function getUTCDate($dateTime = null) { + $oldTimezone = self::getTimezone(); + if ('UTC' !== strtoupper($oldTimezone)) { + self::setTimezone('UTC'); + } + $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); + if ('UTC' !== strtoupper($oldTimezone)) { + self::setTimezone($oldTimezone); + } + return $date; + } + /** + * 获取微秒数 + * @return number + */ + public static function getMicroTime($get_as_float = null,$mircrotime = null) { + return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); + } + /** + * 判断是否是闰年 + * @param int $year + * @return string + */ + public static function isLeapYear($year) { + if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { + return true; + } + return false; + } + public static function getTimeStamp($dateTime = null){ + return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); + } + + /** + * @param int $time 当前时间戳 + * @param int $timestamp 比较的时间戳 + * @param string $format 格式化当前时间戳 + * @param array $type 要返回的时间类型 + * @return array + */ + public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { + $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); + $timestamp = $timestamp ? $timestamp : time(); + $compareTime = strtotime(self::format('Y-m-d',$timestamp)); + $currentTime = strtotime(self::format('Y-m-d',$time)); + $decrease = $timestamp - $time; + $result = self::format($format,$time); + if (0 >= $decrease) { + return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); + } + if ($currentTime == $compareTime) { + if (1 == $type) { + if (60 >= $decrease) { + return array($decrease . $timelang['second'], $result); + } + return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); + } + return array(self::format('H:i',$time), $result); + } elseif ($currentTime == $compareTime - 86400) { + return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); + } elseif ($currentTime == $compareTime - 172800) { + return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); + } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { + return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); + } + return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); + } +} \ No newline at end of file diff --git a/wind/component/utility/date/WindGeneralDate.php b/wind/component/utility/date/WindGeneralDate.php new file mode 100644 index 00000000..3e52d67a --- /dev/null +++ b/wind/component/utility/date/WindGeneralDate.php @@ -0,0 +1,248 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * 是将日期转化为一个对象去操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +class WindGeneralDate { + /** + * @var int 填充展示 + */ + const FILL = 0; + /** + * @var int 数字展示 + */ + const DIGIT = 1; + /** + * @var int 文本展示 + */ + const TEXT = 2; + /** + * @var string 默认格式化 + */ + const DEFAULT_FORMAT = 'Y-m-d H:i:s'; + /** + * @var int unix时间戳 + */ + private $time = 0; + + /** + * 根据输入的日期格式转化为时间戳进行属性time初始化 + * + * mktime函数,在只有输入一个年份的时候,就会默认转化为上一年的最后一天,输入一个月份并且缺省输入day的时候, + * 会转化为上个月的最后一天。所以这种情况需要注意。 + * 如果该构造函数没有参数传入的时候,得到的日期不是期望的当前日期,而是上两年的11月的30日 + * + * 如果月份为空:如果年份为空,则取当前月份;否则取1 + * 如果日期为空:如果年份为空,则取当前日期,否则取1 + * 如果小时为空:如果年份为空,则取当前小时 + * 如果分为空:如果年份为空,则取当前分 + * 如果秒为空:如果年份为空,则取当前秒 + * 如果年份为空:取当前年份 + * + * @param int $year 年 + * @param int $month 月 + * @param int $day 日 + * @param int $hours 小时 + * @param int $minutes 分 + * @param int $second 秒 + */ + public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { + $time = time(); + !$month && ((!$year) ? $month = date('m', $time) : $month = 1); + !$day && ((!$year) ? $day = date('d', $time) : $day = 1); + !$hours && !$year && $hours = date('H', $time); + !$minutes && !$year && $minutes = date('i', $time); + !$second && !$year && $second = date('s', $time); + !$year && $year = date('Y', $time); + $this->time = mktime($hours, $minutes, $second, $month, $day, $year); + } + /** + * 获取当前时间所在月的天数 + * @return string + */ + public function getDaysInMonth() { + return date('t', $this->time); + } + /** + * 获取当前时间所在年的天数 + * @return int 如果是闰年返回366否则返回365 + */ + public function getDaysInYear() { + return $this->isLeapYear() ? 366 : 365; + } + /** + * 所表示当前日期是该年中的第几天。 + * @return int 返回时该年中的第几天 + */ + public function getDayOfYear() { + return date('z', $this->time) + 1; + } + /** + * 表示当前日期为该月中的第几天。 + * @return int + */ + public function getDayOfMonth() { + return date('j', $this->time); + } + /** + * 表示当前日期是该星期中的第几天。 + * @return int + */ + public function getDayOfWeek() { + return date('w', $this->time) + 1; + } + /** + * 判断当前日期所在年的第几周 + * @return int + */ + public function getWeekOfYear() { + return date('W', $this->time); + } + /** + * 获取当前日期的年份 + * @param boolean $format 是否返回四位格式的年份或是两位格式的年份 + * @return string + */ + public function getYear($format = true) { + return date($format ? 'Y' : 'y', $this->time); + } + /** + * 获当前日期的取月份 + * @param int $display 显示类型 + * @return string + */ + public function getMonth($display = self::FILL) { + if(self::FILL == $display){ + return date('m', $this->time); + }elseif(self::DIGIT == $display){ + return date('n', $this->time); + }elseif(self::TEXT == $display){ + return date('M', $this->time); + } + return date('n', $this->time); + } + /** + * 获取当前日期的天数 + * @param string $display 显示类型 + * @return string + */ + public function getDay($display = self::FILL) { + if(self::FILL == $display){ + return date('d', $this->time); + }elseif(self::DIGIT == $display){ + return date('j', $this->time); + }elseif(self::TEXT == $display){ + return date('jS', $this->time); + } + return date('j', $this->time); + } + /** + * 获取当前日期的星期 + * @param string $display 显示类型 + * @return string + */ + public function getWeek($display = self::FILL) { + if(self::FILL == $display || self::DIGIT == $display){ + return date('w', $this->time); + }elseif(self::TEXT == $display){ + return date('D', $this->time); + } + return date('N', $this->time); + } + /** + * 获取当前日期的12小时制时间 + * @param string $display 显示类型 + * @return string + */ + public function get12Hours($display = self::FILL){ + if(self::FILL == $display){ + return date('h', $this->time); + }elseif(self::DIGIT == $display){ + return date('g', $this->time);; + } + return date('h', $this->time); + } + /** + * 获取当前日期的24小时制时间 + * @param string $display 显示类型 + * @return string + */ + public function get24Hours($display = self::FILL){ + if(self::FILL == $display){ + return date('H', $this->time); + }elseif(self::DIGIT == $display){ + return date('G', $this->time);; + } + return date('H', $this->time); + } + /** + * 获取当前日期的分钟 + * @return string + */ + public function getMinutes() { + return date('i', $this->time); + } + /** + * 获取当前日期的秒数 + * @return string + */ + public function getSeconds() { + return date('s', $this->time); + } + /** + * 获取当前日期的本地时区 + * @return string + */ + public function getLocalTimeZone() { + return date('T', $this->time); + } + /** + * 重新设置当前日期与时间 + * @param string | int $time + */ + public function setTime($time) { + if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { + $this->time = $time; + } + } + /** + * 取得当前日期时间对象 + * @return WindDate + */ + public function getNow() { + $date = getdate($this->time); + return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); + } + /** + * 对象转化为字符串,魔术方法 + * @return string + */ + public function __toString() { + return $this->toString(); + } + /** + * 格式化时间输出 + * @param string $format 需要输出的格式 + * @return string + */ + public function toString($format = null) { + return date($format ? $format : self::DEFAULT_FORMAT, $this->time); + } + /** + * 判断是否是闰年 + * @return string 返回1或是0 + */ + public function isLeapYear() { + return date('L', $this->time); + } +} \ No newline at end of file diff --git a/wind/component/utility/json/WindDecoder.php b/wind/component/utility/json/WindDecoder.php new file mode 100644 index 00000000..17e3342b --- /dev/null +++ b/wind/component/utility/json/WindDecoder.php @@ -0,0 +1,235 @@ + +* @author Matt Knapp +* @author Brett Stimmerman +* @copyright 2005 Michal Migurski +* @license http://www.opensource.org/licenses/bsd-license.php +* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 +*/ + +/** + * CJSON converts PHP data to and from JSON format. + * + * @author Michal Migurski + * @author Matt Knapp + * @author Brett Stimmerman + * @version $Id$ + * @package system.web.helpers + * @since 1.0 + */ +class WindDecoder { + const JSON_SLICE = 1; + const JSON_IN_STR = 2; + const JSON_IN_ARR = 4; + const JSON_IN_OBJ = 8; + const JSON_IN_CMT = 16; + public static function decode($str, $useArray = true) { + $str = strtolower(self::reduceString($str)); + if ('true' == $str) { + return true; + } elseif ('false' == $str) { + return false; + } elseif ('null' == $str) { + return null; + } elseif (is_numeric($str)) { + return (float)$str == (integer)$str ? (integer) $str : (float) $str; + }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ + return self::jsonToString($str); + }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ + return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); + } + return false; + } + protected static function jsonToString($string) { + $delim = substr($string, 0, 1); + $chrs = substr($string, 1, -1); + $decodeStr = ''; + for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { + $compare = substr($chrs, $c, 2); + $ordCode = ord($chrs{$c}); + if('\b' == $compare){ + $decodeStr .= chr(0x08); + ++$c; + }elseif('\t' == $compare){ + $decodeStr .= chr(0x09); + ++$c; + }elseif('\n' == $compare){ + $decodeStr .= chr(0x0A); + ++$c; + }elseif('\f' == $compare){ + $decodeStr .= chr(0x0C); + ++$c; + }elseif('\r' == $compare){ + $decodeStr .= chr(0x0D); + ++$c; + }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ + if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { + $decodeStr .= $chrs{++$c}; + } + }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); + $decodeStr .= self::utf16beToUTF8($utf16); + $c += 5; + }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ + $decodeStr .= $chrs{$c}; + }elseif(0xC0 == ($ordCode & 0xE0)){ + $decodeStr .= substr($chrs, $c, 2); + ++$c; + }elseif(0xE0 == ($ordCode & 0xF0)){ + $decodeStr .= substr($chrs, $c, 3); + $c += 2; + }elseif(0xF0 == ($ordCode & 0xF8)){ + $decodeStr .= substr($chrs, $c, 4); + $c += 3; + }elseif(0xF8 == ($ordCode & 0xFC)){ + $decodeStr .= substr($chrs, $c, 5); + $c += 4; + }elseif(0xFC == ($ordCode & 0xFE)){ + $decodeStr .= substr($chrs, $c, 6); + $c += 5; + } + } + return $decodeStr; + } + protected static function jsonToArray($str) { + return self::complexConvert($str,true); + } + protected static function jsonToObject($str) { + return self::complexConvert($str,false); + } + protected static function complexConvert($str,$useArray = true){ + if ('[' == $str{0}) { + $stk = array(self::JSON_IN_ARR); + $arr = array(); + } else { + $obj = $useArray ? array() : new stdClass(); + $stk = array(self::JSON_IN_OBJ); + } + array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); + $chrs = substr($str, 1, -1); + $chrs = self::reduceString($chrs); + if ('' == $chrs) { + return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; + } + for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + if (reset($stk) == self::JSON_IN_ARR) { + array_push($arr, self::decode($slice, $useArray)); + } elseif (reset($stk) == self::JSON_IN_OBJ) { + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + $key = self::decode($parts[1], $useArray); + $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); + } + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { + array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { + array_pop($stk); + } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, + self::JSON_IN_ARR, self::JSON_IN_OBJ))) { + array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); + } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { + array_pop($stk); + } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, + self::JSON_IN_ARR, self::JSON_IN_OBJ))) { + array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { + array_pop($stk); + } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, + self::JSON_IN_ARR, self::JSON_IN_OBJ))) { + array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { + array_pop($stk); + for ($i = $top['where']; $i <= ++$c; ++$i){ + $chrs = substr_replace($chrs, ' ', $i, 1); + } + } + + } + if (self::JSON_IN_ARR == reset($stk)) { + return $arr; + } elseif (self::JSON_IN_OBJ == reset($stk)) { + return $obj; + } + return false; + } + + protected static function unicodeToUTF8(&$str) { + $utf8 = ''; + foreach ($str as $unicode) { + if ($unicode < 128) { + $utf8 .= chr($unicode); + } elseif ($unicode < 2048) { + $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); + $utf8 .= chr(128 + ($unicode % 64)); + } else { + $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); + $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); + $utf8 .= chr(128 + ($unicode % 64)); + } + } + return $utf8; + } + + protected static function reduceString($str) { + return trim(preg_replace(array( + '#^\s*//(.+)$#m', + '#^\s*/\*(.+)\*/#Us', + '#/\*(.+)\*/\s*$#Us'), + '', $str)); + } + + protected static function utf16beToUTF8(&$str) { + return self::unicodeToUTF8(unpack('n*', $str)); + } + +} \ No newline at end of file diff --git a/wind/component/utility/json/WindEncoder.php b/wind/component/utility/json/WindEncoder.php new file mode 100644 index 00000000..289a7b63 --- /dev/null +++ b/wind/component/utility/json/WindEncoder.php @@ -0,0 +1,202 @@ + +* @author Matt Knapp +* @author Brett Stimmerman +* @copyright 2005 Michal Migurski +* @license http://www.opensource.org/licenses/bsd-license.php +* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 +*/ + +/** + * CJSON converts PHP data to and from JSON format. + * + * @author Michal Migurski + * @author Matt Knapp + * @author Brett Stimmerman + * @version $Id$ + * @package system.web.helpers + * @since 1.0 + */ +class WindEncoder { + public static $charset = 'utf-8'; + /** + * @param mixed $var + * @return string + */ + public static function encode($value) { + switch (gettype($value)) { + case 'boolean': + return $value ? 'true' : 'false'; + case 'NULL': + return 'null'; + case 'integer': + return (int) $value; + case 'double': + case 'float': + return (float) $value; + case 'string': + return self::stringToJson($value); + case 'array': + return self::arrayToJson($value); + case 'object': + return self::objectToJson($value); + default: + return ''; + } + return ''; + } + /** + * 将字符串转化成json格式对象 + * @param string $string + * @return string + */ + protected static function stringToJson($string) { + if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { + $string = iconv($enc, 'UTF-8', $string); + } + $ascii = ''; + $strlen = strlen($string); + for ($c = 0; $c < $strlen; ++$c) { + $ordVar = ord($string{$c}); + if (0x08 == $ordVar) { + $ascii .= '\b'; + } elseif (0x09 == $ordVar) { + $ascii .= '\t'; + } elseif (0x0A == $ordVar) { + $ascii .= '\n'; + } elseif (0x0C == $ordVar) { + $ascii .= '\f'; + } elseif (0x0D == $ordVar) { + $ascii .= '\r'; + } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { + $ascii .= '\\' . $string{$c}; + } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { + $ascii .= $string{$c}; //ASCII + } elseif (0xC0 == ($ordVar & 0xE0)) { + $char = pack('C*', $ordVar, ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } elseif (0xE0 == ($ordVar & 0xF0)) { + $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } elseif (0xF0 == ($ordVar & 0xF8)) { + $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } elseif (0xF8 == ($ordVar & 0xFC)) { + $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } elseif (0xFC == ($ordVar & 0xFE)) { + $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } + } + return '"' . $ascii . '"'; + } + /** + * 将数组转化成json格式对象 + * @param array $array + * @return string + */ + protected static function arrayToJson(array $array) { + if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { + return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; + } + return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; + } + /** + * 将对象转化成json格式对象 + * @param string $object + * @return string + */ + protected static function objectToJson($object) { + if ($object instanceof Traversable) { + $vars = array(); + foreach ($object as $k => $v) { + $vars[$k] = $v; + } + } else { + $vars = get_object_vars($object); + } + return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; + } + + protected static function nameValue($name, $value) { + return self::encode(strval($name)) . ':' . self::encode($value); + } + + protected static function utf8ToUTF16BE(&$string, $bom = false) { + $out = $bom ? "\xFE\xFF" : ''; + if (function_exists('mb_convert_encoding')) { + return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); + } + $uni = self::utf8ToUnicode($string); + foreach ($uni as $cp) { + $out .= pack('n', $cp); + } + return $out; + } + + protected static function utf8ToUnicode(&$string) { + $unicode = $values = array(); + $lookingFor = 1; + for ($i = 0, $length = strlen($string); $i < $length; $i++) { + $thisValue = ord($string[$i]); + if ($thisValue < 128) { + $unicode[] = $thisValue; + } else { + if (count($values) == 0) { + $lookingFor = ($thisValue < 224) ? 2 : 3; + } + $values[] = $thisValue; + if (count($values) == $lookingFor) { + $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; + $values = array(); + $lookingFor = 1; + } + } + } + return $unicode; + } + +} \ No newline at end of file diff --git a/wind/config/components_config.php b/wind/config/components_config.php new file mode 100644 index 00000000..d6fe2660 --- /dev/null +++ b/wind/config/components_config.php @@ -0,0 +1,26 @@ + array('path' => 'WIND:core.web.WindWebApplication', 'scope' => 'request', + 'properties' => array('dispatcher' => array('ref' => 'dispatcher'))), + 'dispatcher' => array('path' => 'WIND:core.web.WindDispatcher', 'scope' => 'prototype'), + 'windLogger' => array('path' => 'WIND:component.log.WindLogger', 'scope' => 'request'), + 'forward' => array('path' => 'WIND:core.web.WindForward', 'scope' => 'prototype'), + 'urlBasedRouter' => array('path' => 'WIND:core.router.WindUrlBasedRouter', 'scope' => 'application', + 'config' => array('module' => array('url-param' => 'm', 'default-value' => 'default'), + 'controller' => array('url-param' => 'c', 'default-value' => 'index'), + 'action' => array('url-param' => 'a', 'default-value' => 'run'))), + 'urlHelper' => array('path' => 'WIND:core.web.WindUrlHelper', 'scope' => 'singleton', + 'properties' => array('windRouter' => array('ref' => 'urlBasedRouter')), + 'config' => array('url-pattern' => array('value' => '-/'), 'route-suffix' => array('value' => 'htm'), + 'route-param' => array('value' => 'r'))), + 'windView' => array('path' => 'WIND:core.viewer.WindView', 'scope' => 'prototype', + 'config' => array('template-dir' => array('value' => 'template'), 'template-ext' => array('value' => 'htm'), + 'is-cache' => array('value' => 'true'), 'cache-dir' => array('value' => 'cache'), + 'compile-dir' => array('value' => 'compile.template')), + 'properties' => array('viewResolver' => array('ref' => 'viewResolver'))), + 'viewResolver' => array('path' => 'WIND:core.viewer.WindViewerResolver', 'scope' => 'prototype', + 'properties' => array('urlHelper' => array('ref' => 'urlHelper'))), + 'template' => array('path' => 'WIND:core.viewer.compiler.WindViewTemplate', 'scope' => 'prototype', + 'config' => array('resource' => '')), + 'errorMessage' => array('path' => 'WIND:core.web.WindErrorMessage', 'scope' => 'prototype')); +?> \ No newline at end of file diff --git a/wind/config/components_config.xml b/wind/config/components_config.xml new file mode 100644 index 00000000..11dfa2f1 --- /dev/null +++ b/wind/config/components_config.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wind/core/AbstractWindServer.php b/wind/core/AbstractWindServer.php new file mode 100644 index 00000000..7be412be --- /dev/null +++ b/wind/core/AbstractWindServer.php @@ -0,0 +1,159 @@ + 2010-11-7 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindServer { + const METHOD_DELETE = "DELETE"; + const METHOD_HEAD = "HEAD"; + const METHOD_GET = "GET"; + const METHOD_OPTIONS = "OPTIONS"; + const METHOD_POST = "POST"; + const METHOD_PUT = "PUT"; + const METHOD_TRACE = "TRACE"; + private $request; + private $response; + + /** + * @throws Exception + */ + public function __construct() { + try { + Wind::import('WIND:core.request.WindHttpRequest'); + $this->request = new WindHttpRequest(); + $this->response = $this->request->getResponse(); + } catch (Exception $exception) { + throw new Exception('init action servlet failed!!'); + } + } + + /** + * 执行操作 + * @throws Exception + */ + public function run() { + if ($this->request === null || $this->response === null) { + throw new Exception('init action servlet failed!!'); + } + $this->beforeProcess($this->request, $this->response); + $this->service($this->request, $this->response); + $this->afterProcess($this->request, $this->response); + $this->response->sendResponse(); + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + */ + protected function beforeProcess(WindHttpRequest $request, WindHttpResponse $response) {} + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + */ + protected function afterProcess(WindHttpRequest $request, WindHttpResponse $response) {} + + /** + * 执行请求的操作 + */ + abstract protected function process(WindHttpRequest $request, WindHttpResponse $response); + + /** + * Receives standard HTTP requests from the public + * service method and dispatches + * them to the action methods defined in + * this class.There's no need to override this method. + * + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @throws Exception + */ + protected function service(WindHttpRequest $request, WindHttpResponse $response) { + $method = $request->getRequestMethod(); + if (strcasecmp($method, self::METHOD_GET) == 0) { + $this->doGet($request, $response); + } else if (strcasecmp($method, self::METHOD_POST) == 0) { + $this->doPost($request, $response); + } else if (strcasecmp($method, self::METHOD_PUT) == 0) { + $this->doPut($request, $response); + } else if (strcasecmp($method, self::METHOD_DELETE) == 0) { + $this->doDelete($request, $response); + } else if (strcasecmp($method, self::METHOD_HEAD) == 0) {} else if (strcasecmp($method, self::METHOD_OPTIONS) == 0) {} else if (strcasecmp($method, self::METHOD_TRACE) == 0) {} else { + $errMsg = 'your request method is not supported!!!'; + $response->sendError(WindHttpResponse::SC_METHOD_NOT_ALLOWED, $errMsg); + } + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @throws Exception + */ + protected function doPost(WindHttpRequest $request, WindHttpResponse $response) { + $protocol = $request->getProtocol(); + $msg = "The method post is not supported."; + if (!$protocol || (strpos($protocol, '1.1')) !== false) { + $response->sendError(WindHttpResponse::SC_METHOD_NOT_ALLOWED, $msg); + } else + $this->process($request, $response); + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @throws Exception + */ + protected function doGet(WindHttpRequest $request, WindHttpResponse $response) { + $protocol = $request->getProtocol(); + $msg = "The method get is not supported."; + if (!$protocol || (strpos($protocol, '1.1')) !== false) { + $response->sendError(WindHttpResponse::SC_METHOD_NOT_ALLOWED, $msg); + } else + $this->process($request, $response); + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @throws Exception + */ + protected function doPut(WindHttpRequest $request, WindHttpResponse $response) { + $this->process($request, $response); + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @throws Exception + */ + protected function doDelete(WindHttpRequest $request, WindHttpResponse $response) { + $this->process($request, $response); + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + */ + protected function doTrace(WindHttpRequest $request, WindHttpResponse $response) {} + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + */ + protected function doOptions(WindHttpRequest $request, WindHttpResponse $response) {} + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @throws Exception + */ + protected function doHead(WindHttpRequest $request, WindHttpResponse $response) {} +} \ No newline at end of file diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php new file mode 100644 index 00000000..56eca015 --- /dev/null +++ b/wind/core/WindComponentModule.php @@ -0,0 +1,101 @@ + + * @author Qiong Wu + * @version $Id: WindComponent.php 809 2010-12-22 11:28:28Z yishuo $ + * @package + */ +abstract class WindComponentModule extends WindModule { + private $_attribute = array(); + private $_config = null; + /** + * @var WindHttpRequest + */ + protected $request; + /** + * @var WindHttpResponse + */ + protected $response; + /** + * @var WindSystemConfig + */ + protected $windSystemConfig; + /** + * @var WindFactory + */ + protected $windFactory; + + /** + * Enter description here ... + */ + protected function getAutoSetProperty() { + return array( + 'request' => 'IWindRequest', + 'response' => 'IWindResponse', + 'windSystemConfig' => 'WindSystemConfig', + 'windFactory' => 'WindFactory'); + } + + /** + * Enter description here ... + */ + public function getAttribute($alias = '') { + if ($alias === '') + return $this->_attribute; + else + return isset($this->_attribute[$alias]) ? $this->_attribute[$alias] : null; + } + + /** + * @param string $alias + * @param object $object + */ + public function setAttribute($alias, $object = null) { + if (is_array($alias)) + $this->_attribute += $alias; + elseif (is_string($alias)) + $this->_attribute[$alias] = $object; + } + + /** + * 根据配置名取得相应的配置 + * + * @param string $configName 键名 + * @param string $subConfigName 二级键名 + * @param array $default 缺省的数组格式 + * @return string|array + */ + public function getConfig($configName = '', $subConfigName = '', $default = array()) { + if (null === $this->_config) return ''; + return $this->_config->getConfig($configName, $subConfigName, array(), $default); + } + + /** + * @param string|array|windConfig $config + */ + public function setConfig($config) { + if (is_object($config)) { + $this->_config = $config; + } elseif (is_array($config)) { + $this->_config = new WindConfig($config); + } elseif (is_string($config)) { + Wind::import('WIND:core.config.parser.WindConfigParser'); + $configParser = new WindConfigParser(); + $this->_config = new WindConfig($config, $configParser, get_class($this), CONFIG_CACHE); + } + } + + /** + * 更改现有的config 或是合并 + * @param array $config + * @param boolean 是否合并现有 + * @return true + */ + public function updateConfig($config, $merge = false) { + if (null === $this->_config) return false; + $this->_config->setConfig($config, $merge); + return true; + } +} \ No newline at end of file diff --git a/wind/core/WindEnableValidateModule.php b/wind/core/WindEnableValidateModule.php new file mode 100644 index 00000000..44812fec --- /dev/null +++ b/wind/core/WindEnableValidateModule.php @@ -0,0 +1,125 @@ + 2011-1-7 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:core.WindModule'); +/** + * 启用了自动验证器的WindModule基类 + * 注入:验证器/异常处理器 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class WindEnableValidateModule extends WindModule { + + protected $_validatorClass = 'WIND:component.utility.WindValidator'; + protected $errorController = ''; + protected $errorAction = ''; + + private $_validator = null; + + private $_errors = array(); + + private $_defaultMessage = 'the field validate fail.'; + + /** + * @return the $_errors + */ + public function getErrors() { + return $this->_errors; + } + + public function getErrorControllerAndAction() { + return array($this->errorController, $this->errorAction); + } + /** + * 返回验证规则 + * + * validator : required/not-required + * @return multitype:multitype:string + */ + protected function validateRules() { + return array(); + } + + /** + * 验证方法 + * + * @param array|WindModule $input + */ + public function validate(&$input) { + if (is_array($input)) + $this->validateArray($input); + elseif (is_object($input)) + $this->validateObject($input); + } + + /** + * 验证数组类型的输入 + * @param array $input + */ + private function validateArray(&$input) { + $rules = $this->validateRules(); + foreach ((array) $rules as $rule) { + $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; + $arg = (array) $rule['args']; + array_unshift($arg, $_input); + if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; + if ($rule['default'] === null) { + $this->_errors[$rule['field']] = $rule['message']; + continue; + } + $input[$rule['field']] = $rule['default']; + } + } + + /** + * 验证对象类型的输入 + * 需要设置set和get方式 + * + * @param object $input 传入需要验证的数据 + * + */ + private function validateObject(&$input) { + $rules = $this->validateRules(); + $methods = get_class_methods($input); + foreach ((array) $rules as $rule) { + $getMethod = 'get' . ucfirst($rule['field']); + $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; + $arg = (array) $rule['args']; + array_unshift($arg, $_input); + if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; + if ($rule['default'] === null) { + $this->_errors[$rule['field']] = $rule['message']; + continue; + } + $setMethod = 'set' . ucfirst($rule['field']); + in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); + } + } + + /** + * @param WindValidator $validator + */ + protected function setValidator($validator) { + $this->_validator = $validator; + } + + /** + * 返回验证器 + * @return WindValidator + */ + protected function getValidator() { + if ($this->_validator === null) { + $_className = Wind::import($this->_validatorClass); + Wind::import('WIND:core.factory.WindFactory'); + $this->_validator = WindFactory::createInstance($_className); + if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); + } + return $this->_validator; + } +} \ No newline at end of file diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php new file mode 100644 index 00000000..9c9cedf2 --- /dev/null +++ b/wind/core/WindHelper.php @@ -0,0 +1,32 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHelper { + + + /** + * 解析ControllerPath + * 返回解析后的controller信息,controller,module,app + * + * @param string $controllerPath + * @return array + */ + public static function resolveController($controllerPath) { + $_m = $_c = ''; + if (!$controllerPath) return array($_c, $_m); + if (false !== ($pos = strrpos($controllerPath, '.'))) { + $_m = substr($controllerPath, 0, $pos); + $_c = substr($controllerPath, $pos + 1); + } else { + $_c = $controllerPath; + } + return array($_c, $_m); + } +} +?> \ No newline at end of file diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php new file mode 100644 index 00000000..800f65ad --- /dev/null +++ b/wind/core/WindModule.php @@ -0,0 +1,128 @@ + + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2010 phpwind.com + * @license + */ + +/** + * 所有module的基础抽象类 + * 主要实现__get(), __set()等方法 + * 通过继承该类 + * + * @author Qiong Wu + * @version $Id$ + */ +abstract class WindModule { + + private $_classProxy = null; + + /** + * @param string $propertyName + * @param string $value + */ + public function __set($propertyName, $value) { + if (!$this->validatePropertyName($propertyName, $value)) return; + $this->$propertyName = $value; + } + + /** + * @param string $propertyName + */ + public function __get($propertyName) { + if (!$this->validatePropertyName($propertyName)) return null; + return $propertyName; + } + + /** + * 实现setter或者getter方法调用 + * + */ + public function __call($methodName, $args) { + $_propertyName = ''; + $_perfix = substr($methodName, 0, 3); + if (in_array($_perfix, array('set', 'get'))) { + $_propertyName = trim(substr($methodName, 3), '_'); + $_propertyName = strtolower(substr($_propertyName, 0, 1)) . substr($_propertyName, 1); + if (!$_propertyName || !in_array($_propertyName, (array) $this->getWriteTableForGetterAndSetter())) return; + switch ($_perfix) { + case 'set': + $this->$_propertyName = $args[0]; + break; + case 'get': + return $this->$_propertyName; + break; + default: + break; + } + } + } + + public function __clone() { + foreach ($this->getCloneProperty() as $value) { + $this->$value = clone $this->$value; + } + } + + /** + * Enter description here ... + * + * @return multitype: + */ + public function toArray() { + $class = new ReflectionClass(get_class($this)); + $properties = $class->getProperties(); + $vars = array(); + foreach ($properties as $property) { + $_propertyName = $property->name; + $vars[$_propertyName] = $this->$_propertyName; + } + return $vars; + } + + /** + * @return the $_classProxy + */ + public function getClassProxy() { + return ($this->_classProxy instanceof WindClassProxy) ? $this->_classProxy : null; + } + + /** + * @param WindClassProxy $classProxy + */ + public function setClassProxy($classProxy) { + $this->_classProxy = $classProxy->initClassProxy($this); + } + + /** + * 验证属性白名单 + */ + protected function validatePropertyName($propertyName, $value = null) { + $autoSetProperty = $this->getAutoSetProperty(); + if (empty($autoSetProperty)) return true; + + if (!key_exists($propertyName, $autoSetProperty)) return false; + //TODO add check for value + return true; + } + + /** + * Enter description here ... + */ + protected function getAutoSetProperty() { + return array(); + } + + /** + * 设置自动实现Getter/Setter方法的属性名称 + */ + protected function getWriteTableForGetterAndSetter() { + return array(); + } + + protected function getCloneProperty() { + return array(); + } + +} \ No newline at end of file diff --git a/wind/core/config/WindConfig.php b/wind/core/config/WindConfig.php new file mode 100644 index 00000000..c9277245 --- /dev/null +++ b/wind/core/config/WindConfig.php @@ -0,0 +1,151 @@ + 2010-12-21 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.WindModule'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindConfig extends WindModule { + + /* 配置解析信息 */ + protected $configParser = null; + + protected $cacheName; + + protected $append; + + protected $config = array(); + + /** + * @param string $config | 配置文件路径信息 + * @param string $configParser | 配置解析器 + * @param string $cacheName | 配置文件缓存文件名称 + * @param WindConfigParser $configParser | 配置解析器 + */ + public function __construct($config, $configParser = null, $cacheName = '', $append = false) { + $this->setConfigParser($configParser); + $this->setCacheName($cacheName); + $this->setAppend($append); + $this->initConfig($config); + } + + /** + * 根据配置名取得相应的配置 + * + * @param string $configName + * @param string $subConfigName + * @return string + */ + public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { + if (!$config) $config = $this->config; + if ($configName === '') return $config; + + $_config = $default; + if (isset($config[$configName])) { + $_config = $config[$configName]; + } + if ($subConfigName === '') return $_config; + + $_subConfig = $default; + if (is_array($_config) && isset($_config[$subConfigName])) { + $_subConfig = $_config[$subConfigName]; + } + return $_subConfig; + } + + /** + * 初始化配置文件对象,如果参数是非数据格式, + * 则该方法会尝试调用注册进来的配置解析器进行配置解析 + * 如果没有注册过任何配置解析器,则抛出异常 + * + * @param array $config + */ + protected function initConfig($config) { + if (!$config) return; + if (!is_array($config)) { + $config = $this->parseConfig($config, $this->getCacheName(), $this->getAppend()); + } + $this->setConfig($config); + } + + /** + * 解析配置信息,返回解析后的配置结果 + * @param string $config | 配置文件源路径 + * @param string $cacheName | 缓存文件名称 | key值 + * @param string $append | 配置缓存是否追加到该缓存文件下面 + * @return array + */ + protected function parseConfig($config, $cacheName, $append) { + if ($this->getConfigParser() === null) { + throw new WindException('configParser is null.'); + } + return $this->getConfigParser()->parse($config, $cacheName, $append); + } + + /** + * @param $config the $config to set + * @author Qiong Wu + */ + public function setConfig($config, $merage = false) { + if (!is_array($config)) throw new WindException('config error.'); + if ($merage) + $this->config = array_merge($this->config, $config); + else + $this->config = $config; + } + + /** + * @return WindConfigParser $configParser + */ + public function getConfigParser() { + return $this->configParser; + } + + /** + * @param WindConfigParser $configParser + * @author Qiong Wu + */ + public function setConfigParser($configParser) { + if ($this->configParser || $configParser == null) return; + $this->configParser = $configParser; + } + + /** + * @return the $cacheName + */ + public function getCacheName() { + return $this->cacheName; + } + + /** + * @return the $append + */ + public function getAppend() { + return $this->append; + } + + /** + * @param $cacheName the $cacheName to set + * @author Qiong Wu + */ + public function setCacheName($cacheName) { + $this->cacheName = $cacheName; + } + + /** + * @param $append the $append to set + * @author Qiong Wu + */ + public function setAppend($append) { + $this->append = $append; + } + +} \ No newline at end of file diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php new file mode 100644 index 00000000..0b878f47 --- /dev/null +++ b/wind/core/config/WindSystemConfig.php @@ -0,0 +1,213 @@ + 2010-12-21 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.config.WindConfig'); +/** + * 框架配置对象windConfig类, + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindSystemConfig extends WindConfig { + + /* 通用配置 */ + const CLASS_PATH = 'class'; + + const PATH = 'path'; + + const VALUE = 'value'; + + /* import 外部配置文件包含 */ + const IMPORTS = 'imports'; + + const IMPORTS_RESOURCE = 'resource'; + + const IMPORTS_IS_APPEND = 'is-append'; + + /* app 相关配置 */ + const WEB_APPS = 'web-apps'; + + const WEB_APP_ROOT_PATH = 'root-path'; + + const WEB_APP_FACTORY = 'factory'; + + const WEB_APP_FACTORY_CLASS_DEFINITION = 'class-definition'; + + const WEB_APP_FILTER = 'filters'; + + const WEB_APP_ROUTER = 'router'; + + const WEB_APP_MODULE = 'modules'; + + const WEB_APP_TEMPLATE = 'template'; + + protected $appName = ''; + + protected $imports = array(); + + /** + * Enter description here ... + * + * @param string $config + * @param WindConfigParser $configParser + * @param string $appName + */ + public function __construct($config, $configParser, $appName) { + $cacheName = $appName . '_config'; + $this->appName = $appName; + parent::__construct($config, $configParser, $cacheName); + } + + /* (non-PHPdoc) + * @see AbstractWindConfig::getConfig() + */ + public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { + $imports = parent::getConfig(self::IMPORTS); + if (key_exists($configName, (array) $imports)) { + return $this->parseImport($configName); + } + return parent::getConfig($configName, $subConfigName, $config, $default); + } + + /** + * @return the $appName + */ + public function getAppName() { + return $this->appName; + } + + /** + * 返回当前应用的启动脚本位置 + */ + public function getAppClass() { + $_config = $this->getConfig(self::WEB_APPS, $this->appName); + $_tmp = $this->getConfig(self::CLASS_PATH, '', $_config); + return $_tmp ? $_tmp : COMPONENT_WEBAPP; + } + + /** + * 返回应用路径信息 + * + * @return string + */ + public function getRootPath($appName = '') { + if ($appName === '') $appName = $this->appName; + + $_tmp = $appName . '_RootPath'; + if (!isset($this->$_tmp)) { + $appConfig = $this->getConfig(self::WEB_APPS, $appName); + if (isset($appConfig[self::WEB_APP_ROOT_PATH]) && !empty($appConfig[self::WEB_APP_ROOT_PATH])) + $rootPath = $appConfig[self::WEB_APP_ROOT_PATH]; + else + $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); + + //TODO 绝对路径相对路径判断,相对于webroot,支持自定义路径 + $this->$_tmp = $rootPath; + } + return $this->$_tmp; + } + + /** + * @param string $name + */ + public function getFactory($name = '') { + $_config = $this->getConfig(self::WEB_APPS, $this->appName); + return $this->getConfig(self::WEB_APP_FACTORY, $name, $_config); + } + + /** + * @param string $name + * @return array|string + */ + public function getFilters($name = '') { + $_config = $this->getConfig(self::WEB_APPS, $this->appName); + return $this->getConfig(self::WEB_APP_FILTER, $name, $_config); + } + + /** + * @param string $name + * @return array|string + */ + public function getRouter($name = '') { + $_config = $this->getConfig(self::WEB_APPS, $this->appName); + $_router = $this->getConfig(self::WEB_APP_ROUTER, $name, $_config); + return $_router ? $_router : COMPONENT_ROUTER; + } + + /** + * @param string $name + * @return array|string + */ + public function getModules($name = '') { + $_config = $this->getConfig(self::WEB_APPS, $this->appName); + return $this->getConfig(self::WEB_APP_MODULE, $name, $_config); + } + + /** + * @param string $name + * @return array|string + */ + public function getTemplate($name = '') { + return $this->getConfig(self::TEMPLATE, $name); + } + + /** + * @param string $name + * @return array|string + */ + public function getViewerResolvers($name = '') { + return $this->getConfig(self::VIEWER_RESOLVERS, $name); + } + + /** + * @param string $name + * @return Ambigous + */ + public function getApplications($name = '') { + return $this->getConfig(self::APPLICATIONS, $name); + } + + /** + * @param string $name + * @return Ambigous + */ + public function getErrorMessage($name = '') { + return $this->getConfig(self::ERROR, $name); + } + + /** + * @param name + * @param cacheName + * @param configPath + * @param append + */ + protected function parseImport($name) { + if (!isset($this->imports[$name])) { + $imports = $this->getConfig(self::IMPORTS); + if (!isset($imports[$name])) return array(); + $import = $imports[$name]; + $config = array(); + if (is_array($import) && !empty($import)) { + $configPath = Wind::getRealPath($import[self::IMPORTS_RESOURCE]); + if (!isset($import[self::IMPORTS_IS_APPEND]) || $import[self::IMPORTS_IS_APPEND] === 'true') { + $append = $this->cacheName; + } elseif ($import[self::IMPORTS_IS_APPEND] === 'false' || $import[self::IMPORTS_IS_APPEND] === '') { + $append = false; + } else { + $append = $import[self::IMPORTS_IS_APPEND]; + } + $cacheName = $append ? $name : $this->appName . '_' . $name . '_config'; + $config = $this->parseConfig($configPath, $cacheName, $append); + } + $this->imports[$name] = $config; + } + return $this->imports[$name]; + } + +} \ No newline at end of file diff --git a/wind/core/config/parser/IWindConfigParser.php b/wind/core/config/parser/IWindConfigParser.php new file mode 100644 index 00000000..bc42c3fb --- /dev/null +++ b/wind/core/config/parser/IWindConfigParser.php @@ -0,0 +1,27 @@ + 2010-12-30 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +interface IWindConfigParser { + + /** + * 解析文件,保存缓存,返回解析结果 + * + * 1、缺省的配置文件,采用XML格式解析返回 + * 2、如果输入的配置文件格式没有提供支持,则抛出异常 + * 3、根据格式进行解析 + * 4、参数三$isApp 用来配置该解析式组件格式的解析还是应用配置的解析, + * 如果是应用解析需要进行merge操作,如果是组件解析则不用 + * + * @param string $name 解析后保存的文件名字 + * @param string $configPath 待解析文件的绝对路径 + * @param boolean $isApp 判断是应用解析还是组件配置解析 + * @return array 解析成功返回的数据 + */ + public function parse($configPath, $alias = '', $append = ''); + +} \ No newline at end of file diff --git a/wind/core/config/parser/WindConfigParser.php b/wind/core/config/parser/WindConfigParser.php new file mode 100644 index 00000000..c7bdae44 --- /dev/null +++ b/wind/core/config/parser/WindConfigParser.php @@ -0,0 +1,206 @@ + + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindConfigParser implements IWindConfigParser { + /** + * 配置文件支持的格式白名单 + */ + const CONFIG_XML = 'XML'; + const CONFIG_PHP = 'PHP'; + const CONFIG_INI = 'INI'; + const CONFIG_PROPERTIES = 'PROPERTIES'; + const WIND_ROOT = 'wind'; + /** + * 配置解析对象队列 + * @var array object $configParser + */ + private $configParsers = array(); + + /** + * 初始化 + * 设置解析数据输出的编码方式 + * @param String $outputEncoding + */ + public function __construct() {} + + /** + * 解析组件的配置文件 + * + * 如果用户没有传入别名,则每次都执行解析 + * 如果用户传入别名,判断是否传入了追加的文件名 + * 如果传入了追加的文件名,则判断该文件的内容中是否存在以别名为key的值 + * 如果有该值则返回该值,否则继续 + * 如果没有传入追加的文件名,则判断该别名命名的缓存文件是否存在 + * 如果存在则返回该文件内容,否则继续 + * 如果没有传入别名,则继续 + * + * 如果该缓存文件不存在,则判断如果不是以追加的方式,并且已经存在该缓存文件,则返回该缓存文件 + * 如果都不存在,则执行解析,并根据是否追加的条件,进行追加或是新建。 + * + * @param string $configPath 待解析的文件路径 + * @param string $alias 解析后保存的key名 + * @param string $append 采用最佳的方法追加到$appandName指定的文件中 + * @return array 解析结果 + */ + public function parse($configPath, $alias = '', $append = '') { + $config = array(); + $alias = trim($alias); + $append = !$append ? '' : trim($append); + $alias && $cacheFileName = ($append ? $this->buildCacheFilePath($append) : $this->buildCacheFilePath($alias)); + if ($alias) { + $append && $config = $this->getCacheContent($cacheFileName); + if (isset($config[$alias]) && !$this->needCompiled()) { + return $config[$alias]; + } + } + if (!($configPath = trim($configPath))) throw new WindException('Please input the file path!'); + $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); + if (!$alias) return $result; + $config[$alias] = $result; + $this->saveConfigFile($cacheFileName, $config); + return $result; + } + + /** + * 获得缓存文件内容 + * + * @param string $file 缓存文件名 + * @return array 缓存文件内容 + */ + private function getCacheContent($file) { + $content = array(); + if (is_file($file)) $content = include ($file); + return is_array($content) ? $content : array(); + } + + /** + * 创建配置文件解析器 + * + * @access private + */ + private function createParser($type) { + switch ($type) { + case self::CONFIG_XML: + Wind::import("WIND:component.parser.WindXmlParser"); + return new WindXmlParser(); + break; + case self::CONFIG_INI: + Wind::import("WIND:component.parser.WindIniParser"); + return new WindIniParser(); + break; + case self::CONFIG_PROPERTIES: + Wind::import("WIND:component.parser.WindPropertiesParser"); + return new WindPropertiesParser(); + break; + default: + throw new WindException('init config parser error.'); + break; + } + } + + /** + * 执行解析并返回解析结果 + * 接收一个配置文件路径,根据路径信息初始化配置解析器,并解析该配置 + * 以数组格式返回配置解析结果 + * + * @param string $configFile 解析的文件路径 + * @return array 返回解析结果 + */ + private function doParser($configFile, $type) { + if (!$configFile) return array(); + if (!is_file($configFile)) throw new WindException('The file <' . $configFile . '> is not exists'); + if ($type == 'PHP') { + $config = include ($configFile); + return (isset($config['wind'])) ? $config['wind'] : $config; + } + if (!isset($this->configParsers[$type])) { + $this->configParsers[$type] = $this->createParser($type); + } + return $this->configParsers[$type]->parse($configFile); + } + + /** + * 返回是否需要执行解析 + * + * 如果是debug模式,则返回false, 进行每次都进行解析 + * 如果不是debug模式,则先判断是否设置了缓存模式 + * 如果没有设置缓存则返回false, 进行解析, + * 如果设置了缓存模式,则判断缓存文件是否存在 + * 如果该解析出来的文件不存在,则返回false, 执行解析 + * 否则返回true, 直接读取缓存 + * + * @param string $cacheFile 缓存文件路径 + * @return boolean false:需要进行解析, true:不需要进行解析,直接读取缓存文件 + */ + private function needCompiled() { + if (IS_DEBUG && is_dir(COMPILE_PATH)) return true; + return false; + } + + /** + * 获得文件的后缀,决定采用的是哪种配置格式, + * 如果传递的文件配置格式不在支持范围内,则抛出异常 + * + * @param string $configPath 配置文件路径 + * @return boolean : true 解析文件格式成功,解析失败则抛出异常 + */ + private function getConfigFormat($configPath) { + if ($configPath === '') return self::CONFIG_XML; + $format = strtoupper(trim(strrchr($configPath, '.'), '.')); + if (!in_array($format, $this->getConfigFormatList())) { + throw new WindException("The format of the config file doesn't sopported yet!"); + } + return $format; + } + + /** + * 保存成文件 + * + * @param string $filename 保存的文件名 + * @param array $data 需要保持的数据 + * @return boolean 保存成功则返回true,保存失败则返回false + */ + private function saveConfigFile($filename, $data) { + if (!$filename || !$data || !is_dir(COMPILE_PATH)) return false; + Wind::import('COM:utility.WindFile'); + return WindFile::savePhpData($filename, $data); + } + + /** + * 构造文件的路径 + * + * @param string $fileName 缓存文件的名字 + * @return string 返回缓存文件的$fileName的绝对路径 + */ + private function buildCacheFilePath($fileName) { + return rtrim(COMPILE_PATH, '/') . D_S . strtolower($fileName) . '.php'; + } + + /** + * 获得支持解析的配置文件格式的白名单 + * + * @return array 返回配置文件格式的白名单 + */ + private function getConfigFormatList() { + return array(self::CONFIG_XML, self::CONFIG_PHP, self::CONFIG_INI, self::CONFIG_PROPERTIES); + } + + /** + * 析构函数 + * + */ + public function __destruct() { + $this->configParser = array(); + } +} \ No newline at end of file diff --git a/wind/core/exception/WindActionException.php b/wind/core/exception/WindActionException.php new file mode 100644 index 00000000..83f8d858 --- /dev/null +++ b/wind/core/exception/WindActionException.php @@ -0,0 +1,52 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindActionException extends WindException { + + private $error; + + /** + * @param WindErrorMessage $error + */ + public function __construct($error) { + $this->setError($error); + parent::__construct(''); + } + + /** + * 自定义异常号的对应异常信息 + * + * @param int $code 异常号 + * @return string 返回异常号对应的异常组装信息原型 + */ + protected function messageMapper($code) { + $messages = array(); + + return isset($messages[$code]) ? $messages[$code] : '$message'; + } + + /** + * @return WindErrorMessage $error + */ + public function getError() { + return $this->error; + } + + /** + * @param WindErrorMessage $error + */ + public function setError($error) { + $this->error = $error; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/exception/WindCacheException.php b/wind/core/exception/WindCacheException.php new file mode 100644 index 00000000..649964bf --- /dev/null +++ b/wind/core/exception/WindCacheException.php @@ -0,0 +1,19 @@ + 2010-11-7 +*@link http://www.phpwind.com +*@copyright Copyright © 2003-2110 phpwind.com +*@license +*/ + +Wind::import('WIND:core.exception.WindException'); + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindCacheException extends WindException{ + +} \ No newline at end of file diff --git a/wind/core/exception/WindDaoException.php b/wind/core/exception/WindDaoException.php new file mode 100644 index 00000000..69cb36e5 --- /dev/null +++ b/wind/core/exception/WindDaoException.php @@ -0,0 +1,27 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindDaoException extends WindException { + + /** + * 自定义异常号的对应异常信息 + * + * @param int $code 异常号 + * @return string 返回异常号对应的异常组装信息原型 + */ + protected function messageMapper($code) { + $messages = array(); + + return isset($messages[$code]) ? $messages[$code] : '$message'; + } +} + +?> \ No newline at end of file diff --git a/wind/core/exception/WindException.php b/wind/core/exception/WindException.php new file mode 100644 index 00000000..a6bc5201 --- /dev/null +++ b/wind/core/exception/WindException.php @@ -0,0 +1,108 @@ + 2010-11-3 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 异常处理机制 + * + * the last known user to change this file in the repository <$LastChangedBy: weihu $> + * @author Qian Su + * @version $Id: WindException.php 37 2010-11-08 12:57:04Z weihu $ + * @package + */ +class WindException extends Exception { + + /* 类错误 */ + const ERROR_CLASS_NOT_EXIST = '100'; + + const ERROR_CLASS_TYPE_ERROR = '101'; + + const ERROR_CLASS_METHOD_NOT_EXIST = '102'; + + const ERROR_OBJECT_NOT_EXIST = '103'; + + /* 参数错误 */ + const ERROR_PARAMETER_TYPE_ERROR = '110'; + + /* 配置错误 */ + const ERROR_CONFIG_ERROR = '120'; + + /* 返回值类型错误 */ + const ERROR_RETURN_TYPE_ERROR = '130'; + + private $innerException = null; + + /** + * 异常构造函数 + * + * @param $message 异常信息 + * @param $code 异常代号 + * @param $innerException 内部异常 + */ + public function __construct($message = '', $code = 0, Exception $innerException = null) { + $message = $this->buildMessage($message, $code); + parent::__construct($message, $code); + $this->innerException = $innerException; + } + + /** + * 取得内部异常 + */ + public function getInnerException() { + return $this->innerException; + } + + /** + * 取得异常堆栈信息 + */ + public function getStackTrace() { + if ($this->innerException) { + $thisTrace = $this->getTrace(); + $class = __CLASS__; + $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); + foreach ($innerTrace as $trace) + $thisTrace[] = $trace; + return $thisTrace; + } else { + return $this->getTrace(); + } + return array(); + } + + /** + * 组装异常信息 + * + * 根据输入的异常号组装相对应的异常信息 + * + * @param string $message 用户自定义的信息 + * @param int $code 异常号 + * @return string 组装后的异常信息 + */ + public function buildMessage($message, $code) { + eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); + return $message; + } + + /** + * 自定义异常号的对应异常信息 + * + * @param int $code 异常号 + * @return string 返回异常号对应的异常组装信息原型 + */ + protected function messageMapper($code) { + $messages = array(self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', + self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', + self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , or the method is not exist.', + self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', + self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', + self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', + self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); + + return isset($messages[$code]) ? $messages[$code] : '$message'; + } + +} \ No newline at end of file diff --git a/wind/core/exception/WindFinalException.php b/wind/core/exception/WindFinalException.php new file mode 100644 index 00000000..f86995a8 --- /dev/null +++ b/wind/core/exception/WindFinalException.php @@ -0,0 +1,14 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFinalException extends WindException {} + +?> \ No newline at end of file diff --git a/wind/core/exception/WindSqlException.php b/wind/core/exception/WindSqlException.php new file mode 100644 index 00000000..b4b39f59 --- /dev/null +++ b/wind/core/exception/WindSqlException.php @@ -0,0 +1,119 @@ + 2010-11-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:core.exception.WindException'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSqlException extends WindException { + //TODO change exception message like WindException. + const DB_CONN_EMPTY = 200; + + const DB_CONN_FORMAT = 201; + + const DB_CONN_NOT_EXIST = 202; + + const DB_CONN_EXIST = 203; + + const DB_CONNECT_NOT_EXIST = 204; + + const DB_QUERY_EMPTY = 210; + + const DB_QUERY_LINK_EMPTY = 211; + + const DB_QUERY_FIELD_EMPTY = 212; + + const DB_QUERY_FIELD_EXIST = 213; + + const DB_QUERY_FIELD_FORMAT = 214; + + const DB_QUERY_INSERT_DATA = 215; + + const DB_QUERY_UPDATE_DATA = 216; + + const DB_QUERY_CONDTTION_FORMAT = 217; + + const DB_QUERY_GROUP_MATCH = 218; + + const DB_QUERY_LOGIC_MATCH = 219; + + const DB_QUERY_FETCH_ERROR = 220; + + const DB_QUERY_TRAN_BEGIN = 221; + + const DB_QUERY_COMPARESS_ERROR = 222; + + const DB_QUERY_COMPARESS_EXIST = 223; + + const DB_QUERY_WHERE_ERROR = 224; + + const DB_QUERY_JOIN_TYPE_ERROR = 225; + + const DB_TABLE_EMPTY = 240; + + const DB_EMPTY = 241; + + const DB_DRIVER_NOT_EXIST = 242; + + const DB_DRIVER_EXIST = 243; + + const DB_BUILDER_NOT_EXIST = 250; + + const DB_BUILDER_EXIST = 251; + + const DB_DRIVER_BUILDER_NOT_MATCH = 252; + + const DB_ADAPTER_NOT_EXIST = 260; + + const DB_ADAPTER_EXIST = 261; + + /** + * 重定义异常类型 + * + * @see WindException::messageMapper() + * @param int $code 异常号 + * @return string 最终输出异常信息的原型 + */ + protected function messageMapper($code) { + $messages = array( + self::DB_CONN_EMPTY => 'Database configuration is empty. \'$message\' ', + self::DB_CONN_FORMAT => 'Database configuration format is incorrect. \'$message\' ', + self::DB_CONN_NOT_EXIST => '\'$message\' The identify of the database connection does not exist. ', + self::DB_CONN_EXIST => '\'$message\' The identify of the database connection is aleady exist.', + self::DB_CONNECT_NOT_EXIST => '\'$message\' The database connection does not exist.', + self::DB_QUERY_EMPTY => 'Query is empty. \'$message\'', + self::DB_QUERY_LINK_EMPTY => '\'$message\' Query link is not a validate resource.', + self::DB_QUERY_FIELD_EMPTY => '\'$message\' Query field is empty.', + self::DB_QUERY_FIELD_EXIST => '\'$message\' Query field is not exist.', + self::DB_QUERY_FIELD_FORMAT => 'Inside the field in the query not formatted correctly. \'$message\'', + self::DB_QUERY_INSERT_DATA => 'The new data is empty. \'$message\'', + self::DB_QUERY_UPDATE_DATA => 'The Updated data is empty. \'$message\'', + self::DB_QUERY_CONDTTION_FORMAT => 'The conditions of query are not right. \'$message\'', + self::DB_QUERY_GROUP_MATCH => '\'$message\' Query group does not match.', + self::DB_QUERY_LOGIC_MATCH => '\'$message\' Query logic does not match.', + self::DB_QUERY_FETCH_ERROR => 'The wrong way to obtain the result set. \'$message\'', + self::DB_QUERY_TRAN_BEGIN => 'Transaction has not started. \'$message\'', + self::DB_QUERY_COMPARESS_ERROR => 'Query comparison is incorrect conversion or assembly. \'$message\'', + self::DB_QUERY_COMPARESS_EXIST => 'Comparison does not exist query. \'$message\'', + self::DB_QUERY_WHERE_ERROR => 'Query where is Error. \'$message\'', + self::DB_QUERY_JOIN_TYPE_ERROR => 'The database is wrong type of join query. \'$message\'', + self::DB_TABLE_EMPTY => 'Table is empty. \'$message\'', + self::DB_EMPTY => 'Database is empty. \'$message\'', + self::DB_DRIVER_NOT_EXIST => 'The database driver does not exist. \'$message\'', + self::DB_DRIVER_EXIST => 'The database driver is aleady exist. \'$message\'', + self::DB_BUILDER_NOT_EXIST => 'The database builder does not exist. \'$message\'', + self::DB_BUILDER_EXIST => 'The database builder is aleady exist. \'$message\'', + self::DB_ADAPTER_NOT_EXIST => 'The database adapter does not exist. \'$message\'', + self::DB_ADAPTER_EXIST => 'The database adapter is aleady exist. \'$message\'', + self::DB_DRIVER_BUILDER_NOT_MATCH => '\'$message\' The database driver does not match with the builder. ', + ); + return isset($messages[$code]) ? $messages[$code] : '$message'; + } +} \ No newline at end of file diff --git a/wind/core/exception/WindViewException.php b/wind/core/exception/WindViewException.php new file mode 100644 index 00000000..2a51b3a5 --- /dev/null +++ b/wind/core/exception/WindViewException.php @@ -0,0 +1,29 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewException extends WindException { + + const VIEW_NOT_EXIST = '300'; + + /** + * 自定义异常号的对应异常信息 + * + * @param int $code 异常号 + * @return string 返回异常号对应的异常组装信息原型 + */ + protected function messageMapper($code) { + $messages = array(self::VIEW_NOT_EXIST => 'Not exist view template file or Incorrect file path \'$message\'.'); + + return isset($messages[$code]) ? $messages[$code] : '$message'; + } +} + +?> \ No newline at end of file diff --git a/wind/core/factory/IWindFactory.php b/wind/core/factory/IWindFactory.php new file mode 100644 index 00000000..14d4c508 --- /dev/null +++ b/wind/core/factory/IWindFactory.php @@ -0,0 +1,39 @@ + 2010-12-30 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 类工厂接口定义 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindFactory { + + /** + * 描述:根据类的别名获得一个类实例变量 + * 返回:类的实例对象 + * + * 该方法首先通过类的别名到类的配置文件中找到类的相关配置信息, + * 加载类的路径并创建类的依赖 + * + * @param string $classAlias + */ + public function getInstance($classAlias); + + /** + * 根据类名称创建类对象 + * 返回一个类类型的实例对象,通过此方法创建类实例,并不能自动获取类路径信息 + * + * @param string $className | 类名称 + * @param array $args | 类参数信息 + * @return Object | 返回的类类型的实例对象 + */ + static public function createInstance($className, $args = array()); + +} \ No newline at end of file diff --git a/wind/core/factory/WindClassDefinition.php b/wind/core/factory/WindClassDefinition.php new file mode 100644 index 00000000..7f1a5066 --- /dev/null +++ b/wind/core/factory/WindClassDefinition.php @@ -0,0 +1,440 @@ + 2010-12-31 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.WindModule'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * + * 配置文件格式: + * + * + * + * + * + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindClassDefinition extends WindModule { + + /* 配置信息定义 */ + const NAME = 'name'; + + const PATH = 'path'; + + const FACTORY_METHOD = 'factory-method'; + + const INIT_METHOD = 'init-method'; + + const SCOPE = 'scope'; + + const PROPERTIES = 'properties'; + + const CONSTRUCTOR_ARG = 'constructor-arg'; + + const REF = 'ref'; + + const VALUE = 'value'; + + /* 支持的类命名空间 */ + const SCOPE_SINGLETON = 'singleton'; + + const SCOPE_PROTOTYPE = 'prototype'; + + const SCOPE_REQUEST = 'request'; + + /** + * 类名称 + * @var string + */ + protected $className = ''; + + /** + * 类别名 + * @var string + */ + protected $alias = ''; + + /** + * 类路径 + * @var string + */ + protected $path = ''; + + /** + * 类的存储空间 + * singleton/prototype/request/session + * @var string + */ + protected $scope = ''; + + /** + * 类自定义的初始化方法 + * @var string + */ + protected $factoryMethod = ''; + + /** + * 类设置属性之后的调用处理操作 + * @var string + */ + protected $initMethod = ''; + + /** + * 构造参数定义 + * @var array + */ + protected $constructArgs = array(); + + /** + * 类属性定义 + * @var array + */ + protected $propertys = array(); + + /** + * 类定义 + * @var array + */ + protected $classDefinition; + + /** + * @var prototype + */ + private $prototype = null; + + /** + * @var instance + */ + private $instance = null; + + /** + * 根据类定义信息,初始化类对象 + * + * @param array $classDefinition + */ + public function __construct($classDefinition = array()) { + $this->init($classDefinition); + } + + /** + * 通过对象工厂创建单例对象 + * 如果用户配置有factory-method项,则调用该组件的该方法生成实例 + * 如果用户配置的该项方法不存在,则正常调用 + * + * @modified xiaoxia.xu + * @param IWindFactory $factory + * @return instance|Ambigous |NULL + */ + public function getInstance($factory, $args = array()) { + if (($instance = $this->executeFactoryMethod($args)) != null) return $instance; + switch ($this->scope) { + case 'prototype': + return $this->createInstanceWithPrototype($factory, $args); + case 'request': + return $this->createInstanceWithRequest($factory, $args); + case 'application': + return $this->createInstanceWithApplication($factory, $args); + default: + return $this->createInstanceWithSingleton($factory, $args); + } + } + + /** + * @param IWindFactory $factory + * @param array $args + * @return NULL|object + */ + protected function createInstanceWithApplication($factory, $args) { + if (!isset($factory->application)) return null; + if (null === $factory->application->getAttribute($this->getAlias())) { + $factory->application->setAttribute($this->getAlias(), $this->createInstanceWithPrototype($factory, $args)); + } + return $factory->application->getAttribute($this->getAlias()); + } + + /** + * @param IWindFactory $factory + * @param array $args + * @return NULL|object + */ + protected function createInstanceWithRequest($factory, $args) { + if (!isset($factory->request)) return null; + if (null === $factory->request->getAttribute($this->getAlias(), null)) { + $factory->request->setAttribute($this->getAlias(), $this->createInstanceWithPrototype($factory, $args)); + } + return $factory->request->getAttribute($this->getAlias()); + } + + /** + * @param IWindFactory $factory + * @param array $args + * @return NULL|object + */ + protected function createInstanceWithPrototype($factory, $args) { + if ($this->prototype === null) { + $instance = $this->createInstance($factory, $args); + $this->setProperties($this->getPropertys(), $factory, $instance); + $this->executeInitMethod($instance); + $this->setPrototype($instance); + } + return clone $this->prototype; + } + + /** + * @param IWindFactory $factory + * @param array $args + * @return NULL|object + */ + protected function createInstanceWithSingleton($factory, $args) { + if (!isset($this->instance)) { + $this->instance = $this->createInstanceWithPrototype($factory, $args); + } + return $this->instance; + } + + /** + * + * @modified xiaoxia.xu + * @param AbstractWindFactory $factory + * @param array $args + */ + protected function createInstance($factory, $args = array()) { + $instance = null; + if (empty($args)) { + $args = $this->setProperties($this->getConstructArgs(), $factory); + } + $instance = $factory->createInstance($this->getClassName(), $args); + + return $instance; + } + + /** + * Enter description here ... + * @param instance + * @param proxy + */ + private function setPrototype($instance) { + if ($this->prototype === null) { + if (($instance instanceof WindModule) && (null !== ($proxy = $instance->getClassProxy()))) + $this->prototype = $proxy; + else + $this->prototype = $instance; + } + } + + /** + * 执行用户配置的初始化操作 + * + * @author xiaoxia.xu + * @param object $instance + */ + private function executeInitMethod($instance) { + if (!($initMethod = $this->getInitMethod())) return; + if (!in_array($initMethod, get_class_methods($instance))) throw new WindException(get_class($instance) . '->' . $initMethod, WindException::ERROR_CLASS_METHOD_NOT_EXIST); + $instance->$initMethod(); + } + + /** + * 将类实例的依赖注入到类实例中 + * @param array $subDefinitions | 类定义 + * @param AbstractWindFactory $factory | 抽象的类工厂 + * @param object $instance | 类实例 + */ + private function setProperties($subDefinitions, $factory, $instance = null) { + $_temp = array(); + foreach ($subDefinitions as $key => $subDefinition) { + if (isset($subDefinition[self::REF])) + $_temp[$key] = $factory->getInstance($subDefinition[self::REF]); + elseif (isset($subDefinition[self::VALUE])) + $_temp[$key] = $subDefinition[self::VALUE]; + if ($instance !== null) { + call_user_func_array(array($instance, 'set' . ucfirst(trim($key, '_'))), array($_temp[$key])); + } + } + return $_temp; + } + + /** + * Enter description here ... + * + * @param array $args + * @throws WindException + * @return NULL|mixed + */ + private function executeFactoryMethod($args) { + if (!($factoryMethod = $this->getFactoryMethod())) return null; + if (!in_array($factoryMethod, get_class_methods($this->getClassName()))) throw new WindException($this->getClassName() . '->' . $factoryMethod, WindException::ERROR_CLASS_METHOD_NOT_EXIST); + return call_user_func_array(array($this->getClassName(), $factoryMethod), $args); + } + + /** + * 初始化类定义 + * @param array $classDefinition + */ + protected function init($classDefinition) { + if (empty($classDefinition)) return; + if (isset($classDefinition[self::NAME])) $this->setAlias($classDefinition[self::NAME]); + if (isset($classDefinition[self::PATH])) $this->setPath($classDefinition[self::PATH]); + if (isset($classDefinition[self::SCOPE])) $this->setScope($classDefinition[self::SCOPE]); + if (isset($classDefinition[self::FACTORY_METHOD])) $this->setFactoryMethod($classDefinition[self::FACTORY_METHOD]); + if (isset($classDefinition[self::INIT_METHOD])) $this->setInitMethod($classDefinition[self::INIT_METHOD]); + if (isset($classDefinition[self::PROPERTIES])) $this->setPropertys($classDefinition[self::PROPERTIES]); + if (isset($classDefinition[self::CONSTRUCTOR_ARG])) $this->setConstructArgs($classDefinition[self::CONSTRUCTOR_ARG]); + $this->setClassDefinition($classDefinition); + } + + /** + * @return the $className + */ + public function getClassName() { + if (!$this->className) { + $this->className = Wind::import($this->getPath()); + } + return $this->className; + } + + /** + * @return the $alias + */ + public function getAlias() { + return $this->alias; + } + + /** + * @return the $path + */ + public function getPath() { + return $this->path; + } + + /** + * @return the $scope + */ + public function getScope() { + return $this->scope; + } + + /** + * @param string $className the $className to set + * @author Qiong Wu + */ + public function setClassName($className) { + $this->className = $className; + } + + /** + * @param string $alias the $alias to set + * @author Qiong Wu + */ + public function setAlias($alias) { + $this->alias = $alias; + } + + /** + * @param string $path the $path to set + * @author Qiong Wu + */ + public function setPath($path) { + $this->path = $path; + } + + /** + * @param string $scope the $scope to set + * @author Qiong Wu + */ + public function setScope($scope) { + $this->scope = strtolower($scope); + } + + /** + * @return the $constructArgs + */ + public function getConstructArgs() { + return $this->constructArgs; + } + + /** + * @return the $propertys + */ + public function getPropertys() { + return $this->propertys; + } + + /** + * @return the $classDefinition + */ + public function getClassDefinition() { + return $this->classDefinition; + } + + /** + * @param array $constructArgs the $constructArgs to set + * @author Qiong Wu + */ + public function setConstructArgs($constructArgs) { + if (is_array($constructArgs) && !empty($constructArgs)) $this->constructArgs += $constructArgs; + } + + /** + * @param array $propertys the $propertys to set + * @author Qiong Wu + */ + public function setPropertys($propertys) { + if (is_array($propertys) && !empty($propertys)) $this->propertys += $propertys; + } + + /** + * @param array $classDefinition the $classDefinition to set + * @author Qiong Wu + */ + public function setClassDefinition($classDefinition) { + $this->classDefinition = $classDefinition; + } + + /** + * return the $factoryMethod + * + * @author xiaoxia.xu + * @return the $factoryMethod + */ + public function getFactoryMethod() { + return $this->factoryMethod; + } + + /** + * return the $initMethod + * + * @author xiaoxia.xu + * @return the $initMethod + */ + public function getInitMethod() { + return $this->initMethod; + } + + /** + * the $factoryMethod to set + * + * @author xiaoxia.xu + * @param string $factoryMethod + */ + public function setFactoryMethod($factoryMethod) { + $this->factoryMethod = $factoryMethod; + } + + /** + * the $initMethod to set + * + * @author xiaoxia.xu + * @param string $initMethod + */ + public function setInitMethod($initMethod) { + $this->initMethod = $initMethod; + } + +} \ No newline at end of file diff --git a/wind/core/factory/WindComponentDefinition.php b/wind/core/factory/WindComponentDefinition.php new file mode 100644 index 00000000..605684a9 --- /dev/null +++ b/wind/core/factory/WindComponentDefinition.php @@ -0,0 +1,156 @@ + 2010-12-31 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.factory.WindClassDefinition'); +Wind::import('WIND:core.config.parser.WindConfigParser'); +Wind::import('WIND:core.config.WindConfig'); +/** + * 组件定义 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindComponentDefinition extends WindClassDefinition { + + /* 配置 */ + const CONFIG = 'config'; + + const RESOURCE = 'resource'; + + /* 是否支持隐藏变量 */ + const HIDDEN_PRO = 'hidden-pro'; + + /* component 定义 */ + + const PROXY = 'proxy'; + + protected $proxyClass = 'WIND:core.factory.proxy.WindClassProxy'; + + /** + * 类代理对象定义 + * + * @var string + */ + protected $proxy = ''; + + protected $hiddenPro = ''; + + /** + * @var array + */ + protected $config = array(); + + /* (non-PHPdoc) + * @see WindClassDefinition::createInstance() + */ + protected function createInstance($factory, $args = array()) { + $instance = parent::createInstance($factory, $args); + if (!($instance instanceof WindComponentModule)) return $instance; + $windConfig = null; + if (isset($this->config[self::RESOURCE]) && ($resource = $this->config[self::RESOURCE])) { + $configPath = Wind::getRealPath($resource); + $windConfig = new WindConfig($configPath, new WindConfigParser(), $this->getAlias(), WIND_CONFIG_CACHE); + } else { + $windConfig = new WindConfig($this->config); + } + $instance->setConfig($windConfig); + $this->setHiddenProperty($instance, $factory); + $this->setProxyForClass($instance, $factory); + return $instance; + } + + /** + * 设置组件对象的隐藏属性 + */ + protected function setHiddenProperty($instance, $factory) { + if ($this->getHiddenPro() === 'false') return; + if (isset($factory->request)) { + $instance->windSystemConfig = $factory->request->getAttribute(WindFrontController::WIND_CONFIG); + $instance->windFactory = $factory->request->getAttribute(WindFrontController::WIND_FACTORY); + $instance->request = $factory->request; + } + if (isset($factory->response)) $instance->response = $factory->response; + } + + /** + * 为类设置代理 + * + * @param WindModule $instance + * @param WindFactory $factory + */ + protected function setProxyForClass($instance, $factory) { + if (!($proxyPath = $this->getProxy()) || $proxyPath === 'false') return; + $proxyPath = ($proxyPath === 'true' || $proxyPath === true) ? $this->proxyClass : $this->getProxy(); + $proxyClass = Wind::import($proxyPath); + if (!class_exists($proxyClass)) return; + + $proxyClass = $factory->createInstance($proxyClass); + if ($proxyClass instanceof WindClassProxy) $instance->setClassProxy($proxyClass); + } + + /* (non-PHPdoc) + * @see WindClassDefinition::init() + */ + protected function init($classDefinition) { + parent::init($classDefinition); + if (isset($classDefinition[self::CONFIG])) { + $this->config = $classDefinition[self::CONFIG]; + } + if (isset($classDefinition[self::PROXY])) { + $this->setProxy($classDefinition[self::PROXY]); + } + if (isset($classDefinition[self::HIDDEN_PRO])) { + $this->setHiddenPro($classDefinition[self::HIDDEN_PRO]); + } + } + + /** + * @return the $proxy + */ + public function getProxy() { + return $this->proxy; + } + + /** + * @param string $proxy + */ + public function setProxy($proxy) { + $this->proxy = $proxy; + } + + /** + * @return the $hiddenPro + */ + public function getHiddenPro() { + return $this->hiddenPro; + } + + /** + * @param field_type $hiddenPro + */ + public function setHiddenPro($hiddenPro) { + $this->hiddenPro = $hiddenPro; + } + + /** + * @return the $config + */ + public function getConfig() { + return $this->config; + } + + /** + * @param array $config + */ + public function setConfig($config) { + $this->config = $config; + } + +} \ No newline at end of file diff --git a/wind/core/factory/WindComponentFactory.php b/wind/core/factory/WindComponentFactory.php new file mode 100644 index 00000000..9f6e722b --- /dev/null +++ b/wind/core/factory/WindComponentFactory.php @@ -0,0 +1,18 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindComponentFactory extends WindFactory { + + protected $classDefinitionType = 'WIND:core.factory.WindComponentDefinition'; + +} + +?> \ No newline at end of file diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php new file mode 100644 index 00000000..043b2d3d --- /dev/null +++ b/wind/core/factory/WindFactory.php @@ -0,0 +1,141 @@ + 2010-11-29 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.factory.IWindFactory'); +/** + * Wind容器基类,创建类对象(分为两种模式,一种是普通模式,一种为单利模式) + * + * 职责: + * 类创建 + * 统一类接口访问 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFactory implements IWindFactory { + + protected $classDefinitionType = 'WIND:core.factory.WindClassDefinition'; + + protected $_classDefinitions = array(); + + protected $classDefinitions = array(); + + protected $classAlias = array(); + + protected $cache = ''; + + /** + * 初始化抽象工厂类 + * 可以通过两种方式初始化该工厂 + * 1. 直接传递一个解析好的类配置信息 + * + * @param string $configFile + */ + public function __construct($classDefinitions = array()) { + $this->loadClassDefinitions($classDefinitions); + } + + /* (non-PHPdoc) + * @see AbstractWindFactory::getInstance() + */ + public function getInstance($alias) { + $classDefinition = $this->getClassDefinitionByAlias($alias); + if (!($classDefinition instanceof WindClassDefinition)) { + return null; + } + /*@var $classDefinition WindClassDefinition */ + $args = func_get_args(); + unset($args[0]); + return $classDefinition->getInstance($this, $args); + } + + /* (non-PHPdoc) + * @see AbstractWindFactory::createInstance() + */ + static public function createInstance($className, $args = array()) { + if (!$className) return null; + if (strpos($className, ':') !== false) $className = Wind::import($className); + if (!$className || !class_exists($className)) { + throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); + } + $reflection = new ReflectionClass($className); + if ($reflection->isAbstract() || $reflection->isInterface()) return null; + return call_user_func_array(array($reflection, 'newInstance'), (array) $args); + } + + /** + * Enter description here ... + * + * @param string $classAlias + * @return boolean + */ + public function isSingled($classAlias) { + $classDefinition = $this->getClassDefinitionByAlias($classAlias); + return isset($classDefinition[self::CLASS_SINGLE]) && $classDefinition[self::CLASS_SINGLE] === 'false'; + } + + /** + * 获得类定义对象 + * + * @param string $classAlias + * @return WindClassDefinition + */ + public function getClassDefinitionByAlias($classAlias) { + if (!isset($this->classAlias[$classAlias]) && isset($this->_classDefinitions[$classAlias])) { + $definition = $this->_classDefinitions[$classAlias]; + $classDefinition = self::createInstance($this->classDefinitionType, array($definition)); + $classDefinition->setAlias($classAlias); + $this->addClassDefinitions($classDefinition); + return $classDefinition; + } + return $this->classDefinitions[$this->classAlias[$classAlias]]; + } + + /** + * Enter description here ... + * + * @param WindClassDefinition|array $classDefinition + */ + public function addClassDefinitions($classDefinition) { + if ($classDefinition instanceof WindClassDefinition) { + $className = $classDefinition->getClassName(); + $alias = $classDefinition->getAlias(); + $this->classDefinitions[$className] = $classDefinition; + $this->classAlias[$alias] = $className; + } elseif (is_array($classDefinition)) { + foreach ($classDefinition as $value) + $this->addClassDefinitions($value); + } + } + + /** + * Enter description here ... + * + * @param array $classDefinitions + * @throws WindException + */ + protected function loadClassDefinitions($classDefinitions) { + if (!is_array($classDefinitions)) { + throw new WindException($classDefinitions, WindException::ERROR_PARAMETER_TYPE_ERROR); + } + $this->_classDefinitions = $classDefinitions; + } + + /** + * 类定义检查 + * + * @param array $definition + * @return string + */ + protected function checkClassDefinition($definition) { + //TODO check class definition + return true; + } + +} \ No newline at end of file diff --git a/wind/core/factory/proxy/IWindClassProxy.php b/wind/core/factory/proxy/IWindClassProxy.php new file mode 100644 index 00000000..9e362fa1 --- /dev/null +++ b/wind/core/factory/proxy/IWindClassProxy.php @@ -0,0 +1,53 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindClassProxy { + + const EVENT_TYPE_METHOD = 'method'; + + /** + * Enter description here ... + * + * @var unknown_type + * @deprecated + */ + const EVENT_TYPE_SETTER = 'setter'; + + /** + * Enter description here ... + * + * @var unknown_type + * @deprecated + */ + const EVENT_TYPE_GETTER = 'getter'; + + /** + * Enter description here ... + * @return ReflectionClass + */ + public function _getReflection(); + + /** + * Enter description here ... + */ + public function _getInstance(); + + /** + * Enter description here ... + * + * @param string $event + * @param Object $listener + * @param string $type + */ + public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD); + +} + +?> \ No newline at end of file diff --git a/wind/core/factory/proxy/WindClassProxy.php b/wind/core/factory/proxy/WindClassProxy.php new file mode 100644 index 00000000..3295f4b3 --- /dev/null +++ b/wind/core/factory/proxy/WindClassProxy.php @@ -0,0 +1,257 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindClassProxy implements IWindClassProxy { + + protected $_attributes = array(); + + protected $_className = ''; + + protected $_classPath = ''; + + protected $_reflection = null; + + protected $_instance = null; + + protected $_listener = array(); + + private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; + + /** + * Enter description here ... + * + * @param string|object $targetObj + */ + public function __construct($targetObj = null, $args = array()) { + $this->initClassProxy($targetObj, $args); + } + + /* (non-PHPdoc) + * @see IWindClassProxy::registerAspect() + */ + public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { + //TODO add Logger + if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { + throw new WindException('incorrect registerType ' . $type); + } + if (!isset($this->_listener[$type])) $this->_listener[$type] = array(); + if (!isset($this->_listener[$type][$event])) $this->_listener[$type][$event] = array(); + array_push($this->_listener[$type][$event], $listener); + } + + /** + * Enter description here ... + * + * @param string $propertyName + * @param $value + */ + public function _setProperty($propertyName, $value) { + $this->_getInstance()->$propertyName = $value; + return true; + } + + /** + * Enter description here ... + * + * @param string $propertyName + * @param $value + * @throws WindException + * @deprecated + */ + public function __set($propertyName, $value) { + $property = $this->_getReflection()->getProperty($propertyName); + if (!$property || !$property->isPublic()) { + throw new WindException('undefined property name. '); + } + + $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); + if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); + + $interceptorChain = $this->_getInterceptorChain($propertyName); + $interceptorChain->addInterceptors($listeners); + $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); + return $interceptorChain->getHandler()->handle($value); + } + + /** + * Enter description here ... + * + * @param string $propertyName + */ + public function _getProperty($propertyName) { + return $this->_getInstance()->$propertyName; + } + + /** + * Enter description here ... + * + * @param unknown_type $propertyName + * @deprecated + */ + public function __get($propertyName) { + $property = $this->_getReflection()->getProperty($propertyName); + if (!$property || !$property->isPublic()) { + throw new WindException('undefined property name. '); + } + + $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); + if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); + + $interceptorChain = $this->_getInterceptorChain($propertyName); + $interceptorChain->addInterceptors($listeners); + $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); + return $interceptorChain->getHandler()->handle($propertyName); + } + + /** + * Enter description here ... + * + * @param string $methodName + * @param array $args + * @throws WindException + */ + public function __call($methodName, $args) { + $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); + if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); + + $interceptorChain = $this->_getInterceptorChain($methodName); + $interceptorChain->addInterceptors($listeners); + $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); + return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); + } + + /** + * 初始化类代理对象 + * + * @param string|object $targetObject + * @param array $args + * @throws WindException + */ + public function initClassProxy($targetObject, $args = array()) { + if ($targetObject === null) return null; + if (is_object($targetObject)) { + $this->_setClassName(get_class($targetObject)); + $this->_instance = $targetObject; + } elseif (is_string($targetObject) && !empty($targetObject)) { + if (!class_exists($targetObject)) throw new WindException($targetObject, WindException::ERROR_CLASS_NOT_EXIST); + $this->_setClassName($targetObject); + } + if ($this->_reflection === null) { + $reflection = new ReflectionClass($this->_className); + if ($reflection->isAbstract() || $reflection->isInterface()) return; + $this->_reflection = $reflection; + } + if ($this->_instance === null) { + $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); + } + return $this; + } + + /** + * Enter description here ... + */ + private function _getInterceptorChain($event = '') { + $interceptorChain = WindFactory::createInstance($this->_interceptorChain); + if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { + $interceptorChain->setAttribute($this->_getAttribute()); + $interceptorChain->setAttribute('instance', $this->_getInstance()); + $interceptorChain->setAttribute('event', array($this->_getClassName(), $event)); + return $interceptorChain; + } else + throw new WindException('unable to create interceptorChain.'); + } + + /** + * Enter description here ... + */ + private function _getListenerByType($type, $subType) { + $listener = array(); + if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { + $listener = $this->_listener[$type][$subType]; + } + return $listener; + } + + /* (non-PHPdoc) + * @see IWindClassProxy::_getInstance() + */ + public function _getInstance() { + return $this->_instance; + } + + /* (non-PHPdoc) + * @see IWindClassProxy::_getReflection() + */ + public function _getReflection() { + if ($this->_reflection instanceof ReflectionClass) + return $this->_reflection; + else + throw new WindException(get_class($this) . '->_reflection, ' . gettype($this->_reflection), WindException::ERROR_CLASS_TYPE_ERROR); + } + + /** + * @return the $_className + */ + public function _getClassName() { + return $this->_className; + } + + /** + * @return the $_classPath + */ + public function _getClassPath() { + return $this->_classPath; + } + + /** + * @param string $className + */ + public function _setClassName($className) { + $this->_className = $className; + } + + /** + * @param string $classPath + */ + public function _setClassPath($classPath) { + $this->_setClassName(Wind::import($classPath)); + $this->_classPath = $classPath; + } + + /** + * Enter description here ... + * + * @param unknown_type $alias + * @return multitype:|Ambigous + */ + public function _getAttribute($alias = '') { + if ($alias === '') + return $this->_attributes; + else + return isset($this->_attributes[$alias]) ? $this->_attributes[$alias] : null; + } + + /** + * Enter description here ... + * + * @param unknown_type $alias + * @param unknown_type $object + */ + public function _setAttribute($alias, $object = null) { + if (is_array($alias)) + $this->_attributes += $alias; + elseif (is_string($alias)) + $this->_attributes[$alias] = $object; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/filter/WindFilter.php b/wind/core/filter/WindFilter.php new file mode 100644 index 00000000..4c332bb5 --- /dev/null +++ b/wind/core/filter/WindFilter.php @@ -0,0 +1,32 @@ + 2010-11-4 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.filter.WindHandlerInterceptor'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindFilter extends WindHandlerInterceptor { + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + + } + +} \ No newline at end of file diff --git a/wind/core/filter/WindFilterChain.php b/wind/core/filter/WindFilterChain.php new file mode 100644 index 00000000..37197037 --- /dev/null +++ b/wind/core/filter/WindFilterChain.php @@ -0,0 +1,72 @@ + 2010-11-9 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.filter.WindHandlerInterceptorChain'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFilterChain extends WindHandlerInterceptorChain { + + /** + * @param array $filterConfig + */ + public function __construct($filterConfig) { + $this->_initFilters($filterConfig); + } + + /** + * @param string $filterName + */ + public function deleteFilter($alias) { + unset($this->_interceptors[$alias]); + } + + /** + * 在filter链中动态的添加一个filter + * 当befor为空时,添加到程序结尾处 + * 如果befor有值,则遍历数组,找到befor的位置,将新的过滤器添加到befor后面, + * 并将所有原befor位置后的过滤器往后移一位 + * + * @param string $filterName + * @param string $path + * @param string $beforFilter + */ + public function addFilter($filter, $beforFilter = '') { + if ($beforFilter === '') { + $this->addInterceptors(array(get_class($filter) => $filter)); + return true; + } + $_interceptors = array(); + foreach ($this->_interceptors as $key => $interceptor) { + if ($beforFilter === $key) break; + $_interceptors[$key] = $interceptor; + unset($this->_interceptors[$key]); + } + $_interceptors[get_class($filter)] = $filter; + $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; + } + + /** + * Enter description here ... + * @param array $filters + */ + private function _initFilters($filters = array()) { + $_temp = array(); + foreach ((array) $filters as $key => $filter) { + if (!is_array($filter)) continue; + $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); + if (!class_exists($filterClass)) continue; + $_temp[$key] = new $filterClass(); + } + $this->addInterceptors($_temp); + } + +} \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptor.php b/wind/core/filter/WindHandlerInterceptor.php new file mode 100644 index 00000000..8eb3c200 --- /dev/null +++ b/wind/core/filter/WindHandlerInterceptor.php @@ -0,0 +1,63 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHandlerInterceptor { + + protected $result = null; + + /** + * Enter description here ... + */ + public function preHandle() { + + } + + /** + * Enter description here ... + */ + public function postHandle() { + + } + + /** + * Enter description here ... + * @return mixed + */ + public function handle() { + $args = func_get_args(); + $this->result = call_user_func_array(array($this, 'preHandle'), $args); + if ($this->result !== null) { + return $this->result; + } + if (null !== ($handler = $this->interceptorChain->getHandler())) { + $this->result = call_user_func_array(array($handler, 'handle'), $args); + } else { + $this->result = $this->interceptorChain->execute(); + } + call_user_func_array(array($this, 'postHandle'), $args); + return $this->result; + } + + /** + * @param WindHandlerInterceptorChain $interceptorChain + */ + public function setHandlerInterceptorChain($interceptorChain) { + if ($interceptorChain instanceof WindComponentModule) { + $attributes = $interceptorChain->getAttribute(); + foreach ($attributes as $key => $value) { + $this->$key = $value; + } + } + $this->interceptorChain = $interceptorChain; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptorChain.php b/wind/core/filter/WindHandlerInterceptorChain.php new file mode 100644 index 00000000..f16e85dc --- /dev/null +++ b/wind/core/filter/WindHandlerInterceptorChain.php @@ -0,0 +1,77 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHandlerInterceptorChain extends WindComponentModule { + + protected $_interceptors = array(); + + protected $_callBack = null; + + protected $_args = array(); + + private $_state = true; + + /** + * Enter description here ... + */ + public function setCallBack($callBack, $args = array()) { + $this->_callBack = $callBack; + $this->_args = $args; + } + + /** + * Enter description here ... + * + * @throws WindException + * @return void|mixed + */ + public function execute() { + if ($this->_callBack === null) return null; + if (is_string($this->_callBack) && !function_exists($this->_callBack)) throw new WindException($this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); + + return call_user_func_array($this->_callBack, (array) $this->_args); + } + + /** + * Enter description here ... + * + * @return WindHandlerInterceptor + */ + public function getHandler() { + if ($this->_state) { + $this->addInterceptors(new WindHandlerInterceptor()); + $this->_state = false; + } + if (count($this->_interceptors) <= 0) return null; + + $handler = array_shift($this->_interceptors); + if ($handler instanceof WindHandlerInterceptor) { + $handler->setHandlerInterceptorChain($this); + return $handler; + } + return $this->getHandler(); + } + + /** + * Enter description here ... + * + * @param $interceptors + */ + public function addInterceptors($interceptors) { + if (is_array($interceptors)) + $this->_interceptors += $interceptors; + else + $this->_interceptors[] = $interceptors; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/request/IWindRequest.php b/wind/core/request/IWindRequest.php new file mode 100644 index 00000000..aa657cbf --- /dev/null +++ b/wind/core/request/IWindRequest.php @@ -0,0 +1,25 @@ + 2010-11-3 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 处理请求抽象基类 + * 如http请求 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindRequest { + const INPUT_TYPE_GET = 'get'; + const INPUT_TYPE_POST = 'post'; + const INPUT_TYPE_COOKIE = 'cookie'; +} + + + + diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php new file mode 100644 index 00000000..9ed04c08 --- /dev/null +++ b/wind/core/request/WindHttpRequest.php @@ -0,0 +1,638 @@ + 2010-11-7 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.request.IWindRequest'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHttpRequest implements IWindRequest { + + /** + * 访问的端口号 + * @var int + */ + private $_port = null; + + /** + * 客户端IP + * @var string + */ + private $_clientIp = null; + + /** + * 语言信息 + * @var string + */ + private $_language = null; + + /** + * 路径信息 + * @var string + */ + private $_pathInfo = null; + + /** + * @var string + */ + private $_scriptUrl = null; + + /** + * @var string + */ + private $_requestUri = null; + + /** + * 基础路径信息 + * @var string + */ + private $_baseUrl = null; + + private $_hostInfo = null; + + /** + * 请求参数信息 + * @var array + */ + private $_attribute = array(); + + /** + * @var WindHttpResponse + */ + private $_response = null; + + public function __construct() { + $this->normalizeRequest(); + } + + protected function normalizeRequest() { + if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { + if (isset($_GET)) $_GET = $this->stripSlashes($_GET); + if (isset($_POST)) $_POST = $this->stripSlashes($_POST); + if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); + if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); + } + } + + public function stripSlashes(&$data) { + return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes($data); + } + + public function setAttribute($name, $value) { + $this->_attribute[$name] = $value; + } + + /** + * 根据名称获得服务器和执行环境信息 + * + * @param string|null $name + */ + public function getAttribute($name, $value = '') { + if (isset($this->_attribute[$name])) { + return $this->_attribute[$name]; + } else if (isset($_GET[$name])) + return $_GET[$name]; + else if (isset($_POST[$name])) + return $_POST[$name]; + else if (isset($_COOKIE[$name])) + return $_COOKIE[$name]; + else if (isset($_REQUEST[$name])) + return $_REQUEST[$name]; + else if (isset($_ENV[$name])) + return $_ENV[$name]; + else if (isset($_SERVER[$name])) + return $_SERVER[$name]; + else + return $value; + } + + /** + * 从query中取值 + * + * @param string $name + * @param string $default + * @return string|null + */ + public function getQuery($name = null, $defaultValue = null) { + return $this->getGet($name, $defaultValue); + } + + /** + * 获得post值 + * + * @param string $name + * @param string $defaultValue + * @return string|null + */ + public function getPost($name = null, $defaultValue = null) { + if ($name == null) return $_POST; + return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; + } + + /** + * 获得get值 + * + * @param string $name + * @param string $defaultValue + * @return string|null + */ + public function getGet($name = '', $defaultValue = null) { + if ($name == null) return $_GET; + return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; + } + + /** + * 返回cookie的值,如果$name=null则返回所有Cookie值 + * + * @param string $key + * @param string $defaultValue + * @return string|null|array + */ + public function getCookie($name = null, $defaultValue = null) { + if ($name == null) return $_COOKIE; + return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; + } + + /** + * 返回session的值,如果$name=null则返回所有Cookie值 + * + * @param string $key + * @param string $defaultValue + * @return string|null|array + */ + public function getSession($name = null, $defaultValue = null) { + if ($name == null) return $_SESSION; + return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; + } + + /** + * 返回Server的值,如果$name为空则返回所有Server的值 + * + * @param string $name + * @param string $defaultValue + * @return string|null|array + */ + public function getServer($name = null, $defaultValue = null) { + if ($name == null) return $_SERVER; + return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; + } + + /** + * 返回env中的值,如果$name为null则返回所有env的值 + * + * @param string|null $name + * @param string $defaultValue + * @return string|null|array + */ + public function getEnv($name = null, $defaultValue = null) { + if ($name == null) return $_ENV; + return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; + } + + /** + * 获取协议名称 + * + * @return string + */ + public function getScheme() { + return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; + } + + /** + * 返回请求页面时通信协议的名称和版本 + * @return string + */ + public function getProtocol() { + return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); + } + + /** + * 返回访问IP + * + * @return string|0.0.0.0 + */ + public function getClientIp() { + if (!$this->_clientIp) $this->_getClientIp(); + return $this->_clientIp; + } + + /** + * 获得请求的方法 + */ + public function getRequestMethod() { + return strtoupper($this->getServer('REQUEST_METHOD')); + } + + /** + * 获得请求类型 + * + * @return string + */ + public function getRequestType() { + return IWindRequest::REQUEST_TYPE_WEB; + } + + /** + * 返回该请求是否为ajax请求 + * @return Boolean + */ + public function getIsAjaxRequest() { + return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); + } + + /** + * Returns a boolean indicating whether this request was made using a + * secure channel, such as HTTPS. + * @return Boolean + */ + public function isSecure() { + return !strcasecmp($this->getServer('HTTPS'), 'on'); + } + + /** + * 返回请求是否为GET请求类型 + * @return boolean + */ + public function isGet() { + return !strcasecmp($this->getRequestMethod(), 'GET'); + } + + /** + * 返回请求是否为POST请求类型 + * @return boolean + */ + public function isPost() { + return !strcasecmp($this->getRequestMethod(), 'POST'); + } + + /** + * 返回请求是否为PUT请求类型 + * @return boolean + */ + public function isPut() { + return !strcasecmp($this->getRequestMethod(), 'PUT'); + } + + /** + * 返回请求是否为DELETE请求类型 + * @return boolean + */ + public function isDelete() { + return !strcasecmp($this->getRequestMethod(), 'Delete'); + } + + /** + * 初始化请求的资源标识符 + * 这里的uri是去除协议名、主机名的 + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_requestUri = /example/index.php?a=test + * + * @return string + */ + public function getRequestUri() { + if (!$this->_requestUri) $this->initRequestUri(); + return $this->_requestUri; + } + + /** + * 返回当前执行脚本的绝对路径 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_scriptUrl = /example/index.php + * + * @throws WindException + * @return string + */ + public function getScriptUrl() { + if (!$this->_scriptUrl) $this->_initScriptUrl(); + return $this->_scriptUrl; + } + + /** + * 返回执行脚本 + */ + public function getScript() { + if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; + return substr($this->getScriptUrl(), $pos + 1); + } + + /** + * 获取Http头信息 + * @param string $header 头部名称 + * @return string|null + */ + public function getHeader($header, $default = null) { + $temp = strtoupper(str_replace('-', '_', $header)); + if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; + if (($header = $this->getServer($temp)) != null) return $header; + if (function_exists('apache_request_headers')) { + $headers = apache_request_headers(); + if ($headers[$header]) return $headers[$header]; + } + return $default; + } + + /** + * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 + * + * @throws WindException + * @return string + */ + public function getPathInfo() { + if (!$this->_pathInfo) $this->_initPathInfo(); + return $this->_pathInfo; + } + + /** + * 获取基础URL,这里是去除了脚本文件以及访问参数信息的URL地址信息 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_baseUrl = example + * return absolute url address when absolute is true + * 'example' will be return when absolute is false + * 'http://www.phpwind.net/example' will be return when absolute is true + * 'http://www.phpwind.net:80/example' will be return when absolute is true + * 'http://www.phpwind.net:443/example' will be return when absolute is true + * + * @param boolean $absolute + * @return string + */ + public function getBaseUrl($absolute = false) { + if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); + return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; + } + + /** + * 获得主机信息,包含协议信息,主机名,访问端口信息 + * + * @return string + */ + public function getHostInfo() { + if ($this->_hostInfo === null) $this->_initHostInfo(); + return $this->_hostInfo; + } + + /** + * 返回当前运行脚本所在的服务器的主机名。 + * 如果脚本运行于虚拟主机中 + * 该名称是由那个虚拟主机所设置的值决定 + * + * @return string|'' + */ + public function getServerName() { + return $this->getServer('SERVER_NAME', ''); + } + + /** + * 返回服务端口号 + * https链接的默认端口号为443 + * http链接的默认端口号为80 + * + * @return int + */ + public function getServerPort() { + if (!$this->_port) { + $_default = $this->isSecure() ? 443 : 80; + $this->setServerPort($this->getServer('SERVER_PORT', $_default)); + } + return $this->_port; + } + + /** + * 设置服务端口号 + * https链接的默认端口号为443 + * http链接的默认端口号为80 + * + * @param int $port + */ + public function setServerPort($port) { + $this->_port = (int) $port; + } + + /** + * 返回浏览当前页面的用户的主机名 + * DNS 反向解析不依赖于用户的 REMOTE_ADDR + * + * @return string|null + */ + public function getRemoteHost() { + return $this->getServer('REMOTE_HOST'); + } + + /** + * 返回浏览器发送Referer请求头,可以让服务器了解和追踪发出本次请求的起源URL地址 + * + * @return string|null + */ + public function getUrlReferer() { + return $this->getServer('HTTP_REFERER'); + } + + /** + * 获得用户机器上连接到 Web 服务器所使用的端口号 + * + * @return number|null + */ + public function getRemotePort() { + return $this->getServer('REMOTE_PORT'); + } + + /** + * 返回User-Agent头字段用于指定浏览器或者其他客户端程序的类型和名字 + * 如果客户机是一种无线手持终端,就返回一个WML文件;如果发现客户端是一种普通浏览器, + * 则返回通常的HTML文件 + * + * @return string + */ + public function getUserAgent() { + return $this->getServer('HTTP_USER_AGENT', ''); + } + + /** + * 返回当前请求头中 Accept: 项的内容, + * Accept头字段用于指出客户端程序能够处理的MIME类型,例如 text/html,image/* + * + * @return string|'' + */ + public function getAcceptTypes() { + return $this->getServer('HTTP_ACCEPT', ''); + } + + /** + * 返回客户端程序可以能够进行解码的数据编码方式,这里的编码方式通常指某种压缩方式 + * + * @return string|'' + */ + public function getAcceptCharset() { + return $this->getServer('HTTP_ACCEPT_ENCODING', ''); + } + + /** + * 返回客户端程序期望服务器返回哪个国家的语言文档 + * Accept-Language: en-us,zh-cn + * + * @return string + */ + public function getAcceptLanguage() { + if (!$this->_language) { + $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); + $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; + } + return $this->_language; + } + + /** + * 获得返回信息 + * @return WindHttpResponse + */ + public function getResponse() { + if ($this->_response === null) { + Wind::import('WIND:core.response.WindHttpResponse'); + $this->_response = new WindHttpResponse(); + if ($this->getIsAjaxRequest()) { + $this->_response->addHeader('Content-type', 'text/xml;charset=utf-8'); + $this->_response->setIsAjax(true); + } else + $this->_response->addHeader('Content-type', 'text/html;charset=utf-8'); + } + return $this->_response; + } + + /** + * 返回访问的IP地址 + * + * Example: + * $this->_clientIp = 127.0.0.1 + * + * @return string + */ + private function _getClientIp() { + if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { + $this->_clientIp = $ip; + } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { + $ip = strtok($_ip, ','); + do { + $ip = ip2long($ip); + if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { + $this->_clientIp = long2ip($ip); + return; + } + } while (($ip = strtok(','))); + } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { + $this->_clientIp = $ip; + } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { + $this->_clientIp = $ip; + } else { + $this->_clientIp = "0.0.0.0"; + } + } + + /** + * 初始化请求的资源标识符 + * 这里的uri是去除协议名、主机名的 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_requestUri = /example/index.php?a=test + * + * @throws WindException + */ + private function initRequestUri() { + if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { + $this->_requestUri = $requestUri; + } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { + $this->_requestUri = $requestUri; + if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); + } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { + $this->_requestUri = $requestUri; + if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; + } else + throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); + } + + /** + * 初始化当前执行脚本的绝对路径 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_scriptUrl = /example/index.php + * + * @throws WindException + * @return + */ + private function _initScriptUrl() { + if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); + + $scriptName = basename($scriptName); + if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { + $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; + } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { + $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } + + /** + * 获得主机信息,包含协议信息,主机名,访问端口信息 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_hostInfo = http://www.phpwind.net/ + * $this->_hostInfo = http://www.phpwind.net:80/ + * $this->_hostInfo = https://www.phpwind.net:443/ + * + * @throws WindException + * @return + */ + private function _initHostInfo() { + $http = $this->isSecure() ? 'https' : 'http'; + if (($httpHost = $this->getServer('HTTP_HOST')) != null) + $this->_hostInfo = $http . '://' . $httpHost; + elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { + $this->_hostInfo = $http . '://' . $httpHost; + if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } + + /** + * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 + * + * @throws WindException + * @return + */ + private function _initPathInfo() { + $requestUri = urldecode($this->getRequestUri()); + $scriptUrl = $this->getScriptUrl(); + $baseUrl = $this->getBaseUrl(); + if (strpos($requestUri, $scriptUrl) === 0) + $pathInfo = substr($requestUri, strlen($scriptUrl)); + elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) + $pathInfo = substr($requestUri, strlen($baseUrl)); + elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) + $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); + else + throw new WindException(''); + + if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); + + $this->_pathInfo = trim($pathInfo, '/'); + } + +} \ No newline at end of file diff --git a/wind/core/response/IWindResponse.php b/wind/core/response/IWindResponse.php new file mode 100644 index 00000000..0c437993 --- /dev/null +++ b/wind/core/response/IWindResponse.php @@ -0,0 +1,11 @@ + 2010-11-7 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +interface IWindResponse { + +} \ No newline at end of file diff --git a/wind/core/response/WindHttpResponse.php b/wind/core/response/WindHttpResponse.php new file mode 100644 index 00000000..e45105bb --- /dev/null +++ b/wind/core/response/WindHttpResponse.php @@ -0,0 +1,522 @@ + 2010-11-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.response.IWindResponse'); +/** + * 1xx:信息,请求收到,继续处理 + * 2xx:成功,行为被成功地接受、理解和采纳 + * 3xx:重定向,为了完成请求,必须进一步执行的动作 + * 4xx:客户端错误,请求包含语法错误或者请求无法实现 + * 5xx:服务器错误,服务器不能实现一种明显无效的请求 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHttpResponse implements IWindResponse { + + private $_body = array(); + + private $_headers = array(); + + private $_isRedirect = false; + + private $_status = ''; + + private $_isAjax = false; + + private $_data = array(); + + /* + * Server status codes; see RFC 2068. + * Status code (100) indicating the client can continue. + */ + const SC_CONTINUE = 100; + + /** + * Status code (101) indicating the server is switching protocols + * according to Upgrade header. + */ + const SC_SWITCHING_PROTOCOLS = 101; + + /** + * Status code (200) indicating the request succeeded normally. + */ + const SC_OK = 200; + + /** + * Status code (201) indicating the request succeeded and created + * a new resource on the server. + */ + const SC_CREATED = 201; + + /** + * Status code (202) indicating that a request was accepted for + * processing, but was not completed. + */ + const SC_ACCEPTED = 202; + + /** + * Status code (203) indicating that the meta information presented + * by the client did not originate from the server. + */ + const SC_NON_AUTHORITATIVE_INFORMATION = 203; + + /** + * Status code (204) indicating that the request succeeded but that + * there was no new information to return. + */ + const SC_NO_CONTENT = 204; + + /** + * Status code (205) indicating that the agent SHOULD reset + * the document view which caused the request to be sent. + */ + const SC_RESET_CONTENT = 205; + + /** + * Status code (206) indicating that the server has fulfilled + * the partial GET request for the resource. + */ + const SC_PARTIAL_CONTENT = 206; + + /** + * Status code (300) indicating that the requested resource + * corresponds to any one of a set of representations, each with + * its own specific location. + */ + const SC_MULTIPLE_CHOICES = 300; + + /** + * Status code (301) indicating that the resource has permanently + * moved to a new location, and that future references should use a + * new URI with their requests. + */ + const SC_MOVED_PERMANENTLY = 301; + + /** + * Status code (302) indicating that the resource has temporarily + * moved to another location, but that future references should + * still use the original URI to access the resource. + * + * This definition is being retained for backwards compatibility. + * SC_FOUND is now the preferred definition. + */ + const SC_MOVED_TEMPORARILY = 302; + + /** + * Status code (302) indicating that the resource reside + * temporarily under a different URI. Since the redirection might + * be altered on occasion, the client should continue to use the + * Request-URI for future requests.(HTTP/1.1) To represent the + * status code (302), it is recommended to use this variable. + */ + const SC_FOUND = 302; + + /** + * Status code (303) indicating that the response to the request + * can be found under a different URI. + */ + const SC_SEE_OTHER = 303; + + /** + * Status code (304) indicating that a conditional GET operation + * found that the resource was available and not modified. + */ + const SC_NOT_MODIFIED = 304; + + /** + * Status code (305) indicating that the requested resource + * MUST be accessed through the proxy given by the + * Location field. + */ + const SC_USE_PROXY = 305; + + /** + * Status code (307) indicating that the requested resource + * resides temporarily under a different URI. The temporary URI + * SHOULD be given by the Location + * field in the response. + */ + const SC_TEMPORARY_REDIRECT = 307; + + /** + * Status code (400) indicating the request sent by the client was + * syntactically incorrect. + */ + const SC_BAD_REQUEST = 400; + + /** + * Status code (401) indicating that the request requires HTTP + * authentication. + */ + const SC_UNAUTHORIZED = 401; + + /** + * Status code (402) reserved for future use. + */ + const SC_PAYMENT_REQUIRED = 402; + + /** + * Status code (403) indicating the server understood the request + * but refused to fulfill it. + */ + const SC_FORBIDDEN = 403; + + /** + * Status code (404) indicating that the requested resource is not + * available. + */ + const SC_NOT_FOUND = 404; + + /** + * Status code (405) indicating that the method specified in the + * Request-Line is not allowed for the resource + * identified by the Request-URI. + */ + const SC_METHOD_NOT_ALLOWED = 405; + + /** + * Status code (406) indicating that the resource identified by the + * request is only capable of generating response entities which have + * content characteristics not acceptable according to the accept + * headers sent in the request. + */ + const SC_NOT_ACCEPTABLE = 406; + + /** + * Status code (407) indicating that the client MUST first + * authenticate itself with the proxy. + */ + const SC_PROXY_AUTHENTICATION_REQUIRED = 407; + + /** + * Status code (408) indicating that the client did not produce a + * request within the time that the server was prepared to wait. + */ + const SC_REQUEST_TIMEOUT = 408; + + /** + * Status code (409) indicating that the request could not be + * completed due to a conflict with the current state of the + * resource. + */ + const SC_CONFLICT = 409; + + /** + * Status code (410) indicating that the resource is no longer + * available at the server and no forwarding address is known. + * This condition SHOULD be considered permanent. + */ + const SC_GONE = 410; + + /** + * Status code (411) indicating that the request cannot be handled + * without a defined Content-Length. + */ + const SC_LENGTH_REQUIRED = 411; + + /** + * Status code (412) indicating that the precondition given in one + * or more of the request-header fields evaluated to false when it + * was tested on the server. + */ + const SC_PRECONDITION_FAILED = 412; + + /** + * Status code (413) indicating that the server is refusing to process + * the request because the request entity is larger than the server is + * willing or able to process. + */ + const SC_REQUEST_ENTITY_TOO_LARGE = 413; + + /** + * Status code (414) indicating that the server is refusing to service + * the request because the Request-URI is longer + * than the server is willing to interpret. + */ + const SC_REQUEST_URI_TOO_LONG = 414; + + /** + * Status code (415) indicating that the server is refusing to service + * the request because the entity of the request is in a format not + * supported by the requested resource for the requested method. + */ + const SC_UNSUPPORTED_MEDIA_TYPE = 415; + + /** + * Status code (416) indicating that the server cannot serve the + * requested byte range. + */ + const SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + + /** + * Status code (417) indicating that the server could not meet the + * expectation given in the Expect request header. + */ + const SC_EXPECTATION_FAILED = 417; + + /** + * Status code (500) indicating an error inside the HTTP server + * which prevented it from fulfilling the request. + */ + const SC_INTERNAL_SERVER_ERROR = 500; + + /** + * Status code (501) indicating the HTTP server does not support + * the functionality needed to fulfill the request. + */ + const SC_NOT_IMPLEMENTED = 501; + + /** + * Status code (502) indicating that the HTTP server received an + * invalid response from a server it consulted when acting as a + * proxy or gateway. + */ + const SC_BAD_GATEWAY = 502; + + /** + * Status code (503) indicating that the HTTP server is + * temporarily overloaded, and unable to handle the request. + */ + const SC_SERVICE_UNAVAILABLE = 503; + + /** + * Status code (504) indicating that the server did not receive + * a timely response from the upstream server while acting as + * a gateway or proxy. + */ + const SC_GATEWAY_TIMEOUT = 504; + + /** + * Status code (505) indicating that the server does not support + * or refuses to support the HTTP protocol version that was used + * in the request message. + */ + const SC_HTTP_VERSION_NOT_SUPPORTED = 505; + + /** + * 设置响应头信息,如果已经设置过同名的响应头,该方法将用新的设置取代原来的头字段 + * + * @param string $name 响应头的名称 + * @param string $value 响应头的字段取值 + */ + public function setHeader($name, $value, $replace = false) { + if (trim($name) == '' || trim($value) == '') return; + $name = $this->_normalizeHeader($name); + foreach ($this->_headers as $key => $one) { + ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, + 'replace' => $replace); + } + } + + /** + * 设置响应头信息,如果已经设置过同名的响应头,该方法将增加一个同名的响应头 + * + * @param string $name 响应头的名称 + * @param string $value 响应头的字段取值 + */ + public function addHeader($name, $value, $replace = false) { + if (trim($name) == '' || trim($value) == '') return; + $name = $this->_normalizeHeader($name); + $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); + } + + /** + * 设置响应头状态码 + * + * @param int $status + * @param string $message + */ + public function setStatus($status, $message = '') { + if (!is_int($status) || $status < 100 || $status > 505) return; + + $this->_status = (int) $status; + } + + /** + * 设置相应内容 + * + * @param string $content + * @param string $name + */ + public function setBody($content, $name = null) { + if (!is_string($content) || trim($content) == '') return; + if ($name == null || !is_string($name)) $name = 'default'; + $this->_body[$name] = (string) $content; + } + + /** + * 添加cookie信息 + * + * @param Cookie $cookie + */ + public function addCookie(Cookie $cookie) { + + } + + /** + * 发送一个错误的响应信息 + * + * @param int $status + * @param string $message + */ + public function sendError($status = self::SC_NOT_FOUND, $message = '') { + if (!is_int($status) || $status < 400 || $status > 505) return; + $this->setBody($message); + $this->setStatus($status); + } + + /** + * 重定向一个响应信息 + * + * @param string $location + */ + public function sendRedirect($location, $status = 302) { + if (!is_int($status) || $status < 300 || $status > 399) return; + + $this->addHeader('Location', $location, true); + $this->setStatus($status); + $this->_isRedirect = true; + $this->sendHeaders(); + exit(); + } + + /** + * 发送响应信息 + */ + public function sendResponse() { + $this->sendHeaders(); + $this->sendBody(); + } + + /** + * 发送响应头部信息 + */ + public function sendHeaders() { + if ($this->isSendedHeader()) return; + foreach ($this->_headers as $header) { + header($header['name'] . ': ' . $header['value'], $header['replace']); + } + header('HTTP/1.1 ' . $this->_status); + } + + /** + * 发送响应内容 + */ + public function sendBody() { + /*if ($this->_isAjax) echo "_body as $content) + echo $content; + /*if ($this->_isAjax) echo "]]>";*/ + } + + /** + * 获取内容 + * + * @param string $spec 内容的名称 + * @return string|null + */ + public function getBody($name = false) { + if ($name === false) { + ob_start(); + $this->sendBody(); + return ob_get_clean(); + } elseif ($name === true) { + return $this->_body; + } elseif (is_string($name) && isset($this->_body[$name])) + return $this->_body[$name]; + + return null; + } + + /** + * 是否已经发送了响应头部 + */ + public function isSendedHeader($throw = false) { + $sended = headers_sent($file, $line); + if ($throw && $sended) throw new WindException(__CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); + + return $sended; + } + + /** + * 获取响应头信息 + * + * @return array + */ + public function getHeaders() { + return $this->_headers; + } + + /** + * 清理响应体信息 + */ + public function clearBody() { + $this->_body = array(); + } + + /** + * 清除响应头信息 + */ + public function clearHeaders() { + $this->_headers = array(); + } + + /** + * 格式化响应头信息 + * + * @param string $name + * @return string + */ + private function _normalizeHeader($name) { + if (trim($name) == '') return ''; + $filtered = str_replace(array('-', '_'), ' ', (string) $name); + $filtered = ucwords(strtolower($filtered)); + $filtered = str_replace(' ', '-', $filtered); + return $filtered; + } + + /** + * @return the $_isAjax + */ + public function getIsAjax() { + return $this->_isAjax; + } + + /** + * @param field_type $_isAjax + */ + public function setIsAjax($_isAjax) { + $this->_isAjax = $_isAjax; + } + + /** + * @return the $_data + */ + public function getData($key1, $key2 = '') { + if (!$key1) return $this->_data; + if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; + return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; + } + + /** + * @param $data + */ + public function setData($data, $key) { + if ($key === '') return; + if ($key) { + $this->_data[$key] = $data; + return; + } + if (is_object($data)) $data = get_object_vars($data); + if (is_array($data)) $this->_data += $data; + } + +} \ No newline at end of file diff --git a/wind/core/router/AbstractWindRouter.php b/wind/core/router/AbstractWindRouter.php new file mode 100644 index 00000000..ec824980 --- /dev/null +++ b/wind/core/router/AbstractWindRouter.php @@ -0,0 +1,134 @@ + 2010-11-3 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.WindComponentModule'); +/** + * 路由解析器接口 + * 职责: 路由解析, 返回路由对象 + * 实现路由解析器必须实现该接口的doParser()方法 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindRouter extends WindComponentModule { + + protected $action = 'run'; + + protected $controller = 'index'; + + protected $module = 'default'; + + protected $modulePath = ''; + + protected $appName = ''; + + protected $reParse = true; + + protected $defaultControllerSuffix = 'Controller'; + + protected $defaultControllerPath = 'controller'; + + /** + * Enter description here ... + */ + abstract public function parse(); + + /** + * Enter description here ... + */ + abstract public function getHandler(); + + /** + * Enter description here ... + */ + abstract public function buildUrl(); + + /** + * Enter description here ... + */ + public function doParse() { + if ($this->reParse) { + $this->parse(); + $this->reParse = false; + } + $this->destroy(); + } + + /** + * 重新进行解析 + */ + public function reParse() { + $this->reParse = true; + } + + /** + * 获得业务操作 + */ + public function getAction() { + return $this->action; + } + + /** + * 获得业务对象 + */ + public function getController() { + return $this->controller; + } + + /** + * 返回一组应用入口 + */ + public function getModule() { + return $this->module; + } + + /** + * @param string $action + */ + public function setAction($action) { + $this->action = $action; + } + + /** + * @param string $controller + */ + public function setController($controller) { + $this->controller = $controller; + } + + /** + * @param string $module + */ + public function setModule($module) { + if (false !== $pos = strpos($module, ':')) { + $this->appName = substr($module, 0, $pos); + $this->modulePath = substr($module, $pos + 1); + if (false === strpos($this->modulePath, '.')) { + $this->module = $this->modulePath; + $this->modulePath = ''; + } + } elseif (false !== strpos($module, '.')) { + $this->modulePath = $module; + } else { + $this->module = $module; + $this->modulePath = ''; + $this->appName = ''; + } + } + + /** + * 销毁缓存 + */ + protected function destroy() { + $this->modulePath = ''; + $this->appName = ''; + } + +} \ No newline at end of file diff --git a/wind/core/router/WindUrlBasedRouter.php b/wind/core/router/WindUrlBasedRouter.php new file mode 100644 index 00000000..f069f0ce --- /dev/null +++ b/wind/core/router/WindUrlBasedRouter.php @@ -0,0 +1,100 @@ + 2010-11-3 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.router.AbstractWindRouter'); +/** + * 基于URL的路由解析器. + * 该解析器通过访问一个Http请求的Request对象来获得URL的参数信息 + * 并将其参数根据已定义的路由规则进行解析. + * 通过该方法的getActionHandle方法返回一个,操作处理的句柄信息 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @link WRouteParser + * @package + */ +class WindUrlBasedRouter extends AbstractWindRouter { + + /* url 路由参数规则 */ + const URL_PARAM = 'url-param'; + + const DEFAULT_VALUE = 'default-value'; + + /* url 后缀名参数规则 */ + const CONTROLLER_SUFFIX = 'controller-suffix'; + + const ACTION_SUFFIX = 'action-suffix'; + + const URL_RULE_MODULE = 'module'; + + const URL_RULE_CONTROLLER = 'controller'; + + const URL_RULE_ACTION = 'action'; + + /* (non-PHPdoc) + * @see AbstractWindRouter::parse() + */ + public function parse() { + $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->request, $this->module)); + $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->request, $this->controller)); + $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->request, $this->action)); + } + + /* (non-PHPdoc) + * @see AbstractWindRouter::getHandler() + */ + public function getHandler() { + $moduleConfig = $this->windSystemConfig->getModules($this->getModule()); + $_controllerPath = $this->windSystemConfig->getConfig(WIND_CONFIG_CLASSPATH, '', $moduleConfig, $this->defaultControllerPath); + $_suffix = $this->windSystemConfig->getConfig(self::CONTROLLER_SUFFIX, WIND_CONFIG_VALUE, $moduleConfig, $this->defaultControllerSuffix); + $_path = $this->modulePath ? $this->modulePath : $_controllerPath; + $_path .= '.' . ucfirst($this->controller) . $_suffix; + if (strpos($_path, ':') === false) $_path = strtoupper($this->windSystemConfig->getAppName()) . ':' . $_path; + + //add log + if (IS_DEBUG) { + /* @var $logger WindLogger */ + $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); + $logger->debug('do getHandler of ' . __CLASS__); + } + + return $_path; + } + + /* (non-PHPdoc) + * @see AbstractWindRouter::buildUrl() + */ + public function buildUrl() { + $module = $this->getUrlParamValue(self::URL_RULE_MODULE); + $controller = $this->getUrlParamValue(self::URL_RULE_CONTROLLER); + $action = $this->getUrlParamValue(self::URL_RULE_ACTION); + $url = '?' . $module . '=' . $this->getModule(); + $url .= '&' . $controller . '=' . $this->getController(); + $url .= '&' . $action . '=' . $this->getAction(); + return $url; + } + + /** + * Enter description here ... + * @param urlParam + * @param request + * @param defaultValue + * @return string + */ + private function getUrlParamValue($type, $request = null, $defaultValue = '') { + if ($_param = $this->getConfig($type, self::URL_PARAM)) { + if (is_null($request)) return $_param; + $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE); + $defaultValue = $_defaultValue ? $_defaultValue : $defaultValue; + return $request->getAttribute($_param, $defaultValue); + } + return $defaultValue; + } + +} \ No newline at end of file diff --git a/wind/core/viewer/AbstractWindTemplateCompiler.php b/wind/core/viewer/AbstractWindTemplateCompiler.php new file mode 100644 index 00000000..98cfc9f8 --- /dev/null +++ b/wind/core/viewer/AbstractWindTemplateCompiler.php @@ -0,0 +1,126 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindTemplateCompiler extends WindHandlerInterceptor { + + protected $tags = array(); + + /** + * @var WindViewTemplate + */ + protected $windViewTemplate = null; + + /** + * @var WindViewerResolver + */ + protected $windViewerResolver = null; + + protected $request = null; + + protected $response = null; + + /** + * 初始化标签解析器 + * @param string $tagContent + * @param WindViewTemplate $windViewTemplate + * @param WindViewerResolver $windViewerResolver + * @param WindHttpRequest $request + * @param WindHttpResponse $response + */ + public function __construct($tags, $windViewTemplate, $windViewerResolver, $request, $response) { + $this->tags = $tags; + $this->windViewTemplate = $windViewTemplate; + $this->windViewerResolver = $windViewerResolver; + $this->request = $request; + $this->response = $response; + } + + /** + * 模板编译方法 + * @param string $content | 模板内容 + * @param WindViewTemplate $windViewTemplate | 模板编译引擎 + * @return string | 输出编译后结果 + */ + abstract public function compile($key, $content); + + /** + * 解析属性值 + * @param string $content + */ + protected function compileProperty($content) { + foreach ($this->getProperties() as $value) { + if (!$value) continue; + preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', $content, $result); + if ($result) $this->$value = trim(str_replace($result[1], '', $result[0])); + } + } + + /** + * 返回该标签支持的属性信息 + */ + protected function getProperties() { + return array(); + } + + protected function preCompile() { + + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + if ($this->windViewTemplate === null) return; + $this->preCompile(); + foreach ($this->tags as $key => $value) { + if (!$value[0] || !$value[1]) continue; + $this->compileProperty($value[1]); + $_output = $this->compile($value[0], $value[1]); + $this->windViewTemplate->setCompiledBlockData($value[0], $_output); + } + $this->postCompile(); + } + + /** + * 编译后处理结果 + */ + protected function postCompile() { + + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::handle() + */ + public function handle() { + $args = func_get_args(); + call_user_func_array(array($this, 'preHandle'), $args); + if (null !== ($handler = $this->interceptorChain->getHandler())) { + call_user_func_array(array($handler, 'handle'), $args); + } + call_user_func_array(array($this, 'postHandle'), $args); + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() {} + + /** + * @return WindViewTemplate $windViewTemplate + */ + protected function getWindViewTemplate() { + return $this->windViewTemplate; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/AbstractWindViewTemplate.php b/wind/core/viewer/AbstractWindViewTemplate.php new file mode 100644 index 00000000..7ecea651 --- /dev/null +++ b/wind/core/viewer/AbstractWindViewTemplate.php @@ -0,0 +1,114 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindViewTemplate extends WindComponentModule { + + const SUPPORT_TAGS = 'support-tags'; + + const TAG = 'tag'; + + const REGEX = 'regex'; + + const COMPILER = 'compiler'; + + const PATTERN = 'pattern'; + + /** + * 对模板内容进行编译 + * @param string $content + * @param WindViewerResolver $windViewerResolver + */ + abstract protected function doCompile($content, $windViewerResolver = null); + + /** + * 进行视图渲染 + * @param string $templateFile | 模板文件 + * @param string $compileFile | 编译后生成的文件 + * @param WindViewerResolver $windViewerResolver + */ + public function compile($templateFile, $compileFile, $windViewerResolver) { + if (!$this->checkReCompile($templateFile, $compileFile)) return null; + $_output = $this->getTemplateFileContent($templateFile); + $_output = $this->compileDelimiter($_output); + $_output = $this->doCompile($_output, $windViewerResolver); + $this->cacheCompileResult($compileFile, $_output); + return $_output; + } + + /** + * @param string content + * @return string $content + */ + protected function compileDelimiter($content) { + $content = str_replace(array('', '#-->'), '?>', $content); + return $content; + } + + /** + * 获得模板文件内容,目前只支持本地文件获取 + * @param string $templateFile + */ + private function getTemplateFileContent($templateFile) { + $_output = ''; + if ($fp = @fopen($templateFile, 'r')) { + while (!feof($fp)) { + $_output .= fgets($fp, 4096); + } + fclose($fp); + } else + throw new WindViewException('Unable to open the template file \'' . $templateFile . '\'.'); + + return $_output; + } + + /** + * 将编译结果进行缓存 + * @param string $compileFile | 编译缓存文件 + * @param string $content | 模板内容 + */ + private function cacheCompileResult($compileFile, $content) { + //TODO 修复模板在非Debug模式下不能生成问题 + if (!$compileFile && !$content) return; + WindFile::write($compileFile, $content); + } + + /** + * 检查是否需要重新编译 + * + * @param string $templateFile + * @param string $compileFile + */ + private function checkReCompile($templateFile, $compileFile) { + $_reCompile = false; + if (IS_DEBUG) { + $_reCompile = true; + } elseif (false === ($compileFileModifyTime = @filemtime($compileFile))) { + $_reCompile = true; + } else { + $templateFileModifyTime = @filemtime($templateFile); + if ((int) $templateFileModifyTime >= $compileFileModifyTime) $_reCompile = true; + } + return $_reCompile; + } + + /** + * 返回模板支持的标签 + * array('tagName'=>array('tag','compiler')) + * @return array + */ + protected function getTags() { + return $this->getConfig(self::SUPPORT_TAGS); + } +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/IWindViewerResolver.php b/wind/core/viewer/IWindViewerResolver.php new file mode 100644 index 00000000..ea5556f4 --- /dev/null +++ b/wind/core/viewer/IWindViewerResolver.php @@ -0,0 +1,33 @@ + 2010-11-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 视图引擎基类 + * 通过继承该方法可以实现对视图模板的调用解析 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindViewerResolver { + + /** + * 设置视图变量信息 + * + * @param array $vars + * @param string $key + */ + public function windAssign($vars, $key = ''); + + /** + * 获取模板内容与变量信息 + */ + public function windFetch($template = ''); + +} \ No newline at end of file diff --git a/wind/core/viewer/WindLayout.php b/wind/core/viewer/WindLayout.php new file mode 100644 index 00000000..e243090a --- /dev/null +++ b/wind/core/viewer/WindLayout.php @@ -0,0 +1,67 @@ + 2010-11-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 布局对象, + * 通过加载一个布局对象,或者布局配置文件,或者设置布局变量来实现页面布局 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindLayout { + + private $layoutFile = ''; + + /** + * @param string $layoutFile + */ + public function __construct($layoutFile = '') { + $this->setLayoutFile($layoutFile); + } + + /** + * 解析layout布局文件 + * @param WindViewerResolver $windViewerResolver + */ + public function parse($windViewerResolver) { + if (!$windViewerResolver) return ''; + $this->viewer = $windViewerResolver; + if (!$this->layoutFile) throw new WindException('layout file is required.'); + $layoutFile = $windViewerResolver->compile($this->layoutFile); + ob_start(); + if (!include $layoutFile) throw new WindException('Incorrect layout file ' . $layoutFile); + return ob_get_clean(); + } + + private function setSegments($segment = '') { + $this->getContent($segment); + } + + private function getContent($template = '') { + if (!isset($this->viewer)) return; + if (!$template) $template = $this->viewer->getWindView()->getTemplateName(); + if ($template) $this->viewer->displayWindFetch($template); + } + + /** + * @return the $layoutFile + */ + protected function getLayoutFile() { + return $this->layoutFile; + } + + /** + * @param field_type $layoutFile + */ + protected function setLayoutFile($layoutFile) { + $this->layoutFile = $layoutFile; + } + +} \ No newline at end of file diff --git a/wind/core/viewer/WindView.php b/wind/core/viewer/WindView.php new file mode 100644 index 00000000..e5994267 --- /dev/null +++ b/wind/core/viewer/WindView.php @@ -0,0 +1,226 @@ + 2010-11-9 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.WindComponentModule'); +/** + * 处理视图请求的准备工作,并将视图请求提交给某一个具体的视图解析器 + * 如果视图请求是一个重定向请求,或者是请求另一个操作 + * 则返回一个forward对象 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindView extends WindComponentModule { + + const TEMPLATE_DIR = 'template-dir'; + + const TEMPLATE_EXT = 'template-ext'; + + const IS_CACHE = 'is-cache'; + + const CACHE_DIR = 'cache-dir'; + + const COMPILE_DIR = 'compile-dir'; + + const SHARE_VAR = 'share-var'; + + protected $templatePath = ''; + + protected $templateExt = ''; + + protected $templateName = ''; + + protected $isCache = ''; + + protected $compileDir = ''; + + protected $cacheDir = ''; + + protected $shareVar = ''; + + /** + * 视图解析引擎 + * + * @var WindViewerResolver + */ + protected $viewResolver = null; + + /** + * 布局文件 + * + * @var string + */ + protected $layout = ''; + + /** + * 设置布局对象 + * @param WindLayout|string $layout + */ + public function setLayout($layout) { + if ($layout instanceof WindLayout) + $this->layout = $layout->getLayoutFile(); + else + $this->layout = $layout; + + } + + /** + * 模板路径解析 + * 根据模板的逻辑名称,返回模板的绝对路径信息 + * + * @param string $templateName + * @param string $templateExt + * @return string | false + */ + public function getViewTemplate($template = '', $ext = '') { + $path = $this->getTemplatePath(); + return $this->parseFilePath($template, $ext, $path); + } + + /** + * 模板编译路径解析 + * 根据模板的逻辑名称,返回模板的绝对路径信息 + * + * @param string $templateName + * @param string $templateExt + * @return string | false + */ + public function getCompileFile($template = '', $ext = '') { + $path = $this->getCompileDir(); + return $this->parseFilePath($template, $ext, $path); + } + + /** + * 模板缓存路径路径解析 + * 根据模板的逻辑名称,返回模板的绝对路径信息 + * + * @param string $templateName + * @param string $templateExt + * @return string | false + */ + public function getCacheFile($template = '', $ext = '') { + $path = $this->getCacheDir(); + return $this->parseFilePath($template, $ext, $path); + } + + /** + * @return WindViewerResolver + */ + public function getViewResolver() { + if ($this->viewResolver !== null) { + if ($this->getIsCache() === 'true') { + Wind::import('WIND:core.viewer.listener.WindViewCacheListener'); + $this->viewResolver->setClassProxy(new WindClassProxy()); + $this->viewResolver = $this->viewResolver->getClassProxy(); + $this->viewResolver->registerEventListener('windFetch', new WindViewCacheListener($this)); + } + $this->viewResolver->setWindView($this); + return $this->viewResolver; + } else { + throw new WindException('getViewResolver()', WindException::ERROR_RETURN_TYPE_ERROR); + } + } + + /** + * @param $fileName + * @param $fileExt + * @param $path + */ + private function parseFilePath($fileName, $fileExt, $path) { + if (!$fileName) $fileName = $this->getTemplateName(); + if (!$fileExt) $fileExt = $this->getTemplateExt(); + if (!$fileName) return ''; + if (strrpos($path, ':') === false) $path = $this->windSystemConfig->getAppName() . ':' . $path; + if (!($dir = Wind::getRealPath($path, true)) || !is_dir($dir)) { + throw new WindException('The file folder \'' . $dir . '\' is not exist.'); + } + return Wind::getRealPath($path . '.' . $fileName . '.' . $fileExt); + } + + /** + * @return string $templatePath + */ + public function getTemplatePath() { + //TODO change templatePath to templateDir + if ($this->templatePath === '') { + $this->templatePath = $this->getDefaultValue(self::TEMPLATE_DIR); + } + return $this->templatePath; + } + + /** + * @return string $templateExt + */ + public function getTemplateExt() { + if ($this->templateExt === '') { + $this->templateExt = $this->getDefaultValue(self::TEMPLATE_EXT); + } + return $this->templateExt; + } + + /** + * @return boolean $isCache + */ + public function getIsCache() { + if ($this->isCache === '') { + $this->isCache = $this->getDefaultValue(self::IS_CACHE); + } + return $this->isCache; + } + + /** + * @return string $compileDir + */ + public function getCompileDir() { + if ($this->compileDir === '') { + $this->compileDir = $this->getDefaultValue(self::COMPILE_DIR); + } + return $this->compileDir; + } + + /** + * @return string $cacheDir + */ + public function getCacheDir() { + if ($this->cacheDir === '') $this->cacheDir = $this->getDefaultValue(self::CACHE_DIR); + return $this->cacheDir; + } + + /** + * @return boolean $shareVar + */ + public function getShareVar() { + if ($this->shareVar === '') $this->shareVar = $this->getDefaultValue(self::SHARE_VAR); + return $this->shareVar; + } + + /** + * @param string $type + */ + private function getDefaultValue($type) { + return $this->getConfig($type, WindSystemConfig::VALUE); + } + + /* (non-PHPdoc) + * @see WindModule::getWriteTableForGetterAndSetter() + */ + protected function getWriteTableForGetterAndSetter() { + return array('templatePath', 'templateExt', 'templateName', 'isCache', 'compileDir', 'cacheDir', 'viewResolver', + 'layout'); + } + + /* (non-PHPdoc) + * @see WindModule::getCloneProperty() + */ + protected function getCloneProperty() { + return array('viewResolver'); + } + +} \ No newline at end of file diff --git a/wind/core/viewer/WindViewerResolver.php b/wind/core/viewer/WindViewerResolver.php new file mode 100644 index 00000000..054b05c1 --- /dev/null +++ b/wind/core/viewer/WindViewerResolver.php @@ -0,0 +1,139 @@ + 2010-11-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.viewer.IWindViewerResolver'); +Wind::import('WIND:core.WindComponentModule'); +/** + * 默认视图引擎 + * 基于URL的视图引擎,视图名和模板名称保持一致 + * + * 该视图类接收一个modelAndView对象,通过解析该对象获得一个逻辑视图名称 + * 并将该逻辑视图名称,映射到具体的视图资源。 + * + * 布局解析,模板解析,编译缓存,模板缓存 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewerResolver extends WindComponentModule implements IWindViewerResolver { + + /** + * 模板信息 + * @var WindView + */ + protected $windView = null; + + /** + * @var WindUrlHelper + */ + protected $urlHelper = null; + + /** + * 立即输出模板内容 + * + * @param string $template + */ + public function displayWindFetch($template = '') { + echo $this->windFetch($template); + } + + /* (non-PHPdoc) + * @see IWindViewerResolver::windFetch() + */ + public function windFetch($template = '') { + if (!$template && null !== $layout = $this->getWindView()->getLayout()) { + $template = $layout; + } + ob_start(); + $this->render($template); + return ob_get_clean(); + } + + /** + * 设置模板变量信息 + * + * @param object|array|string $vars + * @param string $key + */ + public function windAssign($vars, $key = '') { + if ($key === '') $key = $this->getWindView()->getTemplateName(); + $this->response->setData($vars, $key); + } + + /** + * 编译模板并返回编译后模板名称 + * @param string $template + * @param string $suffix + * @param boolean $output + * @return string + */ + public function compile($template, $suffix = '', $output = false) { + $templateFile = $this->getWindView()->getViewTemplate($template, $suffix); + if (!file_exists($templateFile)) { + throw new WindViewException($templateFile, WindViewException::VIEW_NOT_EXIST); + } + if (!$this->getWindView()->getCompileDir()) return $templateFile; + $compileFile = $this->getWindView()->getCompileFile($template, 'tpl'); + $_windTemplate = $this->windFactory->getInstance(COMPONENT_TEMPLATE); + if ($_windTemplate) { + $_output = $_windTemplate->compile($templateFile, $compileFile, $this); + } + if ($output === false) return $compileFile; + if ($_output !== null) return array($compileFile, $_output); + if ($fp = @fopen($compileFile, 'r')) { + while (!feof($fp)) + $_output .= fgets($fp, 4096); + fclose($fp); + } else + throw new WindViewException('Unable to open the template file \'' . $compileFile . '\'.'); + + return array($compileFile, $_output); + } + + /** + * 加载视图模板文件 + * @param template + */ + protected function render($template) { + $_tmp = $this->compile($template); + //extract template vars + @extract((array) $this->response->getData($this->windView->getTemplateName()), EXTR_REFS); + if (!include $_tmp) { + throw new WindViewException($_tmp, WindViewException::VIEW_NOT_EXIST); + } + } + + /** + * 当前模板内容 + * @param string $template + */ + private function getContent($template = '') { + if (!$template) $template = $this->getWindView()->getTemplateName(); + if ($template) $this->displayWindFetch($template); + } + + /** + * @return WindView $windView + */ + public function getWindView() { + if ($this->windView !== null) + return $this->windView; + else + throw new WindException('WindView', WindException::ERROR_RETURN_TYPE_ERROR); + } + + /* (non-PHPdoc) + * @see WindModule::getWriteTableForGetterAndSetter() + */ + protected function getWriteTableForGetterAndSetter() { + return array('windView', 'windTemplate', 'urlHelper', 'templateVars'); + } + +} \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerAction.php b/wind/core/viewer/compiler/WindTemplateCompilerAction.php new file mode 100644 index 00000000..cec0934a --- /dev/null +++ b/wind/core/viewer/compiler/WindTemplateCompilerAction.php @@ -0,0 +1,53 @@ + 2010-11-2 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2010 phpwind.com + * @license + */ + +Wind::import('WIND:core.viewer.AbstractWindTemplateCompiler'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerAction extends AbstractWindTemplateCompiler { + + protected $action = ''; + + protected $controller = ''; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + $_content = 'getScript() . ' ?>' . "\r\n"; + return $_content; + } + + /** + * @return string + */ + public function getScript() { + $_tmp = ''; + $_tmp .= '$_tpl_forward = $this->windFactory->getInstance(COMPONENT_FORWARD);'. + '$_tpl_forward->forwardAnotherAction(\''.$this->action.'\', \''.$this->controller.'\');'. + '$_tpl_appName = $this->windSystemConfig->getAppClass();'. + '$_tpl_app = $this->windFactory->getInstance($_tpl_appName);'. + '$_tpl_app->getDispatcher()->setDisplay(true);'. + '$_tpl_app->doDispatch($_tpl_forward);'. + 'list($viewName, $tplVars) = $_tpl_app->getDispatcher()->getAttribute("viewCache");'. + '$this->windAssign($tplVars, $viewName);'; + return $_tmp; + } + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::getProperties() + */ + public function getProperties() { + return array('action', 'controller'); + } + +} \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerComponent.php b/wind/core/viewer/compiler/WindTemplateCompilerComponent.php new file mode 100644 index 00000000..d337ceca --- /dev/null +++ b/wind/core/viewer/compiler/WindTemplateCompilerComponent.php @@ -0,0 +1,52 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerComponent extends AbstractWindTemplateCompiler { + + protected $name = ''; + + protected $app = ''; + + protected $args = ''; + + protected $tpl = ''; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + $_output .= $this->getScript() . ''; + return $_output; + } + + /** + * @return string + */ + private function getScript() { + $_tmp = ''; + + return $_tmp; + } + + /** + * @return string + */ + private function getTplContent() { + + } + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::getProperties() + */ + protected function getProperties() { + return array('name', 'app', 'args', 'tpl'); + } +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerEcho.php b/wind/core/viewer/compiler/WindTemplateCompilerEcho.php new file mode 100644 index 00000000..34380003 --- /dev/null +++ b/wind/core/viewer/compiler/WindTemplateCompilerEcho.php @@ -0,0 +1,39 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + $_output = $content; + $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $_output); + $_output = $this->compileVarShare($_output); + return ''; + } + + /** + * @param string $input + * @return string + */ + private function compileVarShare($input) { + $input = trim($input); + if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) return $input; + list($templateName, $var) = explode(':', $input); + $input = '$this->response->getData(\'' . $templateName . '\', \'' . $var .'\')'; + return $input; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerInternal.php b/wind/core/viewer/compiler/WindTemplateCompilerInternal.php new file mode 100644 index 00000000..e205d20d --- /dev/null +++ b/wind/core/viewer/compiler/WindTemplateCompilerInternal.php @@ -0,0 +1,27 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerInternal extends AbstractWindTemplateCompiler { + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + //TODO php脚本特别解析 + + + return $content; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerPage.php b/wind/core/viewer/compiler/WindTemplateCompilerPage.php new file mode 100644 index 00000000..2af21444 --- /dev/null +++ b/wind/core/viewer/compiler/WindTemplateCompilerPage.php @@ -0,0 +1,87 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerPage extends AbstractWindTemplateCompiler { + protected $tpl = ''; + + protected $url = ''; + + protected $total = '0'; + + protected $page = '1'; + + protected $count = '0'; + + protected $per = '0'; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + return $this->getPageCode(); + + } + + private function getPageCode() { + empty($this->total) && $this->total = '0'; + empty($this->page) && $this->page = '1'; + empty($this->count) && $this->count = '0'; + empty($this->per) && $this->per = '0'; + empty($this->url) && $this->url = ''; + $strPageCode = + 'count . ';' . + '$_tplPagePer=(int)' . $this->per . ';' . + '$_tplPageTotal=(int)' . $this->total . ';' . + '$_tplPageCurrent=(int)' . $this->page . ';' . + '$_tplPageUrl=(string)"' . addslashes($this->url) . '";' . + 'if ($_tplPageCount > 0 && $_tplPagePer > 0) {' . + '$_tplTmpPageTotal = ceil($_tplPageCount / $_tplPagePer);' . + 'if ($_tplPageTotal > $_tplTmpPageTotal) $_tplPageTotal = $_tplTmpPageTotal;' . + '}' . + '$_tplPageCurrent > $_tplPageTotal && $_tplPageCurrent = $_tplPageTotal;' . + 'if ($_tplPageTotal > 1) {' . + "?>\r\n" . + $this->getTplContent() . + "\r\n"; + return $strPageCode; + } + + private function getTplContent() { + if ($this->tpl) { + list($compileFile, $content) = $this->windViewerResolver->compile($this->tpl, '', true); + } else { + $content = $this->getDefaultHtml(); + } + return $this->parsePageTags($content); + } + + private function parsePageTags($content) { + $arrPageTags = array('$total', '$page', '$url'); + $arrPageVars = array('$_tplPageTotal', '$_tplPageCurrent', '$_tplPageUrl'); + return str_ireplace($arrPageTags, $arrPageVars, $content); + } + + private function getDefaultHtml() { + return ''; + } + + /* + * @see AbstractWindTemplateCompiler::getProperties() + */ + public function getProperties() { + return array('tpl', 'total', 'page', 'per', 'count', 'url'); + } +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerScript.php b/wind/core/viewer/compiler/WindTemplateCompilerScript.php new file mode 100644 index 00000000..9dff218e --- /dev/null +++ b/wind/core/viewer/compiler/WindTemplateCompilerScript.php @@ -0,0 +1,36 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerScript extends AbstractWindTemplateCompiler { + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + $content = preg_replace_callback('/{\s*\$(\w)+((\-\>\w+)*(\(.*\))*(\[.*\])*)*?[;\s]*}/i', array($this, + 'doCompile'), $content); + return $content; + } + + /** + * 编译匹配到的结果 + * @param string $content + */ + public function doCompile($content) { + if (empty($content)) + return ''; + $_output = preg_replace(array('/^[\n\s{]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content[0]); + return ''; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/core/viewer/compiler/WindTemplateCompilerTemplate.php new file mode 100644 index 00000000..e5a19890 --- /dev/null +++ b/wind/core/viewer/compiler/WindTemplateCompilerTemplate.php @@ -0,0 +1,55 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerTemplate extends AbstractWindTemplateCompiler { + + protected $source = ''; + + protected $suffix = ''; + + protected $load = 'true'; + + protected $includeFiles = ''; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + if (!isset($this->source)) return $content; + preg_match('/[\$\(\/\\]]/i', $this->source, $result); + if (empty($result)) { + if ($this->load === 'false') { + $content = 'windViewerResolver->compile($this->source, $this->suffix)) . '\'); ?>'; + } else { + list($compileFile, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, true); + + $this->includeFiles .= $this->source . ':' . filemtime($compileFile) . ' '; + } + } else + $content = 'source . '); ?>'; + + return $content; + } + + protected function postCompile() { + + } + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::getProperties() + */ + public function getProperties() { + return array('source', 'suffix', 'load'); + } + +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindViewTemplate.php b/wind/core/viewer/compiler/WindViewTemplate.php new file mode 100644 index 00000000..b719bf56 --- /dev/null +++ b/wind/core/viewer/compiler/WindViewTemplate.php @@ -0,0 +1,176 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewTemplate extends AbstractWindViewTemplate { + + const COMPILER_ECHO = 'WIND:core.viewer.compiler.WindTemplateCompilerEcho'; + + /* 编译结果缓存 */ + protected $blockKey = ""; + + protected $compiledBlockData = array(); + + /** + * 模板编译器支持的标签信息 + * + * @var array('targName','args info') + */ + protected $_compilerCache = array(); + + protected $windHandlerInterceptorChain = null; + + /* (non-PHPdoc) + * @see AbstractWindViewTemplate::doCompile() + */ + protected function doCompile($content, $windViewerResolver = null) { + $content = $this->registerTags($content, $windViewerResolver); + if ($this->windHandlerInterceptorChain !== null) { + $this->windHandlerInterceptorChain->getHandler()->handle(); + } + foreach (array_reverse($this->compiledBlockData) as $key => $value) { + if (!$key) continue; + $content = str_replace($this->getBlockTag($key), ($value ? $value : ' '), $content); + } + $content = preg_replace('/\?>(\s|\n)*?<\?php/i', "\r\n", $content); + return $content; + } + + /* (non-PHPdoc) + * @see AbstractWindViewTemplate::getTags() + */ + protected function getTags() { + $_tags['internal'] = $this->createTag('internal', 'WIND:core.viewer.compiler.WindTemplateCompilerInternal', '/<\?php(.|\n)*?\?>/i'); + /*标签体增加在该位置*/ + $_tags['template'] = $this->createTag('template', 'WIND:core.viewer.compiler.WindTemplateCompilerTemplate'); + $_tags['page'] = $this->createTag('page', 'WIND:core.viewer.compiler.WindTemplateCompilerPage'); + $_tags['action'] = $this->createTag('action', 'WIND:core.viewer.compiler.WindTemplateCompilerAction'); + $_tags['component'] = $this->createTag('component', 'WIND:core.viewer.compiler.WindTemplateCompilerComponent'); + /*标签解析结束*/ + $_tags += (array) parent::getTags(); + $_tags['expression'] = $this->createTag('expression', 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', '/({@|{\$)[^{@=\n]*}/i'); + $_tags['echo'] = $this->createTag('echo', 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); + return $_tags; + } + + /** + * 创建tag配置 + * @param string $tag + * @param string $class + */ + private function createTag($tag, $class, $pattern = '') { + return array(self::TAG => $tag, self::PATTERN => $pattern, self::COMPILER => $class); + } + + /** + * 注册支持的标签并返回注册后的模板内容 + * @param string $content + * @param WindViewerResolver $windViewerResolver + * @return string + */ + private function registerTags($content, $windViewerResolver = null) { + foreach ((array) $this->getTags() as $key => $value) { + $compiler = isset($value[self::COMPILER]) ? $value[self::COMPILER] : ''; + $regex = isset($value[self::PATTERN]) ? $value[self::PATTERN] : ''; + $tag = isset($value[self::TAG]) ? $value[self::TAG] : ''; + if (!$compiler || !$tag) continue; + if ($regex === '') $regex = '/<(' . preg_quote($tag) . ')[^<>\n]*(\/>|>[^<>]*<\/\1>)/i'; + $content = $this->creatTagCompiler($content, $compiler, $regex, $windViewerResolver); + } + return $content; + } + + /** + * 创建标签解析器类 + * @param string content | 模板内容 + * @param string compiler | 标签编译器 + * @param string regex | 正则表达式 + * @param WindViewerResolver $windViewerResolver + */ + private function creatTagCompiler($content, $compiler, $regex, $windViewerResolver = null) { + $content = preg_replace_callback($regex, array($this, '_creatTagCompiler'), $content); + if ($this->windHandlerInterceptorChain === null) { + Wind::import('WIND:core.filter.WindHandlerInterceptorChain'); + $this->windHandlerInterceptorChain = new WindHandlerInterceptorChain(); + } + $_compilerClass = Wind::import($compiler); + if (!class_exists($_compilerClass)) return $content; + $this->windHandlerInterceptorChain->addInterceptors(new $_compilerClass($this->_compilerCache, $this, $windViewerResolver, $this->request, $this->response)); + $this->_compilerCache = array(); + return $content; + } + + /** + * 将标签匹配到的模板内容设置到缓存中,并返回标识位到模板中进行内容站位 + * @param string $content + * @return string|Ambigous --> + */ + private function _creatTagCompiler($content) { + $_content = $content[0]; + if (!$_content) return ''; + + $key = $this->getCompiledBlockKey(); + $this->_compilerCache[] = array($key, $_content); + return $this->getBlockTag($key); + } + + /** + * 对模板块存储进行标签处理 + * 将Key串 'HhQWFLtU0LSA3nLPLHHXMtTP3EfMtN3FsxLOR1nfYC5OiZTQri' 处理为 + * + * 在模板中进行位置标识 + * + * @param string $key | 索引 + * @return string|mixed | 处理后结果 + */ + private function getBlockTag($key) { + if (!$this->blockKey) return ''; + return str_replace('$', $key, $this->blockKey); + } + + /** + * 获得切分后块编译缓存Key值,Key值为一个50位的随机字符串,当产生重复串时继续查找 + * @return string + */ + protected function getCompiledBlockKey() { + Wind::import('WIND:component.utility.WindUtility'); + $key = WindUtility::generateRandStr(50); + if (key_exists($key, $this->compiledBlockData)) { + return $this->getCompiledBlockKey(); + } + return $key; + } + + /** + * 返回编译后结果,根据Key值检索编译后结果,并返回 + * @param string $key + * @return string + */ + public function getCompiledBlockData($key = '') { + if ($key) + return isset($this->compiledBlockData[$key]) ? $this->compiledBlockData[$key] : ''; + else + return $this->compiledBlockData; + } + + /** + * 根据key值保存编译后的模板块 + * @param string $key | 索引 + * @param string $compiledBlockData | 编译结果 + * @param boolean $isTag | 再结果处理时是否添加php脚本定界符 true 添加 ,flase 不添加 + */ + public function setCompiledBlockData($key, $compiledBlockData) { + if ($key) $this->compiledBlockData[$key] = $compiledBlockData; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/viewer/listener/WindViewCacheListener.php b/wind/core/viewer/listener/WindViewCacheListener.php new file mode 100644 index 00000000..a2476660 --- /dev/null +++ b/wind/core/viewer/listener/WindViewCacheListener.php @@ -0,0 +1,41 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewCacheListener extends WindHandlerInterceptor { + + private $windView = null; + + /** + * Enter description here ... + * @param WindView $windView + */ + function __construct($windView) { + $this->windView = $windView; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + //print_r($this->windView); + //TODO 读缓存 + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + //TODO 写缓存 + } +} + +?> \ No newline at end of file diff --git a/wind/core/web/IWindApplication.php b/wind/core/web/IWindApplication.php new file mode 100644 index 00000000..cd1c4b42 --- /dev/null +++ b/wind/core/web/IWindApplication.php @@ -0,0 +1,27 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindApplication { + + /** + * 请求处理 + */ + public function processRequest(); + + /** + * 请求转发 + * + * @param WindForward $forward + */ + public function doDispatch($forward); + +} + +?> \ No newline at end of file diff --git a/wind/core/web/IWindErrorMessage.php b/wind/core/web/IWindErrorMessage.php new file mode 100644 index 00000000..8ce16b3d --- /dev/null +++ b/wind/core/web/IWindErrorMessage.php @@ -0,0 +1,36 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindErrorMessage { + + /** + * 添加错误信息 + * @param string $message + * @param string $key + */ + public function addError($message, $key = ''); + + /** + * 获得一条Error信息 + * @param string $key + */ + public function getError($key = ''); + + /** + * 清空Error信息 + */ + public function clearError(); + + /** + * 发送错误信息 + */ + public function sendError(); +} + +?> \ No newline at end of file diff --git a/wind/core/web/WindAction.php b/wind/core/web/WindAction.php new file mode 100644 index 00000000..3ad06891 --- /dev/null +++ b/wind/core/web/WindAction.php @@ -0,0 +1,274 @@ + 2010-11-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.WindComponentModule'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class WindAction extends WindComponentModule { + + protected $forward = null; + + /** + * @var WindUrlHelper + */ + protected $urlHelper = null; + + /** + * @var WindErrorMessage + */ + protected $errorMessage = null; + + /** + * 默认的操作处理方法 + */ + public function run() {} + + /** + * Action操作预处理方法,返回boolean型值 + * @param AbstractWindRouter $handlerAdapter + * @return boolean + */ + public function beforeAction($handlerAdapter) {} + + /** + * Action操作后处理方法,在执行完Action后执行 + * @param AbstractWindRouter $handlerAdapter + * @return null + */ + public function afterAction($handlerAdapter) {} + + /** + * 根据路由信息重定向执行方法 + * + * @param AbstractWindRouter $handlerAdapter + */ + public function doAction($handlerAdapter) { + $this->setDefaultTemplateName($handlerAdapter); + $this->resolvedActionMethod($handlerAdapter); + $this->afterAction($handlerAdapter); + if ($this->getErrorMessage()->getError()) $this->getErrorMessage()->sendError(); + if ($this->request->getIsAjaxRequest()) $this->setLayout(''); + return $this->getForward(); + } + + /** + * 重定向一个请求到另外的Action + * + * @param string $action + * @param string $controller + * @param array $args + * @param boolean $isRedirect + */ + protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { + $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); + } + + /** + * 请求重定向到另外一个Url + */ + protected function forwardRedirect($url) { + $this->getForward()->setIsRedirect(true); + $this->getForward()->setUrl($url); + } + + /* 数据处理 */ + + /** + * 设置模板数据 + * + * @param string|array|object $data + * @param string $key + */ + protected function setOutput($data, $key = '') { + $this->getForward()->setVars($data, $key); + } + + /** + * 获得输入数据 + * 如果输入了回调方法则返回数组: + * 第一个值:value + * 第二个值:验证结果 + * + * @param string $name input name + * @param string $type input type (GET POST COOKIE) + * @param string $callback | validation for input + * @return array | string + */ + protected function getInput($name, $type = '', $callback = null) { + if (is_array($name)) + return $this->getInputWithArray($name, $type); + else + return $this->getInputWithString($name, $type, $callback); + } + + /* 模板处理 */ + /** + * 设置页面模板 + * @param string $template + */ + protected function setTemplate($template) { + $this->getForward()->getWindView()->setTemplateName($template); + } + + /** + * 设置模板路径 + * @param string $templatePath + */ + protected function setTemplatePath($templatePath) { + $this->getForward()->getWindView()->setTemplatePath($templatePath); + } + + /** + * 设置模板扩展名称 + * @param string $templateExt + */ + protected function setTemplateExt($templateExt) { + $this->getForward()->getWindView()->setTemplateExt($templateExt); + } + + /** + * 设置页面布局 + * 可以是一个布局对象或者一个布局文件 + * @param WindLayout|string $layout + */ + protected function setLayout($layout) { + $this->getForward()->getWindView()->setLayout($layout); + } + + /* 错误处理 */ + + /** + * 添加错误信息 + * @param string $message + * @param string $key + */ + protected function addMessage($message, $key = '') { + $this->getErrorMessage()->addError($message, $key); + } + + /** + * 发送一个错误 + * @param string $message + * @param string $key + * @param string $errorAction + * @param string $errorController + */ + protected function showMessage($message = '', $key = '', $errorAction = '', $errorController = '') { + $this->addMessage($message, $key); + $this->getErrorMessage()->setErrorAction($errorAction); + $this->getErrorMessage()->setErrorController($errorController); + $this->getErrorMessage()->sendError(); + } + + /** + * 返回一个错误处理对象 + * @return WindErrorMessage $errorMessage + */ + public function getErrorMessage() { + if ($this->errorMessage === null) { + throw new WindException(__CLASS__ . '::getError(), Actually get a null', WindException::ERROR_RETURN_TYPE_ERROR); + } + return $this->errorMessage; + } + + /** + * 返回UrlHelper对象 + * + * @return WindUrlHelper + */ + protected function getUrlHelper() { + if ($this->urlHelper === null) { + throw new WindException('urlHelper', WindException::ERROR_CLASS_NOT_EXIST); + } + return $this->urlHelper; + } + + /** + * @return WindForward + */ + protected function getForward() { + if ($this->forward === null) { + throw new WindException('windForward', WindException::ERROR_CLASS_NOT_EXIST); + } + return $this->forward; + } + + /** + * 设置默认的模板名称 + * + * @param WindUrlBasedRouter $handlerAdapter + */ + protected function setDefaultTemplateName($handlerAdapter) { + $_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); + $this->setTemplate($_temp); + } + + /** + * 获得Action处理方法 + * + * @param AbstractWindRouter $handlerAdapter + */ + protected function resolvedActionMethod($handlerAdapter) { + call_user_func_array(array($this, 'run'), array()); + } + + /** + * Enter description here ... + * + * @param unknown_type $name + * @param unknown_type $type + * @return Ambigous + */ + private function getInputWithString($name, $type = '', $callback = array()) { + $value = ''; + switch (strtolower($type)) { + case 'form': + $value = $this->response->getData($name); + break; + case IWindRequest::INPUT_TYPE_GET: + $value = $this->request->getGet($name); + break; + case IWindRequest::INPUT_TYPE_POST: + $value = $this->request->getPost($name); + break; + case IWindRequest::INPUT_TYPE_COOKIE: + $value = $this->request->getCookie($name); + break; + default: + $value = $this->request->getAttribute($name); + } + return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; + } + + /** + * Enter description here ... + * + * @param string $name + * @param string $type + * @return array + */ + private function getInputWithArray($name, $type = '') { + $result = array(); + foreach ($name as $key => $value) { + $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); + } + return $result; + } + + /* (non-PHPdoc) + * @see WindModule::getWriteTableForGetterAndSetter() + */ + protected function getWriteTableForGetterAndSetter() { + return array('forward', 'urlHelper', 'errorMessage'); + } + +} \ No newline at end of file diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php new file mode 100644 index 00000000..222efbf1 --- /dev/null +++ b/wind/core/web/WindController.php @@ -0,0 +1,62 @@ + 2010-11-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.web.WindAction'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class WindController extends WindAction { + + protected $validatorClass = 'WIND:component.utility.WindValidator'; + + /* (non-PHPdoc) + * @see WindAction::resolvedActionMethod() + */ + protected function resolvedActionMethod($handlerAdapter) { + $action = $handlerAdapter->getAction(); + if ($action !== 'run') $action = $this->resolvedActionName($action); + try { + $method = new ReflectionMethod($this, $action); + } catch (Exception $exception) { + throw new WindActionException('The action method ' . $action . ' is protected or not exist.'); + } + if ($action !== 'doAction' && !$method->isAbstract() && $method->isPublic()) + call_user_func_array(array($this, $action), array()); + else + throw new WindException(); + } + + /** + * 根据请求的Action值返回Action的真正方法名 + * 可以通过覆盖该方法来改变Action的命名规则 + * @param string $action + * @return string + */ + protected function resolvedActionName($action) { + return $action . 'Action'; + } + + /** + * 实现表单验证规则 + * @param string $type + */ + public function validatorFormRule($type) { + return array(); + } + + /** + * @return the $validatorClass + */ + public function getValidatorClass() { + return $this->validatorClass; + } + +} \ No newline at end of file diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php new file mode 100644 index 00000000..761c9e16 --- /dev/null +++ b/wind/core/web/WindDispatcher.php @@ -0,0 +1,126 @@ + 2010-12-15 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.WindComponentModule'); +/** + * 请求分发 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindDispatcher extends WindComponentModule { + + protected $oldRouter = null; + + protected $display = false; + + /** + * 请求分发处理 + * @param WindForward $forward + */ + public function dispatch($forward) { + $this->oldRouter = clone $this->windFactory->getInstance(COMPONENT_ROUTER); + if ($forward->getIsRedirect()) + $this->dispatchWithRedirect($forward); + elseif ($forward->getIsReAction()) + $this->dispatchWithAction($forward); + else + $this->render($forward); + $this->destroy(); + } + + /** + * 请求分发一个重定向请求 + * @param WindForward $forward + */ + protected function dispatchWithRedirect($forward) { + $_url = $forward->getUrl(); + //TODO check $_url 在urlHelper中添加url检测方法,检查是否是一个正确的Url形式,包括包含不包含域名等 + $urlHelper = $this->windFactory->getInstance(COMPONENT_URLHELPER); + if (!$_url && $forward->getIsReAction()) { + /* @var $urlHelper WindUrlHelper */ + $_url = $urlHelper->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); + } + $_url = $urlHelper->checkUrl($_url); + $_router = $this->windFactory->getInstance(COMPONENT_ROUTER); + $_router->reParse(); + if ($forward->getIsReAction() && !$this->checkProcess($_router)) { + throw new WindException('Duplicate request ' . $_router->getAction() . '_' . $_router->getController() . '.' . $_router->getModule()); + } + $this->response->sendRedirect($_url); + } + + /** + * 请求分发一个操作请求 + * @param WindForward $forward + */ + protected function dispatchWithAction($forward) { + $_a = $forward->getAction(); + list($_c, $_m) = WindBase::resolveController($forward->getController()); + + /* @var $_router WindUrlBasedRouter */ + $_router = $this->windFactory->getInstance(COMPONENT_ROUTER); + $_a && $_router->setAction($_a); + $_c && $_router->setController($_c); + $_m && $_router->setModule($_m); + if (!$this->checkProcess($_router)) { + throw new WindException('Duplicate request ' . $_router->getAction() . '_' . $_router->getController() . '.' . $_router->getModule()); + } + + $appName = $this->windSystemConfig->getAppClass(); + $application = $this->windFactory->getInstance($appName); + $application->processRequest(); + } + + /** + * 检查请求是否是重复请求 + * @param AbstractWindRouter $router + * @param string $action + * @param string $controller + */ + protected function checkProcess($router) { + if ($router->getAction() !== $this->oldRouter->getAction()) return true; + if ($router->getController() !== $this->oldRouter->getController()) return true; + if ($router->getModule() !== $this->oldRouter->getModule()) return true; + return false; + } + + /** + * 进行视图渲染 + * @param WindForward $forward + */ + protected function render($forward) { + if ($forward && null !== ($windView = $forward->getWindView())) { + if ($windView->getTemplateName() === '') return; + $viewResolver = $windView->getViewResolver(); + $this->response->setData($forward->getVars(), $windView->getTemplateName()); + if ($this->display === false) + $this->response->setBody($viewResolver->windFetch(), $windView->getTemplateName()); + else + $viewResolver->displayWindFetch(); + } else + throw new WindException('unable to create the object with forward.'); + } + + /* (non-PHPdoc) + * @see WindModule::getWriteTableForGetterAndSetter() + */ + public function getWriteTableForGetterAndSetter() { + return array('display'); + } + + /** + * 注销当前dispatcher状态 + */ + protected function destroy() { + $this->display = false; + $this->oldRouter = null; + } +} diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php new file mode 100644 index 00000000..91ecee28 --- /dev/null +++ b/wind/core/web/WindErrorHandler.php @@ -0,0 +1,154 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindErrorHandler extends WindController { + protected $error = array(); + protected $urlReferer = ''; + + /* (non-PHPdoc) + * @see WindAction::beforeAction() + */ + public function beforeAction($handlerAdapter) { + $this->error = $this->getInput('error'); + if ($this->request->getUrlReferer()) + $this->urlReferer = $this->request->getUrlReferer(); + else + $this->urlReferer = $this->request->getBaseUrl(); + return true; + } + + /* (non-PHPdoc) + * @see WindAction::run() + */ + public function run() { + $_tmp = "User Message:\r\n"; + $i = 0; + foreach ($this->error as $key => $value) { + $i++; + $_tmp .= "#$i " . $value . "\r\n"; + } + echo "

User Message: (" . count($this->error) . ")

"; + echo "

" . nl2br($_tmp) . "

"; + echo "
Click to go back."; + $this->addLog("User Error:", $_tmp); + exit(); + } + + /** + * @param string $errno + * @param string $errstr + * @param string $errfile + * @param string $errline + */ + final public function errorHandle($errno, $errstr, $errfile, $errline) { + if ($errno & error_reporting()) { + $errfile = $this->getFile($errfile); + $_tmp = "$errstr ($errfile:$errline)\r\nStack trace:\r\n"; + $_trace = debug_backtrace(false); + foreach ($_trace as $key => $value) { + if (!isset($value['file'])) continue; + if (!isset($value['line'])) $value['line'] = 0; + if (!isset($value['function'])) continue; + $_tmp .= "#$key {$value['file']}({$value['line']}): "; + if (isset($value['object']) && is_object($value['object'])) $_tmp .= get_class($value['object']) . '->'; + $_tmp .= "{$value['function']}()\r\n"; + } + if (IS_DEBUG) { + echo "

" . $this->errnoMap($errno) . " $errstr

"; + echo "

" . nl2br($_tmp) . "

"; + } else + echo "

" . $this->errnoMap($errno) . " $errstr

"; + $this->addLog($this->errnoMap($errno) . $errstr, $_tmp); + } + } + + /** + * Enter description here ... + * @param $string $errno + */ + private function errnoMap($errno) { + $_tmp = ''; + switch ($errno) { + case E_ERROR: + $_tmp = "Error"; + break; + case E_WARNING: + $_tmp = "Warning"; + break; + case E_PARSE: + $_tmp = "Parse Error"; + break; + case E_NOTICE: + $_tmp = "Notice"; + break; + case E_CORE_ERROR: + $_tmp = "Core Error"; + break; + case E_CORE_WARNING: + $_tmp = "Core Warning"; + break; + case E_COMPILE_ERROR: + $_tmp = "Compile Error"; + break; + case E_COMPILE_WARNING: + $_tmp = "Compile Warning"; + break; + case E_USER_ERROR: + $_tmp = "User Error"; + break; + case E_USER_WARNING: + $_tmp = "User Warning"; + break; + case E_USER_NOTICE: + $_tmp = "User Notice"; + break; + case E_STRICT: + $_tmp = "Strict Notice"; + break; + case E_RECOVERABLE_ERROR: + $_tmp = "Recoverable Error"; + break; + default: + $_tmp = "Unknown error ($errno)"; + break; + } + return $_tmp; + } + + /** + * 异常处理句柄 + */ + final public function exceptionHandle($exception) { + $_tmp = $exception->getMessage() . ' (' . $this->getFile($exception->getFile()) . ':' . $exception->getLine() . ')'; + if (IS_DEBUG) { + echo '

' . get_class($exception) . '

'; + echo "

$_tmp

"; + echo '
' . $exception->getTraceAsString() . '
'; + } else { + echo '

' . get_class($exception) . '

'; + echo '

' . $exception->getMessage() . '

'; + } + $this->addLog($_tmp, $exception->getTraceAsString()); + exit(); + } + + private function getFile($filePath) { + return $filePath; + } + + /** + * 日志记录 + * @param string $errno + * @param string $message + */ + private function addLog($errno, $message) { + Wind::import('WIND:component.log.WindLogger'); + $logger = new WindLogger(); + $logger->info("$errno:" . $message); + } +} \ No newline at end of file diff --git a/wind/core/web/WindErrorMessage.php b/wind/core/web/WindErrorMessage.php new file mode 100644 index 00000000..11cc527e --- /dev/null +++ b/wind/core/web/WindErrorMessage.php @@ -0,0 +1,92 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindErrorMessage implements IWindErrorMessage { + private $error = array(); + private $errorAction = 'run'; + /** + * @var string + */ + private $errorController = WIND_M_ERROR; + + /** + * @param string $message + */ + public function __construct($message = '', $errorAction = '', $errorController = '') { + $this->addError($message); + $this->setErrorAction($errorAction); + $this->setErrorController($errorController); + } + + /* (non-PHPdoc) + * @see IWindErrorMessage::sendError() + */ + public function sendError() { + throw new WindActionException($this); + } + + /* (non-PHPdoc) + * @see IWindErrorMessage::clearError() + */ + public function clearError() { + $this->error = array(); + } + + /* (non-PHPdoc) + * @see IWindErrorMessage::getError() + */ + public function getError($key = '') { + if ($key === '') + return $this->error; + else + return isset($this->error[$key]) ? $this->error[$key] : ''; + } + + /* (non-PHPdoc) + * @see IWindErrorMessage::addError() + */ + public function addError($error, $key = '') { + if (!$error) return; + if ($key === '') { + if (is_string($error)) + $this->error[] = $error; + elseif (is_object($error)) + $error = get_object_vars($error); + if (is_array($error)) $this->error += $error; + } else + $this->error[$key] = $error; + } + + /** + * @return the $errorAction + */ + public function getErrorAction() { + return $this->errorAction; + } + + /** + * @return the $errorController + */ + public function getErrorController() { + return $this->errorController; + } + + /** + * @param field_type $errorAction + */ + public function setErrorAction($errorAction) { + if ($errorAction) $this->errorAction = $errorAction; + } + + /** + * @param field_type $errorController + */ + public function setErrorController($errorController) { + if ($errorController) $this->errorController = $errorController; + } +} \ No newline at end of file diff --git a/wind/core/web/WindFormController.php b/wind/core/web/WindFormController.php new file mode 100644 index 00000000..dc3d03e4 --- /dev/null +++ b/wind/core/web/WindFormController.php @@ -0,0 +1,56 @@ + 2010-11-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.base.WindAction'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFormController extends WindAction { + + protected $formClass = ''; + + /* (non-PHPdoc) + * @see WindAction::resolvedActionMethod() + */ + protected function resolvedActionMethod($handlerAdapter) { + $action = $handlerAdapter->getAction(); + if ($action !== 'run') $action = $this->resolvedActionName($action); + try { + $method = new ReflectionMethod($this, $action); + } catch (Exception $exception) { + throw new WindActionException('The action method ' . $action . ' is protected or not exist.'); + } + if ($action !== 'doAction' && !$method->isAbstract() && $method->isPublic()) + call_user_func_array(array($this, $action), array()); + else + throw new WindException(); + } + + /** + * 根据请求的Action值返回Action的真正方法名 + * 可以通过覆盖该方法来改变Action的命名规则 + * @param string $action + * @return string + */ + protected function resolvedActionName($action) { + return $action . 'Action'; + } + + /** + * 返回form的类 + * @return the $formClass + */ + public function getFormClass() { + return $this->formClass; + } +} + +?> \ No newline at end of file diff --git a/wind/core/web/WindForward.php b/wind/core/web/WindForward.php new file mode 100644 index 00000000..07335ee7 --- /dev/null +++ b/wind/core/web/WindForward.php @@ -0,0 +1,201 @@ + 2010-11-22 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.WindComponentModule'); +/** + * 操作转发类,将操作句柄转发给下一个操作或者转发给一个视图处理 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindForward extends WindComponentModule { + + /** + * 模板视图信息 + * + * @var WindView + */ + private $windView = null; + + /** + * 模板变量信息 + * + * @var array + */ + private $vars = array(); + + /** + * 是否为Action请求 + * + * @var boolean + */ + private $isReAction = false; + + /** + * 是否是重定向请求 + * + * @var boolean + */ + private $isRedirect = false; + + /** + * 跳转链接 + * + * @var string + */ + private $url = ''; + + private $action = ''; + + private $controller = ''; + + private $args = ''; + + /** + * 将请求重定向到另外一个Action操作 + * + * @param string $action | $action 操作 + * @param string $controller | controller 路径 , controller 为空是则指向当前的控制器 + * @param array $args | 参数 + * @param boolean $isRedirect | 是否重定向 + * + * @return null + */ + public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = '') { + $this->setIsReAction(true); + $this->setAction($action); + $this->setController($controller); + $this->setArgs($args); + $isRedirect !== '' && $this->setIsRedirect($isRedirect); + } + + /** + * 设置页面模板变量 + * + * @param string|array|object $vars + * @param string $key + */ + public function setVars($vars, $key = '') { + if (!$key) { + if (is_object($vars)) $vars = get_object_vars($vars); + if (is_array($vars)) $this->vars += $vars; + } else + $this->vars[$key] = $vars; + return; + } + + /** + * @return WindView $windView + */ + public function getWindView() { + if ($this->windView === null) { + $module = $this->windFactory->getInstance(COMPONENT_ROUTER)->getModule(); + $moduleConfig = $this->windSystemConfig->getModules($module); + $view = $this->windSystemConfig->getConfig('view', WindSystemConfig::CLASS_PATH, (array) $moduleConfig); + if (!$view) $view = COMPONENT_VIEW; + + $this->windView = $this->windFactory->getInstance($view); + $_viewConfig = $this->windView->getConfig('view', WIND_CONFIG_CONFIG, $moduleConfig); + if ($_viewConfig) $this->windView->updateConfig($_viewConfig, true); + } + return $this->windView; + } + + /** + * @return the $isRedirect + */ + public function getIsRedirect() { + return $this->isRedirect; + } + + /** + * @param boolean $isRedirect + */ + public function setIsRedirect($isRedirect) { + $this->isRedirect = $isRedirect; + } + + /** + * @return the $isReAction + */ + public function getIsReAction() { + return $this->isReAction; + } + + /** + * @param boolean $isReAction + */ + public function setIsReAction($isReAction) { + $this->isReAction = $isReAction; + } + + /** + * @return the $vars + */ + public function getVars() { + return $this->vars; + } + + /** + * @return the $url + */ + public function getUrl() { + return $this->url; + } + + /** + * @param string $url + */ + public function setUrl($url) { + $this->url = $url; + } + + /** + * @return the $action + */ + public function getAction() { + return $this->action; + } + + /** + * @return the $controller + */ + public function getController() { + return $this->controller; + } + + /** + * @return the $args + */ + public function getArgs() { + return $this->args; + } + + /** + * @param field_type $action + */ + public function setAction($action) { + $this->action = $action; + } + + /** + * @param field_type $controller + */ + public function setController($controller) { + $this->controller = $controller; + } + + /** + * @param field_type $args + */ + public function setArgs($args) { + $this->args = $args; + } + +} \ No newline at end of file diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php new file mode 100644 index 00000000..84832c2f --- /dev/null +++ b/wind/core/web/WindFrontController.php @@ -0,0 +1,172 @@ + 2010-10-27 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2010 phpwind.com + * @license + */ + +Wind::import('WIND:core.AbstractWindServer'); +/** + * 抽象的前端控制器接口,通过集成该接口可以实现以下职责 + * + * 职责定义: + * 接受客户请求 + * 处理请求 + * 向客户端发送响应 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFrontController extends AbstractWindServer { + + const WIND_CONFIG = 'WIND:core.config.WindSystemConfig'; + + const WIND_FACTORY = 'WIND:core.factory.WindComponentFactory'; + + const COMPONENTS_CONFIG = 'WIND:config.components_config.php'; + + /** + * @var WindSystemConfig + */ + protected $windSystemConfig = null; + + protected $windFactory = null; + + protected $windErrorHandler = null; + + /** + * @param WindConfig $windConfig + * @param WindFactory $windFactory + */ + public function __construct($appName, $config = array()) { + parent::__construct(); + $this->initWindConfig($appName, $config); + $this->initWindFactory(); + } + + /** + * 初始化类工厂 + */ + protected function initWindFactory() { + $configPath = Wind::getRealPath(self::COMPONENTS_CONFIG); + $classesDefinitions = $this->getWindConfig()->getConfigParser()->parse($configPath, 'components', WIND_CONFIG_CACHE); + $factoryClass = Wind::import(self::WIND_FACTORY); + if (!class_exists($factoryClass)) { + throw new WindException($factoryClass, WindException::ERROR_CLASS_NOT_EXIST); + } + $this->windFactory = new $factoryClass($classesDefinitions); + } + + /** + * Enter description here ... + * + * @param string $appName + * @param string $config + */ + protected function initWindConfig($appName, $config) { + Wind::import('WIND:core.config.parser.WindConfigParser'); + Wind::import('WIND:core.config.WindSystemConfig'); + $configParser = new WindConfigParser(); + $this->windSystemConfig = new WindSystemConfig($config, $configParser, ($appName ? $appName : 'default')); + Wind::register($this->getWindConfig()->getRootPath(), $this->getWindConfig()->getAppName()); + + //TODO register all apps + } + + /* (non-PHPdoc) + * @see wind/core/base/WindServer#process() + */ + protected function process(WindHttpRequest $request, WindHttpResponse $response) { + $this->getWindFactory()->request = $request; + $this->getWindFactory()->response = $response; + $request->setAttribute(self::WIND_CONFIG, $this->windSystemConfig); + $request->setAttribute(self::WIND_FACTORY, $this->windFactory); + + $appName = $this->getWindConfig()->getAppClass(); + $application = $this->getWindFactory()->getInstance($appName); + if (null === $application) { + throw new WindException('application', WindException::ERROR_CLASS_NOT_EXIST); + } + + $this->getWindFactory()->application = $application; + if (null !== $filterChain = $this->getFilterChain()) { + $filterChain->setCallBack(array($application, 'processRequest'), array()); + $filterChain->getHandler()->handle($request, $response); + } else + $application->processRequest(); + + } + + /** + * @return WindFilterChain + */ + private function getFilterChain() { + $filterChainPath = $this->getWindConfig()->getFilters(WindSystemConfig::CLASS_PATH); + return $this->getWindFactory()->createInstance($filterChainPath, array($this->getWindConfig()->getFilters())); + } + + /* (non-PHPdoc) + * @see AbstractWindServer::beforeProcess() + */ + protected function beforeProcess(WindHttpRequest $request, WindHttpResponse $response) { + Wind::import('WIND:core.web.WindErrorHandler'); + set_error_handler(array(new WindErrorHandler(), 'errorHandle'), error_reporting()); + set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); + } + + /* (non-PHPdoc) + * @see AbstractWindServer::afterProcess() + */ + protected function afterProcess(WindHttpRequest $request, WindHttpResponse $response) { + //add log + if (IS_DEBUG) { + /* @var $logger WindLogger */ + $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); + $logger->flush(); + } + restore_error_handler(); + restore_exception_handler(); + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @throws Exception + */ + protected function doPost(WindHttpRequest $request, WindHttpResponse $response) { + $this->process($request, $response); + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @throws Exception + */ + protected function doGet(WindHttpRequest $request, WindHttpResponse $response) { + $this->process($request, $response); + } + + /** + * @return WindSystemConfig $windConfig + */ + public function getWindConfig() { + if ($this->windSystemConfig instanceof WindConfig) + return $this->windSystemConfig; + else + throw new WindException(get_class($this) . '->windSystemConfig', WindException::ERROR_CLASS_TYPE_ERROR); + } + + /** + * @return WindFactory $windFactory + */ + public function getWindFactory() { + if ($this->windFactory instanceof WindFactory) + return $this->windFactory; + else + throw new WindException(get_class($this) . '->windFactory', WindException::ERROR_CLASS_TYPE_ERROR); + } + +} \ No newline at end of file diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php new file mode 100644 index 00000000..52838ac4 --- /dev/null +++ b/wind/core/web/WindUrlHelper.php @@ -0,0 +1,357 @@ + 2010-10-27 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2010 phpwind.com + * @license + */ + +/** + * Enter description here ... + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindUrlHelper extends WindComponentModule { + + const URL_PATTERN = 'url-pattern'; + + const ROUTE_SUFFIX = 'route-suffix'; + + const ROUTE_PARAM = 'route-param'; + + const REWRITE = false; + + const ROUTE_SEPARATOR = '_'; + + protected $routeSuffix = ''; + + protected $routeParam = ''; + + protected $urlPattern = ''; + + protected $windRouter = null; + + public function isRewrite() { + return self::REWRITE; + } + + /** + * 解析Url + * + * 没有配置解析规则,直接返回 + * 获得则匹配RequestUri,根据用户的配置分隔符分割信息 + * 同时设置到超全局变量$_GET中 + */ + public function parseUrl() { + if ((($uri = $this->request->getServer('QUERY_STRING')) == '') || !$this->isRewrite()) return; + if (($pattern = $this->getUrlPattern()) == '') return; + $seperator = isset($pattern[1]) ? $pattern[1] : $pattern[0]; + $uri = explode($seperator, $uri); + if (strcasecmp($pattern, "=&") != 0) $params = $this->parseUrlToParams($uri, $seperator, $pattern[0]); + $_GET = array_merge($_GET, $params); + $this->matchRouter(array_pop($uri)); + } + + /** + * 构造返回Url地址 + * + * 将根据是否开启url重写来分别构造相对应的url + * + * @param string $action 执行的操作 + * @param string $controller 执行的controller + * @param array $params 附带的参数 + * @return string + */ + public function createUrl($action, $controller, $params = array()) { + $action && $this->getWindRouter()->setAction($action); + list($_c, $_m) = WindBase::resolveController($controller); + $_c && $this->getWindRouter()->setController($_c); + $_m && $this->getWindRouter()->setModule($_m); + $url = $this->getWindRouter()->buildUrl(); + $server = $this->getUrlServer(); + if ($this->isRewrite()) { + $server = substr($server, 0, strrpos($server, '/')); + $url = $server . $this->buildRewriteURL($params, $url); + } else { + $url = $server . $url . '&' . $this->buildUrl($params); + } + return $url; + } + + /** + * 返回域名及请求路径 + * + * @param boolean $hasPath 是否含有路径信息 + * @return string + */ + private function getUrlServer($hasPath = true) { + list($protocol, ) = explode('/', $this->request->getProtocol()); + $protocol = strtolower($protocol) . '://' . $this->request->getServer('SERVER_NAME'); + ($hasPath) && $protocol .= $this->request->getServer('PHP_SELF'); + return $protocol; + } + + /** + * 执行匹配 + * + * 获得匹配的结果 + * 对于路由信息, + * 如果没有路由信息,则表示缺省 + * 如果路由中只有一个值,则代表缺省的是m和a + * 如果路由中只有两个值,则代表缺省的是m + * + * @param string 待分析匹配的路由信息 + */ + private function matchRouter($mca) { + if (strrpos($mca, '.' . $this->getRouteSuffix()) === false) return; + $mca = trim(rtrim($mca, '.' . $this->getRouteSuffix())); + if ($mca == '') return; + $mca = explode(self::ROUTE_SEPARATOR, $mca); + $m = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_MODULE); + $c = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_CONTROLLER); + $a = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_ACTION); + if (count($mca) == 1) { + $_GET[$c] = $mca[0]; + } elseif (count($mca) == 2) { + $_GET[$c] = $mca[0]; + $_GET[$a] = $mca[1]; + } else { + ($mca[0]) && $_GET[$m] = $mca[0]; + ($mca[1]) && $_GET[$c] = $mca[1]; + ($mca[2]) && $_GET[$a] = $mca[2]; + } + return; + } + + /** + * 解析uri参数成key-value关联数组形式 + * + * 如果key-value和参数之间,两种的分隔符相同,则采用配对匹配的模式,如果不相同,则对每一对key-value的值进行再次解析 + * + * 如果key是字符串,则直接赋值, + * 如果key是数组: + * 如果key的数组没有键值,则采用数组索引自增的方式 + * 如果key的数组拥有键值,则将该键值作为key来传递 + * + * @param array $url + * @param string $seprator + * @param string $keyAsValue + * @return array + */ + private function parseUrlToParams($url, $seprator = '', $keyAsValue = '=') { + $params = array(); + if ($seprator == $keyAsValue) { + $n = count($url); + for ($i = 0; $i < $n / 2; $i++) { + $k = 2 * $i; + $v = $k + 1; + if (isset($url[$v])) { + $this->parseKey($params, $url[$k], $url[$v]); + } + } + return $params; + } + foreach ((array) $url as $key => $value) { + if (strpos($value, $keyAsValue) === false) continue; + list($key, $value) = explode($keyAsValue, $value); + $this->parseKey($params, $key, $value); + } + return $params; + } + + /** + * 解析url的parama信息中的key值 + * + * 如果key值不存在'[',']'字符,则该key为字符串,直接返回 + * 如果key值存在,并且'['和']'之前没有字符,则表示该key是将是一个数组,并且键值自增,返回array($key) + * 如果key值存在,并且'['和']'之前有字符,则表示该key是一个数组,并且'['和']'其中的字符是该数组中的键值,返回array(key值, 键值) + * + * //TODO 需要考虑多维数组的情况 + * @param string $key + * @return string|array 返回匹配的结果 + */ + private function parseKey(&$params, $key, $value) { + if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { + $params[$key] = $value; + return; + } + $name = substr($key, 0, $pos); + if ($pos2 === $pos + 1) { + $params[$name][] = $value; + return; + } else { + $key = substr($key, $pos + 1, $pos2 - $pos - 1); + $params[$name][$key] = $value; + return; + } + } + + /** + * 获得配置 + * + * 获得用户对于module controller action的对应配置(url-parmar) + * + * @param string $type 查找类型(module,controller,action); + * @param string $type 返回用户对应的设置,如果不存在则返回本身 + */ + private function getUrlParamConfig($type) { + $_config = $this->getWindRouter()->getConfig(WindUrlBasedRouter::URL_RULE); + if ($_param = $this->getConfig($type, WindUrlBasedRouter::URL_PARAM, $_config)) { + return $_param; + } + return $type; + } + + /** + * 获得分割符 + * + * @return array array(key-value分割符,参数之间分隔符) + */ + private function getSeparator() { + (($pattern = $this->getUrlPattern()) == '') && $pattern = '=&'; + $separator = isset($pattern[1]) ? $pattern[1] : $pattern[0]; + return array($pattern[0], $separator); + } + + /** + * 构造重写的url + * + * @param array $params + * @param string $routerInfo + * @return string 返回重写后的url + */ + private function buildRewriteURL($params, $routerInfo) { + $routerInfo = $this->parseUrlToParams(explode('&', trim($routerInfo, '?')), '&', '='); + $routerInfo = implode(self::ROUTE_SEPARATOR, $routerInfo) . '.' . $this->getRouteSuffix(); + $separator = $this->getSeparator(); + if (empty($params)) return $separator[1] . $routerInfo; + $url = ''; + foreach ((array)$params as $key => $value) { + $url .= $this->buildKey($key, $value, $separator[0], $separator[1]) . $separator[1]; + } + return $separator[1] . $url . $routerInfo; + } + + /** + * 构造url的辅助函数 + * + * 支持数组的传递(建议最多传递一维) + * + * @param string $parentKey key + * @param string $parentValue key对应的值 + * @param string $keyAsValue key-value的分隔符 + * @param string $separator 参数之间的分割符 + * @param boolean $flag 标志 + * @return string + */ + private function buildKey($parentKey, $parentValue, $keyAsValue, $separator, $flag = false) { + $flag && $parentKey = is_numeric($parentKey) ? '[]' : '[' . $parentKey . ']'; + if (!is_array($parentValue)) return $parentKey . $keyAsValue . urlencode($parentValue); + $keys = array(); + foreach ($parentValue as $key => $value) { + $keys[] = $parentKey . $this->buildKey($key, $value, $keyAsValue, $separator, true); + } + return implode($separator, $keys); + } + + /** + * 构造普通的url + * + * @param array $params + * @return string + */ + private function buildUrl($params) { + if (empty($params)) return ''; + $url = ''; + foreach ((array) $params as $key => $value) { + $url .= $this->buildKey($key, $value, '=', '&', false) . '&'; + } + return trim($url, '&'); + } + + /** + * 检查Url地址的正确性,并返回正确的URL地址 + * + * @param string $url + * @return string $url + */ + public function checkUrl($url) { + list($protocal, $serverName) = explode('://', $this->getUrlServer(false)); + $pos1 = stripos($url, $protocal); + $pos2 = stripos($url, $serverName); + if (false === $pos1 && false === $pos2) return $protocal . '://' . $serverName . '/' . ltrim($url, '/'); + if (false === $pos1) return $protocal . '://' . ltrim($url, '/'); + return $url; + } + + /** + * @return the $routeSuffix + */ + public function getRouteSuffix() { + if ($this->routeSuffix === '') { + $this->routeSuffix = $this->getConfig(self::ROUTE_SUFFIX, WindSystemConfig::VALUE); + } + return $this->routeSuffix; + } + + /** + * @return the $routeParam + */ + public function getRouteParam() { + if ($this->routeParam === '') { + $this->routeParam = $this->getConfig(self::ROUTE_PARAM, WindSystemConfig::VALUE); + } + return $this->routeParam; + } + + /** + * @return the $urlPattern + */ + public function getUrlPattern() { + if ($this->urlPattern === '') { + $this->urlPattern = $this->getConfig(self::URL_PATTERN, WindSystemConfig::VALUE); + } + return $this->urlPattern; + } + + /** + * @param field_type $routeSuffix + */ + public function setRouteSuffix($routeSuffix) { + $this->routeSuffix = $routeSuffix; + } + + /** + * @param field_type $routeParam + */ + public function setRouteParam($routeParam) { + $this->routeParam = $routeParam; + } + + /** + * @param field_type $urlPattern + */ + public function setUrlPattern($urlPattern) { + $this->urlPattern = $urlPattern; + } + + /** + * @return AbstractWindRouter $windRouter + */ + public function getWindRouter() { + return $this->windRouter; + } + + /** + * @param field_type $windRouter + */ + public function setWindRouter($windRouter) { + $this->windRouter = $windRouter; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php new file mode 100644 index 00000000..8796bde7 --- /dev/null +++ b/wind/core/web/WindWebApplication.php @@ -0,0 +1,177 @@ + 2010-11-7 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +Wind::import('WIND:core.WindComponentModule'); +Wind::import('WIND:core.web.IWindApplication'); +Wind::import('WIND:core.factory.WindComponentDefinition'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindWebApplication extends WindComponentModule implements IWindApplication { + + const ERROR_HANDLER = 'error-handler'; + + protected $dispatcher = null; + + protected $errorHandle = 'WIND:core.web.WindErrorHandler'; + + /* (non-PHPdoc) + * @see IWindApplication::processRequest() + */ + public function processRequest() { + try { + //add log + if (IS_DEBUG) { + /* @var $logger WindLogger */ + $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); + $logger->debug('do processRequest of ' . get_class($this)); + } + + $handler = $this->getHandler(); + $forward = call_user_func_array(array($handler, 'doAction'), array($this->getHandlerAdapter())); + if ($forward === null) { + throw new WindException('doAction', WindException::ERROR_RETURN_TYPE_ERROR); + } + $this->doDispatch($forward); + } catch (WindActionException $actionException) { + $this->sendErrorMessage($actionException); + + } catch (WindSqlException $windSqlException) { + $this->sendErrorMessage($windSqlException->getMessage()); + + } catch (WindViewException $windViewException) { + + } + } + + /* (non-PHPdoc) + * @see IWindApplication::doDispatch() + */ + public function doDispatch($forward) { + //add log + if (IS_DEBUG) { + /* @var $logger WindLogger */ + $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); + $logger->info('do doDispatch of ' . get_class($this)); + } + + $this->dispatcher->dispatch($forward); + } + + /** + * 获得Action处理句柄 + * + * @param WindHttpRequest $request + */ + protected function getHandler() { + $handlerAdapter = $this->getHandlerAdapter(); + $handlerAdapter->doParse(); + + //add log + if (IS_DEBUG) { + /* @var $logger WindLogger */ + $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); + $logger->debug('router result: Action:' . $handlerAdapter->getAction() . ' Controller:' . $handlerAdapter->getController() . ' Module:' . $handlerAdapter->getModule()); + } + + if (!strcasecmp($handlerAdapter->getController(), WIND_M_ERROR)) { + $moduleConfig = $this->windSystemConfig->getModules($this->getModule()); + $handler = $this->windSystemConfig->getConfig(self::ERROR_HANDLER, WIND_CONFIG_CLASS, $moduleConfig, $this->errorHandle); + } else + $handler = $handlerAdapter->getHandler(); + + $definition = new WindComponentDefinition(); + $definition->setPath($handler); + $definition->setScope(WindComponentDefinition::SCOPE_PROTOTYPE); + $definition->setProxy('true'); + $definition->setAlias($handler); + $definition->setPropertys(array('errorMessage' => array('ref' => COMPONENT_ERRORMESSAGE), + 'forward' => array('ref' => COMPONENT_FORWARD), 'urlHelper' => array('ref' => COMPONENT_URLHELPER))); + + $this->windFactory->addClassDefinitions($definition); + $actionHandler = $this->windFactory->getInstance($handler); + $actionHandler->beforeAction($handlerAdapter); + + //TODO 添加过滤链 + if ($actionHandler->_getInstance() instanceof WindFormController) { + if ($formClassPath = $actionHandler->getFormClass()) { + Wind::import('WIND:core.web.listener.WindFormListener'); + $actionHandler->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $actionHandler->getErrorMessage())); + } + } elseif ($actionHandler->_getInstance() instanceof WindController) { + if ($rules = (array) $actionHandler->validatorFormRule($handlerAdapter->getAction())) { + if (!isset($rules['errorMessage'])) { + $rules['errorMessage'] = $actionHandler->getErrorMessage(); + } + Wind::import('WIND:core.web.listener.WindValidateListener'); + $actionHandler->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $actionHandler->getValidatorClass())); + } + } + + //add log + if (IS_DEBUG) { + /* @var $logger WindLogger */ + $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); + $logger->debug('ActionHandler: ' . $handler); + } + + return $actionHandler; + } + + /** + * 错误请求 + * @param WindActionException actionException + */ + protected function sendErrorMessage($actionException) { + $forward = $this->windFactory->getInstance(COMPONENT_FORWARD); + $_tmp = $actionException->getError(); + if (is_string($_tmp)) { + Wind::import('WIND:core.web.WindErrorMessage'); + $_tmp = new WindErrorMessage($_tmp); + } + $forward->forwardAnotherAction($_tmp->getErrorAction(), $_tmp->getErrorController()); + $this->request->setAttribute('error', $_tmp->getError()); + $this->doDispatch($forward); + } + + /** + * @param request + * @return AbstractWindRouter + */ + protected function getHandlerAdapter() { + $routerAlias = $this->windSystemConfig->getRouter(WIND_CONFIG_CLASS); + if (null === $this->getAttribute($routerAlias)) { + /* @var $router AbstractWindRouter */ + $router = $this->windFactory->getInstance($routerAlias); + if (!$router instanceof AbstractWindRouter) { + throw new WindException(get_class($this) . '::getHandlerAdapter()', WindException::ERROR_RETURN_TYPE_ERROR); + } + } + return $this->getAttribute($routerAlias); + } + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @param string $message + */ + protected function noActionHandlerFound($message) { + $this->response->sendError(WindHttpResponse::SC_NOT_FOUND, $message); + } + + /* (non-PHPdoc) + * @see WindModule::getWriteTableForGetterAndSetter() + */ + public function getWriteTableForGetterAndSetter() { + return array('dispatcher'); + } + +} \ No newline at end of file diff --git a/wind/core/web/filter/WindLoggerFilter.php b/wind/core/web/filter/WindLoggerFilter.php new file mode 100644 index 00000000..0ed016d7 --- /dev/null +++ b/wind/core/web/filter/WindLoggerFilter.php @@ -0,0 +1,42 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindLoggerFilter extends WindFilter { + + /* (non-PHPdoc) + * @see WindFilter::preHandle() + */ + public function preHandle($request = null, $response = null) { + if (!IS_DEBUG) return; + $this->initWindLogger($request); + $this->logger->info('-------------------------------request start!!!!--------------------------------'); + } + + /* (non-PHPdoc) + * @see WindFilter::postHandle() + */ + public function postHandle($request = null, $response = null) { + if (!IS_DEBUG) return; + $this->logger->info('---------------------------------request end!!!!---------------------------------'); + if ($this->logger instanceof WindLogger) $this->logger->flush(); + } + + /** + * @param WindHttpRequest $request + */ + private function initWindLogger($request) { + $windFactory = $request->getAttribute(WindFrontController::WIND_FACTORY); + $this->logger = $windFactory->getInstance(COMPONENT_LOGGER); + } + +} + +?> \ No newline at end of file diff --git a/wind/core/web/filter/WindUrlFilter.php b/wind/core/web/filter/WindUrlFilter.php new file mode 100644 index 00000000..d8a44710 --- /dev/null +++ b/wind/core/web/filter/WindUrlFilter.php @@ -0,0 +1,33 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindUrlFilter extends WindFilter { + + /* (non-PHPdoc) + * @see WindFilter::preHandle() + */ + public function preHandle($request = null, $response = null) { + $windFactory = $request->getAttribute(WindFrontController::WIND_FACTORY); + $this->urlHelper = $windFactory->getInstance(COMPONENT_URLHELPER); + $this->urlHelper->parseUrl(); + } + + /* (non-PHPdoc) + * @see WindFilter::postHandle() + */ + public function postHandle($request = null, $response = null) { + + } + +} + +?> \ No newline at end of file diff --git a/wind/core/web/listener/WindFormListener.php b/wind/core/web/listener/WindFormListener.php new file mode 100644 index 00000000..e983ae53 --- /dev/null +++ b/wind/core/web/listener/WindFormListener.php @@ -0,0 +1,73 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFormListener extends WindHandlerInterceptor { + + /** + * @var WindHttpRequest + */ + private $request = null; + + private $formPath = ''; + + private $errorMessage = null; + + /** + * @param WindHttpRequest $request + * @param string $formPath + */ + public function __construct($request, $formPath, $errorMessage) { + $this->request = $request; + $this->formPath = $formPath; + $this->errorMessage = $errorMessage; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + $className = Wind::import($this->formPath); + if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); + if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException('the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); + $form = new $className(); + $methods = get_class_methods($form); + foreach ($methods as $method) { + if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; + $_tmp[0] = strtolower($_tmp[0]); + $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet($_tmp); + if (null === $value) continue; + call_user_func_array(array($form, $method), array($value)); + } + call_user_func_array(array($form, 'validate'), array($form)); + if (($error = $form->getErrors())) { + list($errorController, $errorAction) = $form->getErrorControllerAndAction(); + $this->sendError($errorController, $errorAction, $error); + } + $this->request->setAttribute('formData', $form); + } + + private function sendError($errorController, $errorAction, $errors) { + if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); + $this->errorMessage->setErrorController($errorController); + $this->errorMessage->setErrorAction($errorAction); + $this->errorMessage->addError($errors); + $this->errorMessage->sendError(); + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + + } + +} + +?> \ No newline at end of file diff --git a/wind/core/web/listener/WindLoggerListener.php b/wind/core/web/listener/WindLoggerListener.php new file mode 100644 index 00000000..ef285b14 --- /dev/null +++ b/wind/core/web/listener/WindLoggerListener.php @@ -0,0 +1,119 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindLoggerListener extends WindHandlerInterceptor { + + /** + * Enter description here ... + * @param WindHttpRequest $request + */ + public function __construct($request) { + $this->request = $request; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + $logger = $this->getLogger(); + if ($logger instanceof WindLogger) { + $logger->info($this->getPreLogMessage(func_get_args())); + } + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + $logger = $this->getLogger(); + if ($logger instanceof WindLogger) { + $logger->info($this->getPostLogMessage(func_get_args())); + } + } + + /** + * @return WindLogger + */ + private function getLogger() { + if (!isset($this->logger)) { + $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); + $this->logger = $factory->getInstance(COMPONENT_LOGGER); + } + return $this->logger; + } + + private function getPreLogMessage($args) { + $log = $this->getLogMessage($args); + $log['caller'] = ' #[caller]: ' . $log['caller']; + $log['excute'] = ' #[excute-begin]: ' . $log['excute']; + $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; + return "{$message}
" . implode("\r\n", $log) . '
'; + } + + private function getPostLogMessage($args) { + $log = $this->getLogMessage($args); + $log['caller'] = ' #[caller]: ' . $log['caller']; + $log['excute'] = ' #[excute-end]: ' . $log['excute']; + $log['output'] = ' #[output]: ' . $this->buildArg($this->result); + $message = 'End ' . $this->event[0] . '->' . $this->event[1]; + return "{$message}
" . implode("\r\n", $log) . '
'; + } + + /** + * 获得调用的堆栈信息中回调的方法信息 + * + * @param array $args + * @return string + */ + private function getLogMessage($args) { + $method = ''; + $info = array(); + $flag = false; + foreach (debug_backtrace(false) as $traceKey => $trace) { + $class = isset($trace['class']) ? $trace['class'] : ''; + if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; + $function = isset($trace['function']) ? $trace['function'] : ''; + ($class == 'WindClassProxy' && $function == '__call') && $method = trim($trace['args'][0]); + ($function == $method) && $flag = true; + if (!isset($trace['file'])) continue; + $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; + break; + } + list($class, $method) = $this->event; + $args = array_map(array($this, 'buildArg'), $args); + $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; + return $info; + } + + /** + * 将参数进行类型判断返回类型 + * 如果类型是字符串,则直接返回该字符串 + * + * @param mixed $arg + * @return string + */ + private function buildArg($arg) { + switch (gettype($arg)) { + case 'array': + return 'Array'; + break; + case 'object': + return 'Object ' . get_class($arg); + break; + default: + return "'" . $arg . "'"; + break; + } + } +} + +?> \ No newline at end of file diff --git a/wind/core/web/listener/WindValidateListener.php b/wind/core/web/listener/WindValidateListener.php new file mode 100644 index 00000000..ae4dc730 --- /dev/null +++ b/wind/core/web/listener/WindValidateListener.php @@ -0,0 +1,93 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindValidateListener extends WindHandlerInterceptor { + + /** + * @var WindHttpRequest + */ + private $request = null; + + private $validateRules = array(); + + private $validator = null; + + private $validatorClass = ''; + + private $defaultMessage = '验证失败'; + + /** + * @param WindHttpRequest $request + * @param array $validateRules + * @param string $validatorClass + */ + public function __construct($request, $validateRules, $validatorClass) { + $this->request = $request; + $this->validateRules = (array) $validateRules; + $this->validatorClass = $validatorClass; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + if (!isset($this->validateRules['errorMessage'])) + $errorMessage = new WindErrorMessage(); + else { + $errorMessage = $this->validateRules['errorMessage']; + unset($this->validateRules['errorMessage']); + } + $_input = new stdClass(); + foreach ((array) $this->validateRules as $rule) { + if (!is_array($rule)) continue; + $key = $rule['field']; + $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost($key); + $args = $rule['args']; + array_unshift($args, $value); + if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { + if (null === $rule['default']) + $errorMessage->addError(($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); + else + $value = $rule['default']; + } + $this->request->setAttribute($key, $value); + $_input->$key = $value; + } + if ($errorMessage->getError()) + $errorMessage->sendError(); + else + $this->request->setAttribute('inputData', $_input); + } + + /** + * 返回validator对象 + * @throws WindException + * @return WindValidator + */ + private function getValidator() { + if ($this->validator === null) { + $_className = Wind::import($this->validatorClass); + Wind::import('WIND:core.factory.WindFactory'); + $this->validator = WindFactory::createInstance($_className); + if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); + } + return $this->validator; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + + } + +} + +?> \ No newline at end of file diff --git a/wind/readme b/wind/readme new file mode 100644 index 00000000..3d9fbe42 --- /dev/null +++ b/wind/readme @@ -0,0 +1,8 @@ +版本说明: +wind_0.3.0.v1882_20110315_b #默认配置为 php +wind_0.3.0.v1882_20110315 #默认配置为xml +wind_0.1.0.v849_20101227 + +Feature list: + +Fixed bug list: From 9f5f9949ef10636ab4c948ccb08380baf252e528 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 06:29:57 +0000 Subject: [PATCH 0002/1065] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E4=B8=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2037 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 42c1e939..55c97e87 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -21,7 +21,7 @@ class WindConnection extends WindComponentModule { private $_user; private $_pwd; private $_tablePrefix; - private $_charset = 'gbk'; + private $_charset; private $_enableLog = false; /** * @var array From e871a75e9f559390dc35b59d3f1f784ef7a3e463 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 06:39:14 +0000 Subject: [PATCH 0003/1065] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E4=B8=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2038 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindFrontController.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 84832c2f..51347811 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -5,7 +5,6 @@ * @copyright Copyright © 2003-2010 phpwind.com * @license */ - Wind::import('WIND:core.AbstractWindServer'); /** * 抽象的前端控制器接口,通过集成该接口可以实现以下职责 @@ -21,20 +20,14 @@ * @package */ class WindFrontController extends AbstractWindServer { - const WIND_CONFIG = 'WIND:core.config.WindSystemConfig'; - const WIND_FACTORY = 'WIND:core.factory.WindComponentFactory'; - const COMPONENTS_CONFIG = 'WIND:config.components_config.php'; - /** * @var WindSystemConfig */ protected $windSystemConfig = null; - protected $windFactory = null; - protected $windErrorHandler = null; /** @@ -61,8 +54,6 @@ protected function initWindFactory() { } /** - * Enter description here ... - * * @param string $appName * @param string $config */ @@ -72,8 +63,7 @@ protected function initWindConfig($appName, $config) { $configParser = new WindConfigParser(); $this->windSystemConfig = new WindSystemConfig($config, $configParser, ($appName ? $appName : 'default')); Wind::register($this->getWindConfig()->getRootPath(), $this->getWindConfig()->getAppName()); - - //TODO register all apps + //TODO register all apps } /* (non-PHPdoc) @@ -84,20 +74,17 @@ protected function process(WindHttpRequest $request, WindHttpResponse $response) $this->getWindFactory()->response = $response; $request->setAttribute(self::WIND_CONFIG, $this->windSystemConfig); $request->setAttribute(self::WIND_FACTORY, $this->windFactory); - $appName = $this->getWindConfig()->getAppClass(); $application = $this->getWindFactory()->getInstance($appName); if (null === $application) { throw new WindException('application', WindException::ERROR_CLASS_NOT_EXIST); } - $this->getWindFactory()->application = $application; if (null !== $filterChain = $this->getFilterChain()) { $filterChain->setCallBack(array($application, 'processRequest'), array()); $filterChain->getHandler()->handle($request, $response); } else $application->processRequest(); - } /** @@ -168,5 +155,4 @@ public function getWindFactory() { else throw new WindException(get_class($this) . '->windFactory', WindException::ERROR_CLASS_TYPE_ERROR); } - } \ No newline at end of file From f1c3d018a84a3666ed2ccf1c3c550981df6e31ba Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 06:42:04 +0000 Subject: [PATCH 0004/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2039 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/config/components_config.php | 26 ---------- wind/config/components_config.xml | 82 ------------------------------- 2 files changed, 108 deletions(-) delete mode 100644 wind/config/components_config.php delete mode 100644 wind/config/components_config.xml diff --git a/wind/config/components_config.php b/wind/config/components_config.php deleted file mode 100644 index d6fe2660..00000000 --- a/wind/config/components_config.php +++ /dev/null @@ -1,26 +0,0 @@ - array('path' => 'WIND:core.web.WindWebApplication', 'scope' => 'request', - 'properties' => array('dispatcher' => array('ref' => 'dispatcher'))), - 'dispatcher' => array('path' => 'WIND:core.web.WindDispatcher', 'scope' => 'prototype'), - 'windLogger' => array('path' => 'WIND:component.log.WindLogger', 'scope' => 'request'), - 'forward' => array('path' => 'WIND:core.web.WindForward', 'scope' => 'prototype'), - 'urlBasedRouter' => array('path' => 'WIND:core.router.WindUrlBasedRouter', 'scope' => 'application', - 'config' => array('module' => array('url-param' => 'm', 'default-value' => 'default'), - 'controller' => array('url-param' => 'c', 'default-value' => 'index'), - 'action' => array('url-param' => 'a', 'default-value' => 'run'))), - 'urlHelper' => array('path' => 'WIND:core.web.WindUrlHelper', 'scope' => 'singleton', - 'properties' => array('windRouter' => array('ref' => 'urlBasedRouter')), - 'config' => array('url-pattern' => array('value' => '-/'), 'route-suffix' => array('value' => 'htm'), - 'route-param' => array('value' => 'r'))), - 'windView' => array('path' => 'WIND:core.viewer.WindView', 'scope' => 'prototype', - 'config' => array('template-dir' => array('value' => 'template'), 'template-ext' => array('value' => 'htm'), - 'is-cache' => array('value' => 'true'), 'cache-dir' => array('value' => 'cache'), - 'compile-dir' => array('value' => 'compile.template')), - 'properties' => array('viewResolver' => array('ref' => 'viewResolver'))), - 'viewResolver' => array('path' => 'WIND:core.viewer.WindViewerResolver', 'scope' => 'prototype', - 'properties' => array('urlHelper' => array('ref' => 'urlHelper'))), - 'template' => array('path' => 'WIND:core.viewer.compiler.WindViewTemplate', 'scope' => 'prototype', - 'config' => array('resource' => '')), - 'errorMessage' => array('path' => 'WIND:core.web.WindErrorMessage', 'scope' => 'prototype')); -?> \ No newline at end of file diff --git a/wind/config/components_config.xml b/wind/config/components_config.xml deleted file mode 100644 index 11dfa2f1..00000000 --- a/wind/config/components_config.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From c3768b7183d66c145e58352d7e3b49f04651191e Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 06:42:36 +0000 Subject: [PATCH 0005/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2040 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/WindBase.php | 430 ---------------------------------------------- 1 file changed, 430 deletions(-) delete mode 100644 wind/WindBase.php diff --git a/wind/WindBase.php b/wind/WindBase.php deleted file mode 100644 index d7abccea..00000000 --- a/wind/WindBase.php +++ /dev/null @@ -1,430 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindBase { - private static $_namespace = array(); - private static $_imports = array(); - private static $_classes = array(); - private static $_instances = array(); - private static $_extensions = 'php'; - private static $_includePaths = array(); - private static $_isAutoLoad = true; - private static $_logger = null; - - /** - * 加载应用 - * @param string $appName - * @param string $config - * @throws WindException - * @return - */ - public static function run($appName = '', $config = '') { - $frontController = new WindFrontController($appName, $config); - $frontController->run(); - } - - /** - * 加载一个类或者加载一个包 - * 如果加载的包中有子文件夹不进行循环加载 - * 参数格式说明:'WIND:core.base.WFrontController' - * WIND 注册的应用名称,应用名称与路径信息用‘:’号分隔 - * core.base.WFrontController 相对的路径信息 - * 如果不填写应用名称 ,例如‘core.base.WFrontController’,那么加载路径则相对于默认的应用路径 - * - * 加载一个类的参数方式:'WIND:core.base.WFrontController' - * 加载一个包的参数方式:'WIND:core.base.*' - * - * @param string $filePath | 文件路径信息 或者className - * @param boolean $autoIncludes | 是否采用自动加载方式 - * @param boolean $recursivePackage | 当需要加载的路径为文件夹时是否递归它 - * @return string|null - */ - public static function import($filePath, $recursivePackage = false) { - if (!$filePath) return false; - if ($className = self::_isImported($filePath)) return $className; - if (($pos = strrpos($filePath, '.')) !== false) - $fileName = substr($filePath, $pos + 1); - elseif (($pos1 = strrpos($filePath, ':')) !== false) - $fileName = substr($filePath, $pos1 + 1); - else - $fileName = $filePath; - $isPackage = $fileName === '*'; - if ($isPackage) { - $filePath = substr($filePath, 0, $pos); - $dirPath = self::getRealPath($filePath, true); - if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); - while (($file = readdir($dh)) !== false) { - if (is_dir($dirPath . D_S . $file)) { - if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { - $_filePath = $filePath . '.' . $file . '.' . '*'; - self::import($_filePath, $recursivePackage); - } - } else { - if (($pos = strrpos($file, '.')) === false) { - $fileName = $file; - } else { - if (substr($file, $pos + 1) === self::$_extensions) { - $fileName = substr($file, 0, $pos); - } - } - self::_setImport($fileName, $filePath . '.' . $fileName); - } - } - closedir($dh); - } else { - self::_setImport($fileName, $filePath); - } - return $fileName; - } - - /** - * 将路径信息注册到命名空间,该方法不会覆盖已经定义过的命名空间 - * @param string $path | 需要注册的路径 - * @param string $name | 路径别名 - * @param boolean $includePath | 是否同时定义includePath - * @param boolean $reset | 是否覆盖已经存在的定义,默认false - * @return - */ - public static function register($path, $alias = '', $includePath = false, $reset = false) { - if (!$path) return; - $alias = strtolower(trim($alias)); - if (!empty($alias)) { - if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = $path; - } - if ($includePath) { - if (empty(self::$_includePaths)) { - self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); - if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset(self::$_includePaths[$pos]); - } - array_unshift(self::$_includePaths, $path); - if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { - throw new Exception('set include path error.'); - } - } - } - - /** - * 类文件自动加载方法 callback - * @param string $className - * @param string $path - * @return null - */ - public static function autoLoad($className, $path = '') { - if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; - if ($path === '') { - throw new Exception('auto load ' . $className . ' failed.'); - } - $path = self::getRealPath($path . '.' . self::$_extensions); - if ((include $path) === false) { - throw new Exception('include file ' . $path . ' failed.'); - } - } - - /** - * @param string $key - * @return string|array - */ - public static function getImports($key = '') { - return $key ? self::$_imports[$key] : self::$_imports; - } - - /** - * 返回命名空间的路径信息 - * @param string $namespace - * @return string|Ambigous - */ - public static function getRootPath($namespace = '') { - if (!$namespace) return ''; - $namespace = strtolower($namespace); - return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; - } - - /** - * 解析路径信息,并返回路径的详情 - * @param string $filePath 路径信息 - * @param boolean $info 是否为目录路径 - * @return string|array('isPackage','fileName','extension','realPath') - */ - public static function getRealPath($filePath, $isDir = false) { - $filePath = trim($filePath, ' '); - $namespace = $suffix = ''; - if (!$isDir) { - $_pos1 = strrpos($filePath, '.'); - $suffix = trim(substr($filePath, $_pos1 + 1), '.'); - $filePath = substr($filePath, 0, $_pos1); - } - if (($pos = strpos($filePath, ':')) !== false) { - $namespace = self::getRootPath(substr($filePath, 0, $pos)); - } - $filePath = str_replace('.', D_S, $filePath); - if ($namespace) $filePath = rtrim($namespace, D_S) . D_S . substr($filePath, $pos + 1); - return $suffix ? $filePath . '.' . $suffix : $filePath; - } - - /** - * 将核心库文件打包 - * @throws Exception - * @return - */ - public static function perLoadCoreLibrary($libPath) { - self::import('COM:utility.WindPack'); - $pack = new WindPack(); - $fileList = array(); - foreach (self::$_imports as $key => $value) { - $_key = self::getRealPath($key . '.' . self::$_extensions); - $fileList[$_key] = array( - $key, - $value); - } - $pack->packFromFileList($fileList, $libPath, WindPack::STRIP_PHP, true); - } - - /** - * 初始化框架 - */ - public static function init() { - self::_checkEnvironment(); - self::_setDefaultSystemNamespace(); - self::_registerAutoloader(); - self::_loadBaseLib(); - } - - /** - * @param string $message - * @param int $level - */ - public static function log($message, $level = WindLogger::LEVEL_INFO, $type = 'wind.core') { - if (IS_DEBUG && $level >= IS_DEBUG && $level != WindLogger::LEVEL_PROFILE) { - self::getLogger()->log($message, $level, $type); - } - } - - /** - * @param $token - * @param $message - * @param $type - */ - public static function profileBegin($token, $message = '', $type = 'wind.core') { - if (IS_DEBUG && IS_DEBUG >= WindLogger::LEVEL_PROFILE) { - $msg = $token . ':' . $message; - self::getLogger()->profileBegin($msg, $type); - } - } - - /** - * @param $token - * @param $message - * @param $type - */ - public static function profileEnd($token, $message = '', $type = 'wend.core') { - if (IS_DEBUG && IS_DEBUG >= WindLogger::LEVEL_PROFILE) { - $msg = $token . ':' . $message; - self::getLogger()->profileEnd($msg, $type); - } - } - - /** - * 返回系统日志对象 - * @return WindLogger - */ - public static function getLogger() { - if (self::$_logger === null) { - self::$_logger = new WindLogger(); - self::$_logger->setLogFile(COMPILE_PATH . 'log/log.txt'); - } - return self::$_logger; - } - - /** - * 系统命名空间注册方法 - * @return - */ - private static function _setDefaultSystemNamespace() { - self::register(WIND_PATH, 'WIND'); - self::register(WIND_PATH . 'component' . D_S, 'COM'); - } - - /** - * 检查框架运行环境 - * @return - */ - private static function _checkEnvironment() { - if (!self::_checkPhpVersion()) throw new Exception('php version is too old, php ' . PHPVERSION . ' or later.', E_WARNING); - if (!defined('COMPILE_PATH')) throw new Exception('compile path undefined.'); - function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); - } - - /** - * @param string $className - * @param string $classPath - * @return - */ - private static function _setImport($className, $classPath) { - if (self::_isImported($className)) return; - self::$_imports[$classPath] = $className; - if (self::$_isAutoLoad) - self::$_classes[$className] = $classPath; - else - self::autoLoad($className, $classPath); - } - - /** - * 判断是否类是否已经被加载,如果已经被加载则返回路径信息,如果没有被加载则返回false - * @param string $path - * @return boolean|string - */ - private static function _isImported($param) { - if (isset(self::$_imports[$param])) return self::$_imports[$param]; - if (in_array($param, self::$_imports)) return $param; - return false; - } - - /** - * 注册自动加载回调方法 - * @return - */ - private static function _registerAutoloader() { - if (!self::$_isAutoLoad) return; - if (function_exists('spl_autoload_register')) - spl_autoload_register('Wind::autoLoad'); - else - self::$_isAutoLoad = false; - } - - /** - * 加载核心层库函数 - * @return - */ - private static function _loadBaseLib() { - $_core = self::_coreLib(); - foreach ($_core as $key => $value) { - self::_setImport($key, $value); - } - } - - /* private utility */ - private static function _checkPhpVersion() { - $v1 = $v2 = $v3 = $m1 = $m2 = $m3 = 0; - $phpversion = phpversion(); - sscanf($phpversion, "%d.%d.%d", $v1, $v2, $v3); - sscanf(PHPVERSION, "%d.%d.%d", $m1, $m2, $m3); - if ($v1 > $m1) return true; - if ($v1 < $m1) return false; - if ($v2 > $m2) return true; - if ($v2 < $m2) return false; - if ($v3 > $m3) return true; - if ($v3 < $m3) return false; - return true; - } - - /** - * 核心库文件 - * @return - */ - private static function _coreLib() { - return array( - 'AbstractWindServer' => 'WIND:core.AbstractWindServer', - 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', - 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', - 'WindConfig' => 'WIND:core.config.WindConfig', - 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', - 'WindDaoCacheListener' => 'WIND:core.dao.listener.WindDaoCacheListener', - 'WindActionException' => 'WIND:core.exception.WindActionException', - 'WindCacheException' => 'WIND:core.exception.WindCacheException', - 'WindDaoException' => 'WIND:core.exception.WindDaoException', - 'WindException' => 'WIND:core.exception.WindException', - 'WindFinalException' => 'WIND:core.exception.WindFinalException', - 'WindSqlException' => 'WIND:core.exception.WindSqlException', - 'WindViewException' => 'WIND:core.exception.WindViewException', - 'IWindFactory' => 'WIND:core.factory.IWindFactory', - 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', - 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', - 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', - 'WindComponentDefinition' => 'WIND:core.factory.WindComponentDefinition', - 'WindComponentFactory' => 'WIND:core.factory.WindComponentFactory', - 'WindFactory' => 'WIND:core.factory.WindFactory', - 'WindFilter' => 'WIND:core.filter.WindFilter', - 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', - 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', - 'IWindRequest' => 'WIND:core.request.IWindRequest', - 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', - 'IWindResponse' => 'WIND:core.response.IWindResponse', - 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', - 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', - 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', - 'AbstractWindTemplateCompiler' => 'WIND:core.viewer.AbstractWindTemplateCompiler', - 'AbstractWindViewTemplate' => 'WIND:core.viewer.AbstractWindViewTemplate', - 'WindTemplateCompilerAction' => 'WIND:core.viewer.compiler.WindTemplateCompilerAction', - 'WindTemplateCompilerComponent' => 'WIND:core.viewer.compiler.WindTemplateCompilerComponent', - 'WindTemplateCompilerEcho' => 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', - 'WindTemplateCompilerInternal' => 'WIND:core.viewer.compiler.WindTemplateCompilerInternal', - 'WindTemplateCompilerPage' => 'WIND:core.viewer.compiler.WindTemplateCompilerPage', - 'WindTemplateCompilerScript' => 'WIND:core.viewer.compiler.WindTemplateCompilerScript', - 'WindTemplateCompilerTemplate' => 'WIND:core.viewer.compiler.WindTemplateCompilerTemplate', - 'WindViewTemplate' => 'WIND:core.viewer.compiler.WindViewTemplate', - 'IWindViewerResolver' => 'WIND:core.viewer.IWindViewerResolver', - 'WindViewCacheListener' => 'WIND:core.viewer.listener.WindViewCacheListener', - 'WindLayout' => 'WIND:core.viewer.WindLayout', - 'WindView' => 'WIND:core.viewer.WindView', - 'WindViewerResolver' => 'WIND:core.viewer.WindViewerResolver', - 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', - 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', - 'IWindApplication' => 'WIND:core.web.IWindApplication', - 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', - 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', - 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', - 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', - 'WindAction' => 'WIND:core.web.WindAction', - 'WindController' => 'WIND:core.web.WindController', - 'WindDispatcher' => 'WIND:core.web.WindDispatcher', - 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', - 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', - 'WindFormController' => 'WIND:core.web.WindFormController', - 'WindForward' => 'WIND:core.web.WindForward', - 'WindFrontController' => 'WIND:core.web.WindFrontController', - 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', - 'WindWebApplication' => 'WIND:core.web.WindWebApplication', - 'WindComponentModule' => 'WIND:core.WindComponentModule', - 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', - 'WindHelper' => 'WIND:core.WindHelper', - 'WindModule' => 'WIND:core.WindModule', - 'WindLogger' => 'COM:log.WindLogger'); - } -} -/* 组件定义 */ -!defined('COMPONENT_WEBAPP') && define('COMPONENT_WEBAPP', 'windWebApp'); -!defined('COMPONENT_ERRORHANDLER') && define('COMPONENT_ERRORHANDLER', 'errorHandler'); -!defined('COMPONENT_LOGGER') && define('COMPONENT_LOGGER', 'windLogger'); -!defined('COMPONENT_FORWARD') && define('COMPONENT_FORWARD', 'forward'); -!defined('COMPONENT_ROUTER') && define('COMPONENT_ROUTER', 'urlBasedRouter'); -!defined('COMPONENT_URLHELPER') && define('COMPONENT_URLHELPER', 'urlHelper'); -!defined('COMPONENT_VIEW') && define('COMPONENT_VIEW', 'windView'); -!defined('COMPONENT_VIEWRESOLVER') && define('COMPONENT_VIEWRESOLVER', 'viewResolver'); -!defined('COMPONENT_TEMPLATE') && define('COMPONENT_TEMPLATE', 'template'); -!defined('COMPONENT_ERRORMESSAGE') && define('COMPONENT_ERRORMESSAGE', 'errorMessage'); -!defined('COMPONENT_DB') && define('COMPONENT_DB', 'db'); -//TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 -//********************约定变量*********************************** -define('WIND_M_ERROR', 'windError'); -define('WIND_CONFIG_CACHE', 'wind_components_config'); -//**********配置*******通用常量定义*************************************** -define('WIND_CONFIG_CONFIG', 'config'); -define('WIND_CONFIG_CLASS', 'class'); -define('WIND_CONFIG_CLASSPATH', 'path'); -define('WIND_CONFIG_RESOURCE', 'resource'); -define('WIND_CONFIG_VALUE', 'value'); \ No newline at end of file From f01a972a7f4741f759ce5d95095b3e8774cb4e28 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 06:42:56 +0000 Subject: [PATCH 0006/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2041 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 26 ++++++++++++ wind/components_config.xml | 82 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 wind/components_config.php create mode 100644 wind/components_config.xml diff --git a/wind/components_config.php b/wind/components_config.php new file mode 100644 index 00000000..d6fe2660 --- /dev/null +++ b/wind/components_config.php @@ -0,0 +1,26 @@ + array('path' => 'WIND:core.web.WindWebApplication', 'scope' => 'request', + 'properties' => array('dispatcher' => array('ref' => 'dispatcher'))), + 'dispatcher' => array('path' => 'WIND:core.web.WindDispatcher', 'scope' => 'prototype'), + 'windLogger' => array('path' => 'WIND:component.log.WindLogger', 'scope' => 'request'), + 'forward' => array('path' => 'WIND:core.web.WindForward', 'scope' => 'prototype'), + 'urlBasedRouter' => array('path' => 'WIND:core.router.WindUrlBasedRouter', 'scope' => 'application', + 'config' => array('module' => array('url-param' => 'm', 'default-value' => 'default'), + 'controller' => array('url-param' => 'c', 'default-value' => 'index'), + 'action' => array('url-param' => 'a', 'default-value' => 'run'))), + 'urlHelper' => array('path' => 'WIND:core.web.WindUrlHelper', 'scope' => 'singleton', + 'properties' => array('windRouter' => array('ref' => 'urlBasedRouter')), + 'config' => array('url-pattern' => array('value' => '-/'), 'route-suffix' => array('value' => 'htm'), + 'route-param' => array('value' => 'r'))), + 'windView' => array('path' => 'WIND:core.viewer.WindView', 'scope' => 'prototype', + 'config' => array('template-dir' => array('value' => 'template'), 'template-ext' => array('value' => 'htm'), + 'is-cache' => array('value' => 'true'), 'cache-dir' => array('value' => 'cache'), + 'compile-dir' => array('value' => 'compile.template')), + 'properties' => array('viewResolver' => array('ref' => 'viewResolver'))), + 'viewResolver' => array('path' => 'WIND:core.viewer.WindViewerResolver', 'scope' => 'prototype', + 'properties' => array('urlHelper' => array('ref' => 'urlHelper'))), + 'template' => array('path' => 'WIND:core.viewer.compiler.WindViewTemplate', 'scope' => 'prototype', + 'config' => array('resource' => '')), + 'errorMessage' => array('path' => 'WIND:core.web.WindErrorMessage', 'scope' => 'prototype')); +?> \ No newline at end of file diff --git a/wind/components_config.xml b/wind/components_config.xml new file mode 100644 index 00000000..11dfa2f1 --- /dev/null +++ b/wind/components_config.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b1bf5a532123c22aa6984da8f957a2972eaef98b Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 06:47:44 +0000 Subject: [PATCH 0007/1065] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E4=B8=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2042 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 wind/Wind.php diff --git a/wind/Wind.php b/wind/Wind.php deleted file mode 100644 index 2cd52df5..00000000 --- a/wind/Wind.php +++ /dev/null @@ -1,10 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @copyright Copyright © 2003-2015 phpwind.com - */ -class Wind extends WindBase {} -Wind::init(); From b25a9247e4014719d34a856d336001c319fcb9b2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 06:47:53 +0000 Subject: [PATCH 0008/1065] =?UTF-8?q?=E6=A1=86=E6=9E=B6=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E4=B8=BB=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2043 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 431 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 wind/Wind.php diff --git a/wind/Wind.php b/wind/Wind.php new file mode 100644 index 00000000..4277d4e1 --- /dev/null +++ b/wind/Wind.php @@ -0,0 +1,431 @@ + + * @author Qiong Wu + * @version $Id: WindBase.php 2017 2011-06-22 03:51:39Z yishuo $ + * @package + */ +class Wind { + private static $_namespace = array(); + private static $_imports = array(); + private static $_classes = array(); + private static $_instances = array(); + private static $_extensions = 'php'; + private static $_includePaths = array(); + private static $_isAutoLoad = true; + private static $_logger = null; + + /** + * 加载应用 + * @param string $appName + * @param string $config + * @throws WindException + * @return + */ + public static function run($appName = '', $config = '') { + $frontController = new WindFrontController($appName, $config); + $frontController->run(); + } + + /** + * 加载一个类或者加载一个包 + * 如果加载的包中有子文件夹不进行循环加载 + * 参数格式说明:'WIND:core.base.WFrontController' + * WIND 注册的应用名称,应用名称与路径信息用‘:’号分隔 + * core.base.WFrontController 相对的路径信息 + * 如果不填写应用名称 ,例如‘core.base.WFrontController’,那么加载路径则相对于默认的应用路径 + * + * 加载一个类的参数方式:'WIND:core.base.WFrontController' + * 加载一个包的参数方式:'WIND:core.base.*' + * + * @param string $filePath | 文件路径信息 或者className + * @param boolean $autoIncludes | 是否采用自动加载方式 + * @param boolean $recursivePackage | 当需要加载的路径为文件夹时是否递归它 + * @return string|null + */ + public static function import($filePath, $recursivePackage = false) { + if (!$filePath) return false; + if ($className = self::_isImported($filePath)) return $className; + if (($pos = strrpos($filePath, '.')) !== false) + $fileName = substr($filePath, $pos + 1); + elseif (($pos1 = strrpos($filePath, ':')) !== false) + $fileName = substr($filePath, $pos1 + 1); + else + $fileName = $filePath; + $isPackage = $fileName === '*'; + if ($isPackage) { + $filePath = substr($filePath, 0, $pos); + $dirPath = self::getRealPath($filePath, true); + if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); + while (($file = readdir($dh)) !== false) { + if (is_dir($dirPath . D_S . $file)) { + if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { + $_filePath = $filePath . '.' . $file . '.' . '*'; + self::import($_filePath, $recursivePackage); + } + } else { + if (($pos = strrpos($file, '.')) === false) { + $fileName = $file; + } else { + if (substr($file, $pos + 1) === self::$_extensions) { + $fileName = substr($file, 0, $pos); + } + } + self::_setImport($fileName, $filePath . '.' . $fileName); + } + } + closedir($dh); + } else { + self::_setImport($fileName, $filePath); + } + return $fileName; + } + + /** + * 将路径信息注册到命名空间,该方法不会覆盖已经定义过的命名空间 + * @param string $path | 需要注册的路径 + * @param string $name | 路径别名 + * @param boolean $includePath | 是否同时定义includePath + * @param boolean $reset | 是否覆盖已经存在的定义,默认false + * @return + */ + public static function register($path, $alias = '', $includePath = false, $reset = false) { + if (!$path) return; + $alias = strtolower(trim($alias)); + if (!empty($alias)) { + if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = $path; + } + if ($includePath) { + if (empty(self::$_includePaths)) { + self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); + if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset(self::$_includePaths[$pos]); + } + array_unshift(self::$_includePaths, $path); + if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { + throw new Exception('set include path error.'); + } + } + } + + /** + * 类文件自动加载方法 callback + * @param string $className + * @param string $path + * @return null + */ + public static function autoLoad($className, $path = '') { + if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; + if ($path === '') { + throw new Exception('auto load ' . $className . ' failed.'); + } + $path = self::getRealPath($path . '.' . self::$_extensions); + if ((include $path) === false) { + throw new Exception('include file ' . $path . ' failed.'); + } + } + + /** + * @param string $key + * @return string|array + */ + public static function getImports($key = '') { + return $key ? self::$_imports[$key] : self::$_imports; + } + + /** + * 返回命名空间的路径信息 + * @param string $namespace + * @return string|Ambigous + */ + public static function getRootPath($namespace = '') { + if (!$namespace) return ''; + $namespace = strtolower($namespace); + return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; + } + + /** + * 解析路径信息,并返回路径的详情 + * @param string $filePath 路径信息 + * @param boolean $info 是否为目录路径 + * @return string|array('isPackage','fileName','extension','realPath') + */ + public static function getRealPath($filePath, $isDir = false) { + $filePath = trim($filePath, ' '); + $namespace = $suffix = ''; + if (!$isDir) { + $_pos1 = strrpos($filePath, '.'); + $suffix = trim(substr($filePath, $_pos1 + 1), '.'); + $filePath = substr($filePath, 0, $_pos1); + } + if (($pos = strpos($filePath, ':')) !== false) { + $namespace = self::getRootPath(substr($filePath, 0, $pos)); + } + $filePath = str_replace('.', D_S, $filePath); + if ($namespace) $filePath = rtrim($namespace, D_S) . D_S . substr($filePath, $pos + 1); + return $suffix ? $filePath . '.' . $suffix : $filePath; + } + + /** + * 将核心库文件打包 + * @throws Exception + * @return + */ + public static function perLoadCoreLibrary($libPath) { + self::import('COM:utility.WindPack'); + $pack = new WindPack(); + $fileList = array(); + foreach (self::$_imports as $key => $value) { + $_key = self::getRealPath($key . '.' . self::$_extensions); + $fileList[$_key] = array( + $key, + $value); + } + $pack->packFromFileList($fileList, $libPath, WindPack::STRIP_PHP, true); + } + + /** + * 初始化框架 + */ + final public static function init() { + self::_checkEnvironment(); + self::_setDefaultSystemNamespace(); + self::_registerAutoloader(); + self::_loadBaseLib(); + } + + /** + * @param string $message + * @param int $level + */ + public static function log($message, $level = WindLogger::LEVEL_INFO, $type = 'wind.core') { + if (IS_DEBUG && $level >= IS_DEBUG && $level != WindLogger::LEVEL_PROFILE) { + self::getLogger()->log($message, $level, $type); + } + } + + /** + * @param $token + * @param $message + * @param $type + */ + public static function profileBegin($token, $message = '', $type = 'wind.core') { + if (IS_DEBUG && IS_DEBUG >= WindLogger::LEVEL_PROFILE) { + $msg = $token . ':' . $message; + self::getLogger()->profileBegin($msg, $type); + } + } + + /** + * @param $token + * @param $message + * @param $type + */ + public static function profileEnd($token, $message = '', $type = 'wend.core') { + if (IS_DEBUG && IS_DEBUG >= WindLogger::LEVEL_PROFILE) { + $msg = $token . ':' . $message; + self::getLogger()->profileEnd($msg, $type); + } + } + + /** + * 返回系统日志对象 + * @return WindLogger + */ + public static function getLogger() { + if (self::$_logger === null) { + self::$_logger = new WindLogger(); + self::$_logger->setLogFile(COMPILE_PATH . 'log/log.txt'); + } + return self::$_logger; + } + + /** + * 系统命名空间注册方法 + * @return + */ + private static function _setDefaultSystemNamespace() { + self::register(WIND_PATH, 'WIND'); + self::register(WIND_PATH . 'component' . D_S, 'COM'); + } + + /** + * 检查框架运行环境 + * @return + */ + private static function _checkEnvironment() { + if (!self::_checkPhpVersion()) throw new Exception('php version is too old, php ' . PHPVERSION . ' or later.', E_WARNING); + if (!defined('COMPILE_PATH')) throw new Exception('compile path undefined.'); + function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); + } + + /** + * @param string $className + * @param string $classPath + * @return + */ + private static function _setImport($className, $classPath) { + if (self::_isImported($className)) return; + self::$_imports[$classPath] = $className; + if (self::$_isAutoLoad) + self::$_classes[$className] = $classPath; + else + self::autoLoad($className, $classPath); + } + + /** + * 判断是否类是否已经被加载,如果已经被加载则返回路径信息,如果没有被加载则返回false + * @param string $path + * @return boolean|string + */ + private static function _isImported($param) { + if (isset(self::$_imports[$param])) return self::$_imports[$param]; + if (in_array($param, self::$_imports)) return $param; + return false; + } + + /** + * 注册自动加载回调方法 + * @return + */ + private static function _registerAutoloader() { + if (!self::$_isAutoLoad) return; + if (function_exists('spl_autoload_register')) + spl_autoload_register('Wind::autoLoad'); + else + self::$_isAutoLoad = false; + } + + /** + * 加载核心层库函数 + * @return + */ + private static function _loadBaseLib() { + $_core = self::_coreLib(); + foreach ($_core as $key => $value) { + self::_setImport($key, $value); + } + } + + /* private utility */ + private static function _checkPhpVersion() { + $v1 = $v2 = $v3 = $m1 = $m2 = $m3 = 0; + $phpversion = phpversion(); + sscanf($phpversion, "%d.%d.%d", $v1, $v2, $v3); + sscanf(PHPVERSION, "%d.%d.%d", $m1, $m2, $m3); + if ($v1 > $m1) return true; + if ($v1 < $m1) return false; + if ($v2 > $m2) return true; + if ($v2 < $m2) return false; + if ($v3 > $m3) return true; + if ($v3 < $m3) return false; + return true; + } + + /** + * 核心库文件 + * @return + */ + private static function _coreLib() { + return array( + 'AbstractWindServer' => 'WIND:core.AbstractWindServer', + 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', + 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', + 'WindConfig' => 'WIND:core.config.WindConfig', + 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', + 'WindDaoCacheListener' => 'WIND:core.dao.listener.WindDaoCacheListener', + 'WindActionException' => 'WIND:core.exception.WindActionException', + 'WindCacheException' => 'WIND:core.exception.WindCacheException', + 'WindDaoException' => 'WIND:core.exception.WindDaoException', + 'WindException' => 'WIND:core.exception.WindException', + 'WindFinalException' => 'WIND:core.exception.WindFinalException', + 'WindSqlException' => 'WIND:core.exception.WindSqlException', + 'WindViewException' => 'WIND:core.exception.WindViewException', + 'IWindFactory' => 'WIND:core.factory.IWindFactory', + 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', + 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', + 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', + 'WindComponentDefinition' => 'WIND:core.factory.WindComponentDefinition', + 'WindComponentFactory' => 'WIND:core.factory.WindComponentFactory', + 'WindFactory' => 'WIND:core.factory.WindFactory', + 'WindFilter' => 'WIND:core.filter.WindFilter', + 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', + 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', + 'IWindRequest' => 'WIND:core.request.IWindRequest', + 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', + 'IWindResponse' => 'WIND:core.response.IWindResponse', + 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', + 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', + 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', + 'AbstractWindTemplateCompiler' => 'WIND:core.viewer.AbstractWindTemplateCompiler', + 'AbstractWindViewTemplate' => 'WIND:core.viewer.AbstractWindViewTemplate', + 'WindTemplateCompilerAction' => 'WIND:core.viewer.compiler.WindTemplateCompilerAction', + 'WindTemplateCompilerComponent' => 'WIND:core.viewer.compiler.WindTemplateCompilerComponent', + 'WindTemplateCompilerEcho' => 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', + 'WindTemplateCompilerInternal' => 'WIND:core.viewer.compiler.WindTemplateCompilerInternal', + 'WindTemplateCompilerPage' => 'WIND:core.viewer.compiler.WindTemplateCompilerPage', + 'WindTemplateCompilerScript' => 'WIND:core.viewer.compiler.WindTemplateCompilerScript', + 'WindTemplateCompilerTemplate' => 'WIND:core.viewer.compiler.WindTemplateCompilerTemplate', + 'WindViewTemplate' => 'WIND:core.viewer.compiler.WindViewTemplate', + 'IWindViewerResolver' => 'WIND:core.viewer.IWindViewerResolver', + 'WindViewCacheListener' => 'WIND:core.viewer.listener.WindViewCacheListener', + 'WindLayout' => 'WIND:core.viewer.WindLayout', + 'WindView' => 'WIND:core.viewer.WindView', + 'WindViewerResolver' => 'WIND:core.viewer.WindViewerResolver', + 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', + 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', + 'IWindApplication' => 'WIND:core.web.IWindApplication', + 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', + 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', + 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', + 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', + 'WindAction' => 'WIND:core.web.WindAction', + 'WindController' => 'WIND:core.web.WindController', + 'WindDispatcher' => 'WIND:core.web.WindDispatcher', + 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', + 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', + 'WindFormController' => 'WIND:core.web.WindFormController', + 'WindForward' => 'WIND:core.web.WindForward', + 'WindFrontController' => 'WIND:core.web.WindFrontController', + 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', + 'WindWebApplication' => 'WIND:core.web.WindWebApplication', + 'WindComponentModule' => 'WIND:core.WindComponentModule', + 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', + 'WindHelper' => 'WIND:core.WindHelper', + 'WindModule' => 'WIND:core.WindModule', + 'WindLogger' => 'COM:log.WindLogger'); + } +} +Wind::init(); +/* 组件定义 */ +!defined('COMPONENT_WEBAPP') && define('COMPONENT_WEBAPP', 'windWebApp'); +!defined('COMPONENT_ERRORHANDLER') && define('COMPONENT_ERRORHANDLER', 'errorHandler'); +!defined('COMPONENT_LOGGER') && define('COMPONENT_LOGGER', 'windLogger'); +!defined('COMPONENT_FORWARD') && define('COMPONENT_FORWARD', 'forward'); +!defined('COMPONENT_ROUTER') && define('COMPONENT_ROUTER', 'urlBasedRouter'); +!defined('COMPONENT_URLHELPER') && define('COMPONENT_URLHELPER', 'urlHelper'); +!defined('COMPONENT_VIEW') && define('COMPONENT_VIEW', 'windView'); +!defined('COMPONENT_VIEWRESOLVER') && define('COMPONENT_VIEWRESOLVER', 'viewResolver'); +!defined('COMPONENT_TEMPLATE') && define('COMPONENT_TEMPLATE', 'template'); +!defined('COMPONENT_ERRORMESSAGE') && define('COMPONENT_ERRORMESSAGE', 'errorMessage'); +!defined('COMPONENT_DB') && define('COMPONENT_DB', 'db'); +//TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 +//********************约定变量*********************************** +define('WIND_M_ERROR', 'windError'); +define('WIND_CONFIG_CACHE', 'wind_components_config'); +//**********配置*******通用常量定义*************************************** +define('WIND_CONFIG_CONFIG', 'config'); +define('WIND_CONFIG_CLASS', 'class'); +define('WIND_CONFIG_CLASSPATH', 'path'); +define('WIND_CONFIG_RESOURCE', 'resource'); +define('WIND_CONFIG_VALUE', 'value'); \ No newline at end of file From 9e0aca36d25584c57add1d0dac6fc2c1285ff2de Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 27 Jun 2011 07:39:09 +0000 Subject: [PATCH 0009/1065] =?UTF-8?q?=E7=BB=84=E4=BB=B6=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2044 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindFrontController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 51347811..9d5cc43c 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -22,7 +22,7 @@ class WindFrontController extends AbstractWindServer { const WIND_CONFIG = 'WIND:core.config.WindSystemConfig'; const WIND_FACTORY = 'WIND:core.factory.WindComponentFactory'; - const COMPONENTS_CONFIG = 'WIND:config.components_config.php'; + const COMPONENTS_CONFIG = 'WIND:components_config.php'; /** * @var WindSystemConfig */ From 80c4e6cae233042b501a499a2d48860c752e4410 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 27 Jun 2011 08:37:00 +0000 Subject: [PATCH 0010/1065] =?UTF-8?q?NEW=20-=20bug=20146:=20db=20windSqlSt?= =?UTF-8?q?atement=E6=8E=A5=E5=8F=A3=E5=AE=8C=E5=96=84=20http://bugs.phpwi?= =?UTF-8?q?nd-inc.com/show=5Fbug.cgi=3Fid=3D146?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2046 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 73 +++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 64526821..512ff12d 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -68,6 +68,28 @@ public function bindParam($parameter, $variable, $data_type = null, $length = nu } } + /** + * 批量绑定变量 + * 如果是一维数组,则使用key=>value的形式,key代表变量位置,value代表替换的值,而替换值需要的类型则通过该值的类型来判断---不准确 + * 如果是一个二维数组,则允许,key=>array(0=>value, 1=>data_type, 2=>length, 3=>driver_options)的方式来传递变量。 + * @param array $parameters + * @return WindSqlStatement + */ + public function bindParams($parameters) { + foreach ($parameters as $key => $value) { + if (is_array($value)) { + list($var) = $value; + $dataType = isset($value[1]) ? $value[1] : null; + $length = isset($value[2]) ? $value[2] : null; + $driverOptions = isset($value[3]) ? $value[3] : null; + $this->bindParam($key, $var, $dataType, $length, $driverOptions); + } else { + $this->bindParam($key, $value, $this->_getPdoDataType($value)); + } + } + return $this; + } + /** * @param string $parameter * @param string $value @@ -110,10 +132,59 @@ public function query($params = array(), $fetchMode = 0, $fetchType = 0) { $this->execute($params, false); return new WindResultSet($this, $fetchMode, $fetchType); } + + /** + * 执行SQL语句,并返回查询结果 + * @param array $params + * @param string $index 索引 + * @param int $fetchMode + * @param int $fetchType + * @return array + */ + public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) { + $this->bindParams($params); + $this->execute(array(), false); + $rs = new WindResultSet($this, $fetchMode, $fetchType); + $result = array(); + while($one = $rs->fetch()) { + isset($one[$index]) ? $result[$one[$index]] = $one : $result[] = $one; + } + return $result; + } + + /** + * 执行SQL语句,并返回查询结果 + * @param array $params + * @param int $fetchMode + * @param int $fetchType + * @return string + */ + public function getValue($params = array()) { + $this->bindParams($params); + $this->execute(array(), false); + $rs = new WindResultSet($this, PDO::FETCH_NUM, 0); + $one = $rs->fetch(); + if ($one) return $one[0]; + return null; + } + + /** + * 执行SQL语句,并返回查询结果 + * @param array $params + * @param int $fetchMode + * @param int $fetchType + * @return array + */ + public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { + $this->bindParams($params); + $this->execute(array(), false); + $rs = new WindResultSet($this, $fetchMode, $fetchType); + return $rs->fetch(); + } /** * 执行sql,$params为变量信息,并返回结果集 - * @param array $params + * @param array $params -- 注意:绑定的变量数组下标将从0开始索引, * @param boolean $rowCount * @return rowCount */ From 3811ff4798b651137782f69d98f39d4aa3822b60 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 09:21:28 +0000 Subject: [PATCH 0011/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2047 18ba2127-5a84-46d4-baec-3457e417f034 --- .../dao/{AbstractWindDao.php => WindDao.php} | 14 +++----------- ...stractWindDaoFactory.php => WindDaoFactory.php} | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) rename wind/component/dao/{AbstractWindDao.php => WindDao.php} (94%) rename wind/component/dao/{AbstractWindDaoFactory.php => WindDaoFactory.php} (98%) diff --git a/wind/component/dao/AbstractWindDao.php b/wind/component/dao/WindDao.php similarity index 94% rename from wind/component/dao/AbstractWindDao.php rename to wind/component/dao/WindDao.php index 44889024..8c7536d5 100644 --- a/wind/component/dao/AbstractWindDao.php +++ b/wind/component/dao/WindDao.php @@ -2,31 +2,23 @@ Wind::import('WIND:core.WindModule'); /** * 抽象DAO接口 - * + * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ -abstract class AbstractWindDao extends WindModule { - +class WindDao extends WindModule { protected $dbClass = 'WIND:component.db.WindConnection'; - protected $dbConfig = ''; - protected $cacheClass = ''; - protected $cacheConfig = ''; - protected $isDataCache = false; - protected $dbDefinition = null; - /** - * @var WindConnection 数据库链接兑现 + * @var WindConnection 数据库链接对象 */ private $connection = null; - /** * @var AbstractWindCache 缓存操作句柄 */ diff --git a/wind/component/dao/AbstractWindDaoFactory.php b/wind/component/dao/WindDaoFactory.php similarity index 98% rename from wind/component/dao/AbstractWindDaoFactory.php rename to wind/component/dao/WindDaoFactory.php index 80ee1d20..bb32b3cb 100644 --- a/wind/component/dao/AbstractWindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -14,7 +14,7 @@ * @version $Id$ * @package */ -abstract class AbstractWindDaoFactory { +class WindDaoFactory { protected $windFactory = null; protected $daoResource = ''; protected $dbConnections = array(); From 6b35dec72599ff9738517219acea4116bb799fa0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 14:45:53 +0000 Subject: [PATCH 0012/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2049 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindAction.php | 7 ------- wind/core/web/WindErrorHandler.php | 17 +++-------------- wind/core/web/WindFrontController.php | 9 ++------- 3 files changed, 5 insertions(+), 28 deletions(-) diff --git a/wind/core/web/WindAction.php b/wind/core/web/WindAction.php index 3ad06891..355abc05 100644 --- a/wind/core/web/WindAction.php +++ b/wind/core/web/WindAction.php @@ -5,7 +5,6 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ - Wind::import('WIND:core.WindComponentModule'); /** * the last known user to change this file in the repository <$LastChangedBy$> @@ -14,14 +13,11 @@ * @package */ abstract class WindAction extends WindComponentModule { - protected $forward = null; - /** * @var WindUrlHelper */ protected $urlHelper = null; - /** * @var WindErrorMessage */ @@ -81,7 +77,6 @@ protected function forwardRedirect($url) { } /* 数据处理 */ - /** * 设置模板数据 * @@ -145,7 +140,6 @@ protected function setLayout($layout) { } /* 错误处理 */ - /** * 添加错误信息 * @param string $message @@ -270,5 +264,4 @@ private function getInputWithArray($name, $type = '') { protected function getWriteTableForGetterAndSetter() { return array('forward', 'urlHelper', 'errorMessage'); } - } \ No newline at end of file diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php index 91ecee28..b9f16822 100644 --- a/wind/core/web/WindErrorHandler.php +++ b/wind/core/web/WindErrorHandler.php @@ -35,7 +35,7 @@ public function run() { echo "

User Message: (" . count($this->error) . ")

"; echo "

" . nl2br($_tmp) . "

"; echo "Click to go back."; - $this->addLog("User Error:", $_tmp); + Wind::log('User Error:', $_tmp); exit(); } @@ -63,7 +63,7 @@ final public function errorHandle($errno, $errstr, $errfile, $errline) { echo "

" . nl2br($_tmp) . "

"; } else echo "

" . $this->errnoMap($errno) . " $errstr

"; - $this->addLog($this->errnoMap($errno) . $errstr, $_tmp); + Wind::log($this->errnoMap($errno) . $errstr, $_tmp); } } @@ -133,22 +133,11 @@ final public function exceptionHandle($exception) { echo '

' . get_class($exception) . '

'; echo '

' . $exception->getMessage() . '

'; } - $this->addLog($_tmp, $exception->getTraceAsString()); + Wind::log("$_tmp:" . $exception->getTraceAsString()); exit(); } private function getFile($filePath) { return $filePath; } - - /** - * 日志记录 - * @param string $errno - * @param string $message - */ - private function addLog($errno, $message) { - Wind::import('WIND:component.log.WindLogger'); - $logger = new WindLogger(); - $logger->info("$errno:" . $message); - } } \ No newline at end of file diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 9d5cc43c..a347c5d2 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -100,7 +100,7 @@ private function getFilterChain() { */ protected function beforeProcess(WindHttpRequest $request, WindHttpResponse $response) { Wind::import('WIND:core.web.WindErrorHandler'); - set_error_handler(array(new WindErrorHandler(), 'errorHandle'), error_reporting()); + set_error_handler(array(new WindErrorHandler(), 'errorHandle')); set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); } @@ -108,12 +108,7 @@ protected function beforeProcess(WindHttpRequest $request, WindHttpResponse $res * @see AbstractWindServer::afterProcess() */ protected function afterProcess(WindHttpRequest $request, WindHttpResponse $response) { - //add log - if (IS_DEBUG) { - /* @var $logger WindLogger */ - $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); - $logger->flush(); - } + Wind::getLogger()->flush(); restore_error_handler(); restore_exception_handler(); } From a4de51de1e7685ce70af68ce790fed44e71138fb Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 14:46:04 +0000 Subject: [PATCH 0013/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2050 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindClassDefinition.php | 26 ------------------- wind/core/factory/WindComponentDefinition.php | 12 --------- 2 files changed, 38 deletions(-) diff --git a/wind/core/factory/WindClassDefinition.php b/wind/core/factory/WindClassDefinition.php index 7f1a5066..ceeeee3d 100644 --- a/wind/core/factory/WindClassDefinition.php +++ b/wind/core/factory/WindClassDefinition.php @@ -5,7 +5,6 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ - Wind::import('WIND:core.WindModule'); /** * the last known user to change this file in the repository <$LastChangedBy$> @@ -21,93 +20,70 @@ * @package */ class WindClassDefinition extends WindModule { - /* 配置信息定义 */ const NAME = 'name'; - const PATH = 'path'; - const FACTORY_METHOD = 'factory-method'; - const INIT_METHOD = 'init-method'; - const SCOPE = 'scope'; - const PROPERTIES = 'properties'; - const CONSTRUCTOR_ARG = 'constructor-arg'; - const REF = 'ref'; - const VALUE = 'value'; - /* 支持的类命名空间 */ const SCOPE_SINGLETON = 'singleton'; - const SCOPE_PROTOTYPE = 'prototype'; - const SCOPE_REQUEST = 'request'; - /** * 类名称 * @var string */ protected $className = ''; - /** * 类别名 * @var string */ protected $alias = ''; - /** * 类路径 * @var string */ protected $path = ''; - /** * 类的存储空间 * singleton/prototype/request/session * @var string */ protected $scope = ''; - /** * 类自定义的初始化方法 * @var string */ protected $factoryMethod = ''; - /** * 类设置属性之后的调用处理操作 * @var string */ protected $initMethod = ''; - /** * 构造参数定义 * @var array */ protected $constructArgs = array(); - /** * 类属性定义 * @var array */ protected $propertys = array(); - /** * 类定义 * @var array */ protected $classDefinition; - /** * @var prototype */ private $prototype = null; - /** * @var instance */ @@ -210,7 +186,6 @@ protected function createInstance($factory, $args = array()) { $args = $this->setProperties($this->getConstructArgs(), $factory); } $instance = $factory->createInstance($this->getClassName(), $args); - return $instance; } @@ -436,5 +411,4 @@ public function setFactoryMethod($factoryMethod) { public function setInitMethod($initMethod) { $this->initMethod = $initMethod; } - } \ No newline at end of file diff --git a/wind/core/factory/WindComponentDefinition.php b/wind/core/factory/WindComponentDefinition.php index 605684a9..463f532e 100644 --- a/wind/core/factory/WindComponentDefinition.php +++ b/wind/core/factory/WindComponentDefinition.php @@ -5,7 +5,6 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ - Wind::import('WIND:core.factory.WindClassDefinition'); Wind::import('WIND:core.config.parser.WindConfigParser'); Wind::import('WIND:core.config.WindConfig'); @@ -18,30 +17,21 @@ * @package */ class WindComponentDefinition extends WindClassDefinition { - /* 配置 */ const CONFIG = 'config'; - const RESOURCE = 'resource'; - /* 是否支持隐藏变量 */ const HIDDEN_PRO = 'hidden-pro'; - /* component 定义 */ - const PROXY = 'proxy'; - protected $proxyClass = 'WIND:core.factory.proxy.WindClassProxy'; - /** * 类代理对象定义 * * @var string */ protected $proxy = ''; - protected $hiddenPro = ''; - /** * @var array */ @@ -90,7 +80,6 @@ protected function setProxyForClass($instance, $factory) { $proxyPath = ($proxyPath === 'true' || $proxyPath === true) ? $this->proxyClass : $this->getProxy(); $proxyClass = Wind::import($proxyPath); if (!class_exists($proxyClass)) return; - $proxyClass = $factory->createInstance($proxyClass); if ($proxyClass instanceof WindClassProxy) $instance->setClassProxy($proxyClass); } @@ -152,5 +141,4 @@ public function getConfig() { public function setConfig($config) { $this->config = $config; } - } \ No newline at end of file From ad392496361467e079478d9a41908fdbbe699494 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 14:46:20 +0000 Subject: [PATCH 0014/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2051 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindComponentModule.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php index 56eca015..d013f5bc 100644 --- a/wind/core/WindComponentModule.php +++ b/wind/core/WindComponentModule.php @@ -31,11 +31,7 @@ abstract class WindComponentModule extends WindModule { * Enter description here ... */ protected function getAutoSetProperty() { - return array( - 'request' => 'IWindRequest', - 'response' => 'IWindResponse', - 'windSystemConfig' => 'WindSystemConfig', - 'windFactory' => 'WindFactory'); + return array('request' => 'IWindRequest', 'response' => 'IWindResponse', 'windSystemConfig' => 'WindSystemConfig', 'windFactory' => 'WindFactory'); } /** @@ -67,7 +63,7 @@ public function setAttribute($alias, $object = null) { * @param array $default 缺省的数组格式 * @return string|array */ - public function getConfig($configName = '', $subConfigName = '', $default = array()) { + public function getConfig($configName = '', $subConfigName = '', $default = '') { if (null === $this->_config) return ''; return $this->_config->getConfig($configName, $subConfigName, array(), $default); } @@ -86,7 +82,7 @@ public function setConfig($config) { $this->_config = new WindConfig($config, $configParser, get_class($this), CONFIG_CACHE); } } - + /** * 更改现有的config 或是合并 * @param array $config From a804fe73a93dc0187b22baf3ac2bf6d56471e25c Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 14:46:31 +0000 Subject: [PATCH 0015/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2052 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 5 +++++ wind/component/db/WindResultSet.php | 11 ++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 55c97e87..1ed4fa17 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -224,8 +224,13 @@ public function init() { Wind::log("component.db.WindConnection._init() \r\n dsn: " . $this->getDsn() . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, WindLogger::LEVEL_DEBUG); } catch (PDOException $e) { Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", WindLogger::LEVEL_TRACE); + $this->close(); throw new WindDbException($e->getMessage()); } } + + public function close() { + $this->_dbHandle = null; + } } ?> \ No newline at end of file diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 9b8f04df..7a6c252a 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -26,7 +26,6 @@ class WindResultSet { public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { $this->_statement = $sqlStatement->getStatement(); if ($fetchMode != 0) $this->_fetchMode = $fetchMode; - if ($fetchType != 0) $this->_fetchType = $fetchType; } /** @@ -35,9 +34,7 @@ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { */ public function setFetchMode($fetchMode) { $fetchMode = func_get_args(); - call_user_func_array(array( - $this->_statement, - 'setFetchMode'), $fetchMode); + call_user_func_array(array($this->_statement, 'setFetchMode'), $fetchMode); } /** @@ -59,9 +56,13 @@ public function fetch() { /** * @param $fetchMode * @param $fetchType + * @return array */ private function _fetch($fetchMode, $fetchType) { - return $this->_statement->fetch($fetchMode, $fetchType); + if (!$result = $this->_statement->fetch($fetchMode, $fetchType)) + return array(); + else + return $result; } /** From ce8c615c9f93814fe78954eceac95a76b8bc9e05 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 14:46:45 +0000 Subject: [PATCH 0016/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2053 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDao.php | 5 +- wind/component/dao/WindDaoFactory.php | 67 +++++++++++++-------------- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php index 8c7536d5..72c48360 100644 --- a/wind/component/dao/WindDao.php +++ b/wind/component/dao/WindDao.php @@ -41,7 +41,10 @@ public function getDbDefinition() { $definition->setPath($this->dbClass); $definition->setScope(WindComponentDefinition::SCOPE_SINGLETON); $definition->setAlias($this->dbClass); - $definition->setConfig(array(WindComponentDefinition::RESOURCE => $this->dbConfig)); + if (is_array($this->dbConfig)) + $definition->setConfig($this->dbConfig); + else + $definition->setConfig(array(WindComponentDefinition::RESOURCE => $this->dbConfig)); return $definition; } diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index bb32b3cb..b99a4a76 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -22,8 +22,8 @@ class WindDaoFactory { /** * 返回Dao类实例 - * * @param string $className + * @return WindDao */ public function getDao($className) { try { @@ -49,6 +49,20 @@ public function getDao($className) { } } + /** + * @return the $daoResource + */ + public function getDaoResource() { + return $this->daoResource; + } + + /** + * @param field_type $daoResource + */ + public function setDaoResource($daoResource) { + $this->daoResource = $daoResource; + } + /** * 注册Dao缓存监听 * @param AbstractWindDao daoInstance @@ -68,14 +82,13 @@ private function registerCacheListener($daoInstance) { /** * 返回DbHandler - * @param AbstractWindDao $daoObject + * @param WindDao $daoObject * @return WindConnection */ protected function createDbConnection($daoObject) { $_dbClass = $daoObject->getDbClass(); - $_connection = null; if (!isset($this->dbConnections[$_dbClass])) { - $this->createWindFactory(); + $this->_getWindFactory(); $defintion = $daoObject->getDbDefinition(); $this->windFactory->addClassDefinitions($defintion); $this->dbConnections[$_dbClass] = $this->windFactory->getInstance($defintion->getAlias()); @@ -83,20 +96,6 @@ protected function createDbConnection($daoObject) { return $this->getHandler($_dbClass); } - /** - * @param string $key - * @return WindConnection - */ - private function getHandler($key) { - $connection = $this->dbConnections[$key]; - if ($connection === null) return null; - if ($connection instanceof WindConnectionManager) { - return $connection->getConnection(); - } elseif ($connection instanceof WindConnection) { - return $connection; - } - } - /** * 返回Cache对象 * @param AbstractWindDao $daoObject @@ -105,7 +104,7 @@ private function getHandler($key) { protected function createCacheHandler($daoObject) { $_cacheClass = $daoObject->getCacheClass(); if (!isset($this->caches[$_cacheClass])) { - $this->createWindFactory(); + $this->_getWindFactory(); $defintion = $daoObject->getCacheDefinition(); $this->windFactory->addClassDefinitions($defintion); $this->caches[$_cacheClass] = $this->windFactory->getInstance($defintion->getAlias()); @@ -113,29 +112,29 @@ protected function createCacheHandler($daoObject) { return $this->caches[$_cacheClass]; } + /** + * @param string $key + * @return WindConnection + */ + private function getHandler($key) { + $connection = $this->dbConnections[$key]; + if ($connection === null) return null; + if ($connection instanceof WindConnectionManager) { + return $connection->getConnection(); + } elseif ($connection instanceof WindConnection) { + return $connection; + } + } + /** * @return WindFactory */ - private function createWindFactory() { + private function _getWindFactory() { if ($this->windFactory === null) { Wind::import('WIND:core.factory.WindComponentFactory'); $this->windFactory = new WindComponentFactory(); } return $this->windFactory; } - - /** - * @return the $daoResource - */ - public function getDaoResource() { - return $this->daoResource; - } - - /** - * @param field_type $daoResource - */ - public function setDaoResource($daoResource) { - $this->daoResource = $daoResource; - } } ?> \ No newline at end of file From 45862be1064bd966773fdaabaf32a968c005b534 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 27 Jun 2011 14:54:16 +0000 Subject: [PATCH 0017/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2054 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 6 +++--- wind/component/log/WindLogger.php | 23 ++++++++--------------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 4277d4e1..f554839d 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -2,7 +2,7 @@ /* 框架版本信息 */ define('VERSION', '0.5'); define('PHPVERSION', '5.1.2'); -!defined('IS_DEBUG') && define('IS_DEBUG', 0); +!defined('IS_DEBUG') && define('IS_DEBUG', 1); !defined('DEBUG_TIME') && define('DEBUG_TIME', microtime(true)); /* 路径相关配置信息 */ !defined('D_S') && define('D_S', DIRECTORY_SEPARATOR); @@ -244,11 +244,11 @@ public static function profileEnd($token, $message = '', $type = 'wend.core') { public static function getLogger() { if (self::$_logger === null) { self::$_logger = new WindLogger(); - self::$_logger->setLogFile(COMPILE_PATH . 'log/log.txt'); + self::$_logger->setLogDir(COMPILE_PATH . '/log/'); } return self::$_logger; } - + /** * 系统命名空间注册方法 * @return diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index 8a2ee87f..f1c30ee2 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -22,7 +22,7 @@ class WindLogger extends WindComponentModule { private $_logs = array(); private $_logCount = 0; private $_profiles = array(); - private $_logFile; + private $_logDir; private $_maxFileSize = 100; /** @@ -170,12 +170,7 @@ private function _buildProfile($msg, $type, $timer, $mem) { if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); - $this->_profiles[] = array( - $_token, - substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), - $type, - $timer, - $mem); + $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); @@ -266,9 +261,7 @@ private function _getTrace() { $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; - $args = array_map(array( - $this, - '_buildArg'), $trace['args']); + $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; @@ -298,11 +291,11 @@ private function _buildArg($arg) { */ private function _getFileName() { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; - $_logfile = $this->_logFile; + $_logfile = $this->_logDir . '/log.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { - $counter ++; + $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); @@ -317,15 +310,15 @@ public function __destruct() { /** * @param field_type $_logFile */ - public function setLogFile($logFile) { - $this->_logFile = $logFile; + public function setLogDir($logDir) { + $this->_logDir = $logDir; } /** * @param field_type $_maxFileSize */ public function setMaxFileSize($maxFileSize) { - $this->_maxFileSize = (int)$maxFileSize; + $this->_maxFileSize = (int) $maxFileSize; } } From 6f4331ed30ba92099eae596ffafa9e9f90cb8c4f Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 28 Jun 2011 03:15:46 +0000 Subject: [PATCH 0018/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2056 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 39 +++++++++++--------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 512ff12d..027633e2 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -26,11 +26,7 @@ class WindSqlStatement { * * @var array */ - private $_typeMap = array( - 'boolean' => PDO::PARAM_BOOL, - 'integer' => PDO::PARAM_INT, - 'string' => PDO::PARAM_STR, - 'NULL' => PDO::PARAM_NULL); + private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); /** * @param WindConnection $connection @@ -45,22 +41,22 @@ public function __construct($connection, $query) { * 参数绑定 * @param string $parameter * @param string $variable - * @param string $data_type + * @param string $dataType * @param int $length - * @param $driver_options + * @param $driverOptions * @return */ - public function bindParam($parameter, $variable, $data_type = null, $length = null, $driver_options = null) { + public function bindParam($parameter, &$variable, $dataType = null, $length = null, $driverOptions = null) { try { Wind::log("component.db.WindSqlStatement.bindParam. parameter:" . $parameter . " variable:" . $variable, WindLogger::LEVEL_INFO, "component.db"); $this->init(); - if ($data_type === null) { - $data_type = $this->_getPdoDataType($variable); + if ($dataType === null) { + $dataType = $this->_getPdoDataType($variable); } if ($length === null) - $this->getStatement()->bindParam($parameter, $variable, $data_type); + $this->getStatement()->bindParam($parameter, $variable, $dataType); else - $this->getStatement()->bindParam($parameter, $variable, $data_type, $length, $driver_options); + $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, $driverOptions); return $this; } catch (PDOException $e) { Wind::log("component.db.WindSqlStatement.bindParam. exception message:" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); @@ -80,7 +76,7 @@ public function bindParams($parameters) { if (is_array($value)) { list($var) = $value; $dataType = isset($value[1]) ? $value[1] : null; - $length = isset($value[2]) ? $value[2] : null; + $length = isset($value[2]) ? $value[2] : null; $driverOptions = isset($value[3]) ? $value[3] : null; $this->bindParam($key, $var, $dataType, $length, $driverOptions); } else { @@ -107,7 +103,7 @@ public function bindValue($parameter, $value, $data_type = null) { return $this; } catch (PDOException $e) { Wind::log("component.db.WindSqlStatement.bindValue. exception message:" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); - throw new WindException($e->getMessage()); + throw new WindDbException($e->getMessage()); } } @@ -132,7 +128,7 @@ public function query($params = array(), $fetchMode = 0, $fetchType = 0) { $this->execute($params, false); return new WindResultSet($this, $fetchMode, $fetchType); } - + /** * 执行SQL语句,并返回查询结果 * @param array $params @@ -145,13 +141,14 @@ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchT $this->bindParams($params); $this->execute(array(), false); $rs = new WindResultSet($this, $fetchMode, $fetchType); + if (!$index) return $rs->fetchAll(); $result = array(); - while($one = $rs->fetch()) { + while ($one = $rs->fetch()) { isset($one[$index]) ? $result[$one[$index]] = $one : $result[] = $one; } return $result; } - + /** * 执行SQL语句,并返回查询结果 * @param array $params @@ -159,15 +156,13 @@ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchT * @param int $fetchType * @return string */ - public function getValue($params = array()) { + public function getValue($params = array(), $column = 0) { $this->bindParams($params); $this->execute(array(), false); $rs = new WindResultSet($this, PDO::FETCH_NUM, 0); - $one = $rs->fetch(); - if ($one) return $one[0]; - return null; + return $rs->fetchColumn($column); } - + /** * 执行SQL语句,并返回查询结果 * @param array $params From a8793333835bf5589fd003ec8e7589d76e3c2ea8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 28 Jun 2011 04:10:30 +0000 Subject: [PATCH 0019/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2058 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 42 ++++++++++++++++++++------ 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 027633e2..9827eb68 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -117,6 +117,33 @@ public function bindValues($values) { return $this; } + /** + * 将列值绑定到php变量 + * @param $column + * @param $param + * @param $type + * @param $maxlen + * @param $driverdata + * @throws WindDbException + */ + public function bindColumn($column, &$param, $type = null, $maxlen = null, $driverdata = null) { + try { + Wind::log("component.db.WindSqlStatement.bindColumn.", WindLogger::LEVEL_INFO, "component.db"); + $this->init(); + if ($type == null) $type = $this->_getPdoDataType($param); + if ($type == null) + $this->getStatement()->bindColumn($column, $param); + elseif ($maxlen == null) + $this->getStatement()->bindColumn($column, $param, $type); + else + $this->getStatement()->bindColumn($column, $param, $type, $maxlen, $driverdata); + return $this; + } catch (PDOException $e) { + Wind::log("component.db.WindSqlStatement.bindColumn. exception message" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); + throw new WindDbException($e->getMessage()); + } + } + /** * 执行SQL语句,并返回查询结果 * @param array $params @@ -138,8 +165,7 @@ public function query($params = array(), $fetchMode = 0, $fetchType = 0) { * @return array */ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) { - $this->bindParams($params); - $this->execute(array(), false); + $this->execute($params, false); $rs = new WindResultSet($this, $fetchMode, $fetchType); if (!$index) return $rs->fetchAll(); $result = array(); @@ -157,8 +183,7 @@ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchT * @return string */ public function getValue($params = array(), $column = 0) { - $this->bindParams($params); - $this->execute(array(), false); + $this->execute($params, false); $rs = new WindResultSet($this, PDO::FETCH_NUM, 0); return $rs->fetchColumn($column); } @@ -171,8 +196,7 @@ public function getValue($params = array(), $column = 0) { * @return array */ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { - $this->bindParams($params); - $this->execute(array(), false); + $this->execute($params, false); $rs = new WindResultSet($this, $fetchMode, $fetchType); return $rs->fetch(); } @@ -187,10 +211,8 @@ public function execute($params = array(), $rowCount = true) { try { $this->init(); Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); - if (empty($params)) { - $this->getStatement()->execute(); - } else - $this->getStatement()->execute($params); + $this->bindParams($params); + $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); return $_result; From 21241c66e9291224a0d59d98fe94ba62edfae62f Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 28 Jun 2011 04:24:34 +0000 Subject: [PATCH 0020/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2059 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 9 ++++++++- wind/component/db/WindSqlStatement.php | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 7a6c252a..69e70d42 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -38,7 +38,14 @@ public function setFetchMode($fetchMode) { } /** - * 返回结果集的条数 + * 返回最后一条Sql语句的影响行数 + */ + public function rowCount() { + return $this->_statement->rowCount(); + } + + /** + * 返回结果集中的列数 * @return number */ public function columnCount() { diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 9827eb68..43dead0b 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -144,6 +144,15 @@ public function bindColumn($column, &$param, $type = null, $maxlen = null, $driv } } + /** + * 执行SQL语句,并返回更新影响行数 + * @param array $params + * @throws WindDbException + */ + public function update($params = array()) { + return $this->execute($params); + } + /** * 执行SQL语句,并返回查询结果 * @param array $params From 54b06ff2be0be2701409c44f41cf730f5bb25a3c Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 28 Jun 2011 12:21:02 +0000 Subject: [PATCH 0021/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2060 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 26 +++++++++++++++++++++----- wind/component/db/WindSqlStatement.php | 24 +++++++++++++++++++++++- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 69e70d42..53ede774 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -19,12 +19,14 @@ class WindResultSet { * @var number */ private $_fetchType = PDO::FETCH_ORI_FIRST; + private $_columns = array(); /** * @param WindSqlStatement $sqlStatement */ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { $this->_statement = $sqlStatement->getStatement(); + $this->_columns = $sqlStatement->getColumns(); if ($fetchMode != 0) $this->_fetchMode = $fetchMode; } @@ -66,10 +68,16 @@ public function fetch() { * @return array */ private function _fetch($fetchMode, $fetchType) { - if (!$result = $this->_statement->fetch($fetchMode, $fetchType)) - return array(); - else + if (!empty($this->_columns)) $fetchMode = PDO::FETCH_BOUND; + $result = array(); + if ($row = $this->_statement->fetch($fetchMode, $fetchType)) { + if (empty($this->_columns)) return $row; + foreach ($this->_columns as $key => $value) { + $result[$key] = $value; + } return $result; + } + return array(); } /** @@ -83,8 +91,16 @@ public function nextRowset() { * 返回所有的查询结果 * @return array */ - public function fetchAll() { - return $this->_statement->fetchAll(); + public function fetchAll($index = 0) { + if (empty($this->_columns)) + return $this->_statement->fetchAll(); + else { + $result = array(); + while ($row = $this->fetch()) { + $result[] = $row; + } + return $result; + } } /** diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 43dead0b..77b030d6 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -27,6 +27,7 @@ class WindSqlStatement { * @var array */ private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); + private $_columns = array(); /** * @param WindConnection $connection @@ -126,7 +127,7 @@ public function bindValues($values) { * @param $driverdata * @throws WindDbException */ - public function bindColumn($column, &$param, $type = null, $maxlen = null, $driverdata = null) { + public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $driverdata = null) { try { Wind::log("component.db.WindSqlStatement.bindColumn.", WindLogger::LEVEL_INFO, "component.db"); $this->init(); @@ -137,6 +138,7 @@ public function bindColumn($column, &$param, $type = null, $maxlen = null, $driv $this->getStatement()->bindColumn($column, $param, $type); else $this->getStatement()->bindColumn($column, $param, $type, $maxlen, $driverdata); + $this->_columns[$column] = & $param; return $this; } catch (PDOException $e) { Wind::log("component.db.WindSqlStatement.bindColumn. exception message" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); @@ -144,6 +146,19 @@ public function bindColumn($column, &$param, $type = null, $maxlen = null, $driv } } + public function bindColumns($columns, &$param = array()) { + $int = 0; + foreach ($columns as $value) { + $this->bindColumn($value, $param[$int++]); + } + } + + /** + * Enter description here ... + * @param unknown_type $columns + */ + public function setColumns($columns) {} + /** * 执行SQL语句,并返回更新影响行数 * @param array $params @@ -265,6 +280,13 @@ public function getStatement() { return $this->_statement; } + /** + * @return the $_columns + */ + public function getColumns() { + return $this->_columns; + } + /** * @return */ From 55a9eec8052e55312aa811f8f4d91a37edffc10f Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 29 Jun 2011 02:26:02 +0000 Subject: [PATCH 0022/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D=EF=BC=8C?= =?UTF-8?q?=E8=8E=B7=E5=BE=97=E7=9A=84=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=B8=8D=E6=AD=A3=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2061 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindComponentModule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php index d013f5bc..a81c8bab 100644 --- a/wind/core/WindComponentModule.php +++ b/wind/core/WindComponentModule.php @@ -65,7 +65,7 @@ public function setAttribute($alias, $object = null) { */ public function getConfig($configName = '', $subConfigName = '', $default = '') { if (null === $this->_config) return ''; - return $this->_config->getConfig($configName, $subConfigName, array(), $default); + return $this->_config->getConfig($configName, $subConfigName, $default); } /** From b3f082e73a9ba2d3d949f658adba9b61b0504e29 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 03:37:00 +0000 Subject: [PATCH 0023/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D=EF=BC=8Cresolve?= =?UTF-8?q?Controller=E6=9D=A5=E8=87=AAWindHelper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2062 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindDispatcher.php | 2 +- wind/core/web/WindUrlHelper.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php index 761c9e16..90fe8469 100644 --- a/wind/core/web/WindDispatcher.php +++ b/wind/core/web/WindDispatcher.php @@ -63,7 +63,7 @@ protected function dispatchWithRedirect($forward) { */ protected function dispatchWithAction($forward) { $_a = $forward->getAction(); - list($_c, $_m) = WindBase::resolveController($forward->getController()); + list($_c, $_m) = WindHelper::resolveController($forward->getController()); /* @var $_router WindUrlBasedRouter */ $_router = $this->windFactory->getInstance(COMPONENT_ROUTER); diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php index 52838ac4..fe6de0af 100644 --- a/wind/core/web/WindUrlHelper.php +++ b/wind/core/web/WindUrlHelper.php @@ -67,7 +67,7 @@ public function parseUrl() { */ public function createUrl($action, $controller, $params = array()) { $action && $this->getWindRouter()->setAction($action); - list($_c, $_m) = WindBase::resolveController($controller); + list($_c, $_m) = WindHelper::resolveController($controller); $_c && $this->getWindRouter()->setController($_c); $_m && $this->getWindRouter()->setModule($_m); $url = $this->getWindRouter()->buildUrl(); From 2b60500d988005a5710a204b7299c4686cd1d6ec Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 04:55:26 +0000 Subject: [PATCH 0024/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8Cupdate?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=8F=82=E6=95=B0=E8=AE=BE=E7=BD=AE=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E9=9C=80=E8=A6=81=E8=BF=94=E5=9B=9E=E5=8D=B0=E8=B1=A1?= =?UTF-8?q?=E8=A1=8C=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2063 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 77b030d6..903b8ae9 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -162,10 +162,11 @@ public function setColumns($columns) {} /** * 执行SQL语句,并返回更新影响行数 * @param array $params + * @param boolean $rowCount 是否返回影响行数 * @throws WindDbException */ - public function update($params = array()) { - return $this->execute($params); + public function update($params = array(), $rowCount = false) { + return $this->execute($params, $rowCount); } /** From 02365f544295e1ff4d7bab4a114de1a574615ee5 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 05:08:58 +0000 Subject: [PATCH 0025/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8Cupdate?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=8F=82=E6=95=B0=E8=AE=BE=E7=BD=AE=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E9=9C=80=E8=A6=81=E8=BF=94=E5=9B=9E=E5=8D=B0=E8=B1=A1?= =?UTF-8?q?=E8=A1=8C=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2064 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 53ede774..ff78c68b 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -56,10 +56,11 @@ public function columnCount() { /** * Fetches the next row from a result set + * @param int $fetchType * @return array */ - public function fetch() { - return $this->_fetch($this->_fetchMode, $this->_fetchType); + public function fetch($fetchMode = PDO::FETCH_BOTH) { + return $this->_fetch($fetchMode, $this->_fetchType); } /** @@ -81,6 +82,11 @@ private function _fetch($fetchMode, $fetchType) { } /** + * Some database servers support stored procedures that return more than one rowset + * (also known as a result set). PDOStatement::nextRowset() enables you to access the second + * and subsequent rowsets associated with a PDOStatement object. Each rowset can have a + * different set of columns from the preceding rowset. + * * @return boolean | 成功返回true失败返回false */ public function nextRowset() { @@ -89,14 +95,15 @@ public function nextRowset() { /** * 返回所有的查询结果 + * @param int $fetchType 设置返回的方式 * @return array */ - public function fetchAll($index = 0) { + public function fetchAll($fetchType = PDO::FETCH_BOTH) { if (empty($this->_columns)) - return $this->_statement->fetchAll(); + return $this->_statement->fetchAll($fetchType); else { $result = array(); - while ($row = $this->fetch()) { + while ($row = $this->fetch($fetchType)) { $result[] = $row; } return $result; @@ -104,8 +111,10 @@ public function fetchAll($index = 0) { } /** + * 从下一行记录中获得下标使$index的值,如果获取失败则返回false + * * @param int $index - * @return string + * @return string|bool */ public function fetchColumn($index = 0) { return $this->_statement->fetchColumn($index); From aa410e69b2082129c9cc322c8ecdbea2c7aaa485 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 05:10:07 +0000 Subject: [PATCH 0026/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8Cupdate?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=8F=82=E6=95=B0=E8=AE=BE=E7=BD=AE=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E9=9C=80=E8=A6=81=E8=BF=94=E5=9B=9E=E5=8D=B0=E8=B1=A1?= =?UTF-8?q?=E8=A1=8C=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2065 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index ff78c68b..07a441a9 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -41,6 +41,7 @@ public function setFetchMode($fetchMode) { /** * 返回最后一条Sql语句的影响行数 + * @return int */ public function rowCount() { return $this->_statement->rowCount(); From f95937053b795de8bd5d90d4da393619fbcae543 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 07:11:59 +0000 Subject: [PATCH 0027/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8Cupdate?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=8F=82=E6=95=B0=E8=AE=BE=E7=BD=AE=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E9=9C=80=E8=A6=81=E8=BF=94=E5=9B=9E=E5=8D=B0=E8=B1=A1?= =?UTF-8?q?=E8=A1=8C=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2066 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index f1c30ee2..5652c7bd 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -22,7 +22,7 @@ class WindLogger extends WindComponentModule { private $_logs = array(); private $_logCount = 0; private $_profiles = array(); - private $_logDir; + private $_logDir = COMPILE_PATH; private $_maxFileSize = 100; /** From 864f6bed32cae723a4dc2612a130034fdaba87a6 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 07:15:37 +0000 Subject: [PATCH 0028/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8Cupdate?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=8F=82=E6=95=B0=E8=AE=BE=E7=BD=AE=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E9=9C=80=E8=A6=81=E8=BF=94=E5=9B=9E=E5=8D=B0=E8=B1=A1?= =?UTF-8?q?=E8=A1=8C=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2067 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 903b8ae9..356af61b 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -194,7 +194,7 @@ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchT $rs = new WindResultSet($this, $fetchMode, $fetchType); if (!$index) return $rs->fetchAll(); $result = array(); - while ($one = $rs->fetch()) { + while ($one = $rs->fetch($fetchMode)) { isset($one[$index]) ? $result[$one[$index]] = $one : $result[] = $one; } return $result; @@ -223,7 +223,7 @@ public function getValue($params = array(), $column = 0) { public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { $this->execute($params, false); $rs = new WindResultSet($this, $fetchMode, $fetchType); - return $rs->fetch(); + return $rs->fetch($fetchMode); } /** From e14dedc4b7b77096fe9a23199c2264741e14e151 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 07:47:23 +0000 Subject: [PATCH 0029/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=8E=A5=E5=8F=A3lastinsertid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2068 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 356af61b..67652227 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -225,10 +225,18 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { $rs = new WindResultSet($this, $fetchMode, $fetchType); return $rs->fetch($fetchMode); } + + /** + * 返回插入的最后一个ID + * @return int + */ + public function lastInsertId() { + return $this->getConnection()->getDbHandle()->lastInsertId(); + } /** * 执行sql,$params为变量信息,并返回结果集 - * @param array $params -- 注意:绑定的变量数组下标将从0开始索引, + * @param array $params * @param boolean $rowCount * @return rowCount */ From 60457da37d5a8d509c10de4d1e83b084f45708b3 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 08:00:55 +0000 Subject: [PATCH 0030/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=8E=A5=E5=8F=A3=20errorInfo=E8=8E=B7=E5=BE=97?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2069 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 67652227..869a4fa6 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -233,6 +233,14 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { public function lastInsertId() { return $this->getConnection()->getDbHandle()->lastInsertId(); } + + /** + * 错误信息 + * @return array 返回错误代码和错误信息 + */ + public function errorInfo() { + return $this->getStatement()->errorInfo(); + } /** * 执行sql,$params为变量信息,并返回结果集 From 7ebe8cd1e5d3d397bcfe129bd2c31c90ca8e410d Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 09:27:37 +0000 Subject: [PATCH 0031/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2070 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 07a441a9..6026b808 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -60,8 +60,8 @@ public function columnCount() { * @param int $fetchType * @return array */ - public function fetch($fetchMode = PDO::FETCH_BOTH) { - return $this->_fetch($fetchMode, $this->_fetchType); + public function fetch($fetchMode = PDO::FETCH_BOTH, $fetchType = PDO::FETCH_ORI_FIRST) { + return $this->_fetch($fetchMode, $fetchType); } /** From bda859a1f720372c6fcc6c511d282a70f0540e3e Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 09:49:44 +0000 Subject: [PATCH 0032/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2071 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 869a4fa6..2fab8003 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -72,7 +72,7 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu * @param array $parameters * @return WindSqlStatement */ - public function bindParams($parameters) { + public function bindParams(&$parameters) { foreach ($parameters as $key => $value) { if (is_array($value)) { list($var) = $value; @@ -194,7 +194,7 @@ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchT $rs = new WindResultSet($this, $fetchMode, $fetchType); if (!$index) return $rs->fetchAll(); $result = array(); - while ($one = $rs->fetch($fetchMode)) { + while ($one = $rs->fetch()) { isset($one[$index]) ? $result[$one[$index]] = $one : $result[] = $one; } return $result; @@ -223,7 +223,7 @@ public function getValue($params = array(), $column = 0) { public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { $this->execute($params, false); $rs = new WindResultSet($this, $fetchMode, $fetchType); - return $rs->fetch($fetchMode); + return $rs->fetch(); } /** @@ -231,20 +231,12 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { * @return int */ public function lastInsertId() { - return $this->getConnection()->getDbHandle()->lastInsertId(); + return $this->getConnection()->lastInsertId(); } - /** - * 错误信息 - * @return array 返回错误代码和错误信息 - */ - public function errorInfo() { - return $this->getStatement()->errorInfo(); - } - /** * 执行sql,$params为变量信息,并返回结果集 - * @param array $params + * @param array $params -- 注意:绑定的变量数组下标将从0开始索引, * @param boolean $rowCount * @return rowCount */ @@ -252,7 +244,7 @@ public function execute($params = array(), $rowCount = true) { try { $this->init(); Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); - $this->bindParams($params); + $this->bindValues($params); $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); @@ -312,7 +304,6 @@ public function init() { try { Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. ", WindLogger::LEVEL_INFO, "component.db"); Wind::profileBegin("component.db.WindSqlStatement._init", " SQL: " . $this->getQueryString(), "component.db"); - $this->getConnection()->init(); $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString()); Wind::profileEnd('component.db.WindSqlStatement._init'); Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. This statement is " . get_class($this->_statement), WindLogger::LEVEL_DEBUG, "component.db"); From 7b37dc369475811a59763baa1eac6602627e84b6 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 09:51:07 +0000 Subject: [PATCH 0033/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A5=E5=8F=A3=20--=E5=BC=95=E7=94=A8=E4=BC=A0?= =?UTF-8?q?=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2072 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 2fab8003..3d2e56f9 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -73,9 +73,9 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu * @return WindSqlStatement */ public function bindParams(&$parameters) { - foreach ($parameters as $key => $value) { + foreach ($parameters as $key => &$value) { if (is_array($value)) { - list($var) = $value; + $var = &$value[0]; $dataType = isset($value[1]) ? $value[1] : null; $length = isset($value[2]) ? $value[2] : null; $driverOptions = isset($value[3]) ? $value[3] : null; @@ -244,7 +244,11 @@ public function execute($params = array(), $rowCount = true) { try { $this->init(); Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); +<<<<<<< .mine + $params && $this->bindParams($params); +======= $this->bindValues($params); +>>>>>>> .r2071 $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); From cd56dcd2d64f7e6f0efb6facfb5335ef371c43f2 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 09:53:50 +0000 Subject: [PATCH 0034/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A5=E5=8F=A3=20--=E5=BC=95=E7=94=A8=E4=BC=A0?= =?UTF-8?q?=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2073 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 3d2e56f9..4d798c6f 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -244,11 +244,7 @@ public function execute($params = array(), $rowCount = true) { try { $this->init(); Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); -<<<<<<< .mine - $params && $this->bindParams($params); -======= $this->bindValues($params); ->>>>>>> .r2071 $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); From 60d8e28a27c34ac824d113ceb98e4ddd9ca5f87d Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 09:58:23 +0000 Subject: [PATCH 0035/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2074 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDao.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php index 72c48360..e59fe1ab 100644 --- a/wind/component/dao/WindDao.php +++ b/wind/component/dao/WindDao.php @@ -1,5 +1,4 @@ setPath($this->dbClass); $definition->setScope(WindComponentDefinition::SCOPE_SINGLETON); $definition->setAlias($this->dbClass); + $definition->setInitMethod('init'); if (is_array($this->dbConfig)) $definition->setConfig($this->dbConfig); else From eae63f24c6db457b120e545f0ab1a59092e73eab Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 09:59:32 +0000 Subject: [PATCH 0036/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A5=E5=8F=A3=20--=E5=BC=95=E7=94=A8=E4=BC=A0?= =?UTF-8?q?=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2075 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 4d798c6f..7802e15a 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -231,7 +231,7 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { * @return int */ public function lastInsertId() { - return $this->getConnection()->lastInsertId(); + return $this->getConnection()->getDbHandle()->lastInsertId(); } /** From 0625961ff47bf070143f96404ee4e3be4ef2c44c Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 10:15:58 +0000 Subject: [PATCH 0037/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2076 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 36 ++++++++++++----------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 6026b808..987edb19 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -28,15 +28,19 @@ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { $this->_statement = $sqlStatement->getStatement(); $this->_columns = $sqlStatement->getColumns(); if ($fetchMode != 0) $this->_fetchMode = $fetchMode; + if ($fetchMode != 0) $this->_fetchType = $fetchType; } /** * @param $fetchMode * @return */ - public function setFetchMode($fetchMode) { - $fetchMode = func_get_args(); - call_user_func_array(array($this->_statement, 'setFetchMode'), $fetchMode); + public function setFetchMode($fetchMode, $push = false) { + $this->_fetchMode = $fetchMode; + if ($push) { + $fetchMode = func_get_args(); + call_user_func_array(array($this->_statement, 'setFetchMode'), $fetchMode); + } } /** @@ -57,10 +61,13 @@ public function columnCount() { /** * Fetches the next row from a result set + * @param int $fetchMode * @param int $fetchType * @return array */ - public function fetch($fetchMode = PDO::FETCH_BOTH, $fetchType = PDO::FETCH_ORI_FIRST) { + public function fetch($fetchMode = 0, $fetchType = 0) { + if ($fetchMode === 0) $fetchMode = $this->_fetchMode; + if ($fetchType === 0) $fetchMode = $this->_fetchType; return $this->_fetch($fetchMode, $fetchType); } @@ -82,38 +89,25 @@ private function _fetch($fetchMode, $fetchType) { return array(); } - /** - * Some database servers support stored procedures that return more than one rowset - * (also known as a result set). PDOStatement::nextRowset() enables you to access the second - * and subsequent rowsets associated with a PDOStatement object. Each rowset can have a - * different set of columns from the preceding rowset. - * - * @return boolean | 成功返回true失败返回false - */ - public function nextRowset() { - return $this->_statement->nextRowset(); - } - /** * 返回所有的查询结果 * @param int $fetchType 设置返回的方式 * @return array */ - public function fetchAll($fetchType = PDO::FETCH_BOTH) { + public function fetchAll($fetchMode = 0) { + if ($fetchMode === 0) $fetchMode = $this->_fetchMode; if (empty($this->_columns)) - return $this->_statement->fetchAll($fetchType); + return $this->_statement->fetchAll($fetchMode); else { $result = array(); - while ($row = $this->fetch($fetchType)) { + while ($row = $this->fetch($fetchMode)) $result[] = $row; - } return $result; } } /** * 从下一行记录中获得下标使$index的值,如果获取失败则返回false - * * @param int $index * @return string|bool */ From 6f180f6d700878647c18cf82d0e2ef7e830007a9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 10:18:14 +0000 Subject: [PATCH 0038/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2077 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 122 ++++++++++++--------------- 1 file changed, 56 insertions(+), 66 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 1ed4fa17..9bc582e1 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -11,7 +11,7 @@ class WindConnection extends WindComponentModule { const PWD = 'pwd'; const CHARSET = 'charset'; const ENABLELOG = 'enablelog'; - const DRIVER = 'driver'; + const TABLEPREFIX = 'tablePrefix'; /** * PDO 链接字符串 * @var string @@ -21,7 +21,7 @@ class WindConnection extends WindComponentModule { private $_user; private $_pwd; private $_tablePrefix; - private $_charset; + private $_charset = gbk; private $_enableLog = false; /** * @var array @@ -31,6 +31,7 @@ class WindConnection extends WindComponentModule { * @var PDO */ private $_dbHandle = null; + private $_filterArray = array(); /** * @param string $dsn @@ -38,9 +39,9 @@ class WindConnection extends WindComponentModule { * @param string $password */ public function __construct($dsn = '', $username = '', $password = '') { - $this->setDsn($dsn); - $this->setUser($username); - $this->setPwd($password); + $this->_dsn = $dsn; + $this->_user = $username; + $this->_pwd = $password; } /** @@ -66,8 +67,8 @@ public function getDbHandle() { * */ public function getAttribute($attribute = '') { if (!$attribute) return; - if ($this->getDbHandle() !== null) { - return $this->getDbHandle()->getAttribute($attribute); + if ($this->_dbHandle !== null) { + return $this->_dbHandle->getAttribute($attribute); } else return isset($this->_attributes[$attribute]) ? $this->_attributes[$attribute] : ''; } @@ -77,7 +78,7 @@ public function getAttribute($attribute = '') { * @param $value * @return * */ - public function setAttribute($attribute = '', $value = '') { + public function setAttribute($attribute, $value = null) { if (!$attribute) return; if ($this->_dbHandle !== null && $this->_dbHandle instanceof PDO) { $this->_dbHandle->setAttribute($attribute, $value); @@ -92,22 +93,13 @@ public function setAttribute($attribute = '', $value = '') { public function getDriverName() { if ($this->_driverName) return $this->_driverName; if ($this->_dbHandle !== null) { - $this->setDriverName($this->_dbHandle->getAttribute(PDO::ATTR_DRIVER_NAME)); - } elseif (($pos = strpos($this->getDsn(), ':')) !== false) { - $this->setDriverName(strtolower(substr($this->getDsn(), 0, $pos))); - } else { - $this->setDriverName($this->getConfig(self::DRIVER)); + $this->_driverName = $this->_dbHandle->getAttribute(PDO::ATTR_DRIVER_NAME); + } elseif (($pos = strpos($this->_dsn, ':')) !== false) { + $this->_driverName = strtolower(substr($this->_dsn, 0, $pos)); } return $this->_driverName; } - /** - * @param string $driverName - */ - public function setDriverName($driverName) { - $this->_driverName = $driverName; - } - /** * @return the $enableLog */ @@ -137,67 +129,57 @@ public function setTablePrefix($tablePrefix) { } /** - * @return the $charset - */ - public function getCharset() { - if ($this->_charset) return $this->_charset; - $this->setCharset($this->getConfig(self::CHARSET)); - return $this->_charset; - } - - /** - * @param string $charset - */ - public function setCharset($charset) { - $this->_charset = $charset; - } - - /** - * @return the $_dsn + * @param string $sql | SQL statement + * @return row count */ - public function getDsn() { - if ($this->_dsn) return $this->_dsn; - $this->setDsn($this->getConfig(self::DSN)); - return $this->_dsn; + public function execute($sql) { + try { + return $this->getDbHandle()->exec($sql); + } catch (PDOException $e) { + $this->close(); + Wind::log('component.db.WindConnection.excute.', WindLogger::LEVEL_TRACE, 'component.db'); + throw new WindDbException($e->getMessage()); + } } /** - * @param string $dsn + * @param string $sql | SQL statement + * @return PDOStatement */ - public function setDsn($dsn) { - $this->_dsn = $dsn; + public function query($sql) { + return $this->getDbHandle()->query($sql); } /** - * @return the $_user + * 返回最后一条插入数据ID + * @param $name */ - public function getUser() { - if ($this->_user) return $this->_user; - $this->_user = $this->getConfig(self::USER); - return $this->_user; + public function lastInsterId($name = '') { + if ($name) + return $this->getDbHandle()->lastInsertId($name); + else + return $this->getDbHandle()->lastInsertId(); } /** - * @param string $userName + * @param array $array */ - public function setUser($userName) { - $this->_user = $userName; + public function quoteArray($array) { + return $this->getDbHandle()->filterArray($array); } /** - * @return the $_pwd + * @param string $string */ - public function getPwd() { - if ($this->_pwd) return $this->_pwd; - $this->setPwd($this->getConfig(self::PWD)); - return $this->_pwd; + public function quote($string) { + return $this->getDbHandle()->quote($string); } /** - * @param string $_pwd + * 关闭数据库连接 */ - public function setPwd($_pwd) { - $this->_pwd = $_pwd; + public function close() { + $this->_dbHandle = null; } /** @@ -218,19 +200,27 @@ public function init() { if (!$dbHandleClass) { throw new WindDbException('The db handle class path \'' . $dbHandleClass . '\' is not exist.'); } - $this->_dbHandle = new $dbHandleClass($this->getDsn(), $this->getUser(), $this->getPwd(), (array) $this->_attributes); + $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->_dbHandle->setCharset($this->getCharset()); - Wind::log("component.db.WindConnection._init() \r\n dsn: " . $this->getDsn() . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, WindLogger::LEVEL_DEBUG); + $this->_dbHandle->setCharset($this->_charset); + Wind::log("component.db.WindConnection._init() \r\n dsn: " . $this->_dsn() . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, WindLogger::LEVEL_DEBUG); } catch (PDOException $e) { - Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", WindLogger::LEVEL_TRACE); $this->close(); + Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", WindLogger::LEVEL_TRACE); throw new WindDbException($e->getMessage()); } } - public function close() { - $this->_dbHandle = null; + /* (non-PHPdoc) + * @see WindComponentModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + if (!$this->_dsn) $this->_dsn = $this->getConfig(self::DSN, '', $this->_dsn); + if (!$this->_user) $this->_user = $this->getConfig(self::USER, '', $this->_user); + if (!$this->_pwd) $this->_pwd = $this->getConfig(self::PWD, '', $this->_pwd); + if (!$this->_enableLog) $this->_enableLog = $this->getConfig(self::ENABLELOG, '', $this->_enableLog); + if (!$this->_charset) $this->_charset = $this->getConfig(self::CHARSET, '', $this->_charset); } } ?> \ No newline at end of file From 4b19638e98cd9bbbddc49ddd4298fac15e997459 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 10:18:24 +0000 Subject: [PATCH 0039/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2078 18ba2127-5a84-46d4-baec-3457e417f034 --- .../db/mysql/WindMysqlPdoAdapter.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/wind/component/db/mysql/WindMysqlPdoAdapter.php b/wind/component/db/mysql/WindMysqlPdoAdapter.php index b4b1b27d..e0e0de7e 100644 --- a/wind/component/db/mysql/WindMysqlPdoAdapter.php +++ b/wind/component/db/mysql/WindMysqlPdoAdapter.php @@ -11,5 +11,30 @@ public function setCharset($charset) { if (!$charset) $charset = 'gbk'; $this->query("set names " . $this->quote($charset) . ";"); } + + /** + * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组 + * example: + * array('a','b','c') => ('a','b','c') + * array(array('a1','b1','c1'),array('a2','b2','c2')) + * => ('a1','b1','c1'),('a2','b2','c2') + * @param array $variable + * @param string $result + */ + public function filterArray($variable, $result = '') { + if (empty($variable) || !is_array($variable)) return; + $_result = ''; + foreach ($variable as $key => $value) { + if (is_array($value)) + $result = $this->filterArray($value, $result); + else { + $_result .= $this->quote($value) . ','; + } + } + if ($_result) { + $result .= $result ? ',(' . trim($_result, ',') . ')' : '(' . trim($_result, ',') . ')'; + } + return $result; + } } ?> \ No newline at end of file From 8916c1e625aee76203d42a2c5355fcaf15aeb98a Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 10:24:44 +0000 Subject: [PATCH 0040/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2079 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index 5652c7bd..f1c30ee2 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -22,7 +22,7 @@ class WindLogger extends WindComponentModule { private $_logs = array(); private $_logCount = 0; private $_profiles = array(); - private $_logDir = COMPILE_PATH; + private $_logDir; private $_maxFileSize = 100; /** From 84f3332407d58d857f3f04fc18243b9d5e53d5cd Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 10:27:21 +0000 Subject: [PATCH 0041/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2080 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindComponentModule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php index a81c8bab..d013f5bc 100644 --- a/wind/core/WindComponentModule.php +++ b/wind/core/WindComponentModule.php @@ -65,7 +65,7 @@ public function setAttribute($alias, $object = null) { */ public function getConfig($configName = '', $subConfigName = '', $default = '') { if (null === $this->_config) return ''; - return $this->_config->getConfig($configName, $subConfigName, $default); + return $this->_config->getConfig($configName, $subConfigName, array(), $default); } /** From a2b82042e43d28e424eb117b657b7f42fd46dc14 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 10:27:57 +0000 Subject: [PATCH 0042/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2081 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindErrorHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php index b9f16822..2e01a67e 100644 --- a/wind/core/web/WindErrorHandler.php +++ b/wind/core/web/WindErrorHandler.php @@ -125,7 +125,7 @@ private function errnoMap($errno) { */ final public function exceptionHandle($exception) { $_tmp = $exception->getMessage() . ' (' . $this->getFile($exception->getFile()) . ':' . $exception->getLine() . ')'; - if (IS_DEBUG) { + if (IS_DEBUG > WindLogger::LEVEL_DEBUG) { echo '

' . get_class($exception) . '

'; echo "

$_tmp

"; echo '
' . $exception->getTraceAsString() . '
'; From 7b897ed2b015d6004b4e92801923c1952b2ed1d1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 10:28:31 +0000 Subject: [PATCH 0043/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2082 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindFrontController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index a347c5d2..7a8ced70 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -100,7 +100,7 @@ private function getFilterChain() { */ protected function beforeProcess(WindHttpRequest $request, WindHttpResponse $response) { Wind::import('WIND:core.web.WindErrorHandler'); - set_error_handler(array(new WindErrorHandler(), 'errorHandle')); + set_error_handler(array(new WindErrorHandler(), 'errorHandle'), error_reporting()); set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); } From 35f04d94624d406eee3c316766e9eb3c765dab86 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 10:44:35 +0000 Subject: [PATCH 0044/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A5=E5=8F=A3=20bug=E8=B0=83=E6=95=B4=E5=8E=BB?= =?UTF-8?q?=E9=99=A4=E9=BB=98=E8=AE=A4=E7=9A=84charset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2083 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 9bc582e1..cd8c7571 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -21,7 +21,7 @@ class WindConnection extends WindComponentModule { private $_user; private $_pwd; private $_tablePrefix; - private $_charset = gbk; + private $_charset; private $_enableLog = false; /** * @var array From cc65a71e8d0d5c7fc70b2cea70818fe71975833a Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 10:46:07 +0000 Subject: [PATCH 0045/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E6=8E=A5=E5=8F=A3=20bug=E8=B0=83=E6=95=B4=E5=8E=BB?= =?UTF-8?q?=E9=99=A4=E9=BB=98=E8=AE=A4=E7=9A=84charset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2084 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 7802e15a..e59f90df 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -192,9 +192,9 @@ public function query($params = array(), $fetchMode = 0, $fetchType = 0) { public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) { $this->execute($params, false); $rs = new WindResultSet($this, $fetchMode, $fetchType); - if (!$index) return $rs->fetchAll(); + if (!$index) return $rs->fetchAll($fetchMode); $result = array(); - while ($one = $rs->fetch()) { + while ($one = $rs->fetch($fetchMode, $fetchType)) { isset($one[$index]) ? $result[$one[$index]] = $one : $result[] = $one; } return $result; @@ -231,7 +231,7 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { * @return int */ public function lastInsertId() { - return $this->getConnection()->getDbHandle()->lastInsertId(); + return $this->getConnection()->lastInsertId(); } /** From 44050c98863eaf9995baa69f6639e559285a62ed Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 11:10:16 +0000 Subject: [PATCH 0046/1065] WindLogger git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2085 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 75 +++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index f1c30ee2..cb1308db 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -14,6 +14,9 @@ class WindLogger extends WindComponentModule { const LEVEL_PROFILE = 5; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; + const WRITE_ALL = 0; + const WRITE_LEVEL = 1; + const WRITE_TYPE = 2; /** * 每次当日志数量达到100的时候,就写入文件一次 * @var int @@ -24,6 +27,17 @@ class WindLogger extends WindComponentModule { private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; + private $_writeType = '0'; //0只按照log记录打印全部结果,1并且按照level打印结果,2并且按照type打印结果 + private $_types = array(); + + /** + * @param string $logDir + * @param int $writeType + */ + public function __construct($logDir = '', $writeType = 0) { + $this->_logDir = $logDir; + $this->_writeType = $writeType; + } /** * 添加info级别的日志信息 @@ -79,14 +93,19 @@ public function profileEnd($msg, $type = 'wind.core') { * @param const $logType 日志类别 */ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { - $this->_logCount >= $this->_autoFlush && $this->flush(); + if ($this->_writeType == self::WRITE_TYPE) + (count($this->_types[$type]) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); + else + $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) - $this->_logs[] = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); + $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) - $this->_logs[] = $this->_build($msg, $level, $type, microtime(true)); + $message = $this->_build($msg, $level, $type, microtime(true)); else - $this->_logs[] = $this->_build($msg, $level, $type); + $message = $this->_build($msg, $level, $type); + $this->_logs[] = array($level, $type, $message); $this->_logCount++; + if ($this->_writeType == self::WRITE_TYPE) $this->_types[$type] = isset($this->_types[$type]) ? count($this->_types[$type]) + 1 : 1; } /** @@ -96,9 +115,48 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { */ public function flush() { if (empty($this->_logs)) return false; - if (!$fileName = $this->_getFileName()) return false; Wind::import('WIND:component.utility.WindFile'); - WindFile::write($fileName, join("", $this->_logs), 'a'); + if ($this->_writeType == self::WRITE_LEVEL) { + $_logs = array(); + foreach ($this->_logs as $key => $value) { + $_logs[$value[0]][] = $value[2]; + } + foreach ($_logs as $key => $value) { + switch ($key) { + case self::LEVEL_INFO: + $key = 'info'; + break; + case self::LEVEL_ERROR: + $key = 'error'; + break; + case self::LEVEL_DEBUG: + $key = 'debug'; + break; + case self::LEVEL_TRACE: + $key = 'trace'; + break; + case self::LEVEL_PROFILE: + $key = 'profile'; + break; + default: + $key = 'all'; + break; + } + if (!$fileName = $this->_getFileName($key)) continue; + WindFile::write($fileName, join("", $value), 'a'); + } + } elseif ($this->_writeType == self::WRITE_TYPE) { + $_logs = array(); + foreach ($this->_logs as $key => $value) { + $_logs[$value[1]][] = $value[2]; + } + foreach ($_logs as $key => $value) { + if (!$fileName = $this->_getFileName($key)) continue; + WindFile::write($fileName, join("", $value), 'a'); + } + } else { + if ($fileName = $this->_getFileName()) WindFile::write($fileName, join("", $this->_logs), 'a'); + } $this->_logs = array(); $this->_logCount = 0; return true; @@ -289,9 +347,9 @@ private function _buildArg($arg) { * 取得日志文件名 * @return string */ - private function _getFileName() { + private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; - $_logfile = $this->_logDir . '/log.txt'; + $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix . '_' : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { @@ -320,6 +378,7 @@ public function setLogDir($logDir) { public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } + } \ No newline at end of file From c0253466767d13bb512d2930b9d67d5a91c9764e Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 11:11:01 +0000 Subject: [PATCH 0047/1065] WindLogger git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2086 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index f554839d..14f1def2 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -243,8 +243,7 @@ public static function profileEnd($token, $message = '', $type = 'wend.core') { */ public static function getLogger() { if (self::$_logger === null) { - self::$_logger = new WindLogger(); - self::$_logger->setLogDir(COMPILE_PATH . '/log/'); + self::$_logger = new WindLogger(COMPILE_PATH . '/log/' , WindLogger::WRITE_LEVEL); } return self::$_logger; } From a4f5473001d639f41d6b1c246086c1dad6bc4f3d Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 11:22:44 +0000 Subject: [PATCH 0048/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2087 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index e59f90df..a0891ab0 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -192,9 +192,9 @@ public function query($params = array(), $fetchMode = 0, $fetchType = 0) { public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) { $this->execute($params, false); $rs = new WindResultSet($this, $fetchMode, $fetchType); - if (!$index) return $rs->fetchAll($fetchMode); + if (!$index) return $rs->fetchAll(); $result = array(); - while ($one = $rs->fetch($fetchMode, $fetchType)) { + while ($one = $rs->fetch()) { isset($one[$index]) ? $result[$one[$index]] = $one : $result[] = $one; } return $result; @@ -225,15 +225,18 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { $rs = new WindResultSet($this, $fetchMode, $fetchType); return $rs->fetch(); } - + /** - * 返回插入的最后一个ID - * @return int + * 返回最后一条插入数据ID + * @param $name */ - public function lastInsertId() { - return $this->getConnection()->lastInsertId(); + public function lastInsterId($name = '') { + if ($name) + return $this->getDbHandle()->lastInsertId($name); + else + return $this->getDbHandle()->lastInsertId(); } - + /** * 执行sql,$params为变量信息,并返回结果集 * @param array $params -- 注意:绑定的变量数组下标将从0开始索引, From afb147db136b73c1224c1e8c78b696ea0992c4e5 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 11:23:08 +0000 Subject: [PATCH 0049/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2088 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index cd8c7571..3e22fc75 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -150,17 +150,6 @@ public function query($sql) { return $this->getDbHandle()->query($sql); } - /** - * 返回最后一条插入数据ID - * @param $name - */ - public function lastInsterId($name = '') { - if ($name) - return $this->getDbHandle()->lastInsertId($name); - else - return $this->getDbHandle()->lastInsertId(); - } - /** * @param array $array */ From c85cc4db0fbbe5530f0f7fde1d082d5b032285e6 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 11:25:13 +0000 Subject: [PATCH 0050/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2089 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index a0891ab0..312635a6 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -73,15 +73,14 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu * @return WindSqlStatement */ public function bindParams(&$parameters) { - foreach ($parameters as $key => &$value) { + foreach ($parameters as $key => $value) { if (is_array($value)) { - $var = &$value[0]; $dataType = isset($value[1]) ? $value[1] : null; $length = isset($value[2]) ? $value[2] : null; $driverOptions = isset($value[3]) ? $value[3] : null; - $this->bindParam($key, $var, $dataType, $length, $driverOptions); + $this->bindParam($key, $parameters[$key][0], $dataType, $length, $driverOptions); } else { - $this->bindParam($key, $value, $this->_getPdoDataType($value)); + $this->bindParam($key, $parameters[$key], $this->_getPdoDataType($value)); } } return $this; From 20b7ea29587e6bdaebd3b9fd3fbea54b2ca51237 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 30 Jun 2011 11:41:11 +0000 Subject: [PATCH 0051/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2090 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 7 ++++++- wind/component/db/WindResultSet.php | 11 +++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 3e22fc75..9e7e16af 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -147,7 +147,12 @@ public function execute($sql) { * @return PDOStatement */ public function query($sql) { - return $this->getDbHandle()->query($sql); + try { + $statement = $this->getDbHandle()->query($sql); + return new WindResultSet($statement); + } catch (PDOException $e) { + throw new WindDbException(); + } } /** diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 987edb19..3f859819 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -25,8 +25,11 @@ class WindResultSet { * @param WindSqlStatement $sqlStatement */ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { - $this->_statement = $sqlStatement->getStatement(); - $this->_columns = $sqlStatement->getColumns(); + if ($sqlStatement instanceof WindSqlStatement) { + $this->_statement = $sqlStatement->getStatement(); + $this->_columns = $sqlStatement->getColumns(); + } else + $this->_statement = $sqlStatement; if ($fetchMode != 0) $this->_fetchMode = $fetchMode; if ($fetchMode != 0) $this->_fetchType = $fetchType; } @@ -35,9 +38,9 @@ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { * @param $fetchMode * @return */ - public function setFetchMode($fetchMode, $push = false) { + public function setFetchMode($fetchMode, $flush = false) { $this->_fetchMode = $fetchMode; - if ($push) { + if ($flush) { $fetchMode = func_get_args(); call_user_func_array(array($this->_statement, 'setFetchMode'), $fetchMode); } From d3367d5b7858ed71b0fd592bc53f6f9856e99441 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 11:47:27 +0000 Subject: [PATCH 0052/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E8=B0=83=E6=95=B4=EF=BC=8Clogger=E7=9A=84=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E7=BB=9F=E4=B8=80=E4=B8=BAwind::logger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2091 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 8796bde7..6b363b26 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -31,8 +31,10 @@ public function processRequest() { //add log if (IS_DEBUG) { /* @var $logger WindLogger */ - $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); - $logger->debug('do processRequest of ' . get_class($this)); + //TODO 调试信息输出调用Wind::log + Wind::log('do processRequest of ' . get_class($this), WindLogger::LEVEL_DEBUG, 'wind.debug'); +// $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); +// $logger->debug('do processRequest of ' . get_class($this)); } $handler = $this->getHandler(); @@ -59,8 +61,10 @@ public function doDispatch($forward) { //add log if (IS_DEBUG) { /* @var $logger WindLogger */ - $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); - $logger->info('do doDispatch of ' . get_class($this)); + //TODO 调试信息 + Wind::log('do doDispatch of ' . get_class($this), WindLogger::LEVEL_DEBUG, 'wind.debug'); +// $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); +// $logger->info('do doDispatch of ' . get_class($this)); } $this->dispatcher->dispatch($forward); @@ -78,8 +82,10 @@ protected function getHandler() { //add log if (IS_DEBUG) { /* @var $logger WindLogger */ - $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); - $logger->debug('router result: Action:' . $handlerAdapter->getAction() . ' Controller:' . $handlerAdapter->getController() . ' Module:' . $handlerAdapter->getModule()); + //TODO 调试信息输出调用Wind::log + Wind::log('router result: Action:' . $handlerAdapter->getAction() . ' Controller:' . $handlerAdapter->getController() . ' Module:' . $handlerAdapter->getModule(), WindLogger::LEVEL_DEBUG, 'wind.debug'); +// $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); +// $logger->debug('router result: Action:' . $handlerAdapter->getAction() . ' Controller:' . $handlerAdapter->getController() . ' Module:' . $handlerAdapter->getModule()); } if (!strcasecmp($handlerAdapter->getController(), WIND_M_ERROR)) { @@ -119,8 +125,10 @@ protected function getHandler() { //add log if (IS_DEBUG) { /* @var $logger WindLogger */ - $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); - $logger->debug('ActionHandler: ' . $handler); + //TODO 调试信息输出调用Wind::log + Wind::log('ActionHandler: ', WindLogger::LEVEL_DEBUG, 'wind.debug'); +// $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); +// $logger->debug('ActionHandler: ' . $handler); } return $actionHandler; From 51875661d57c93493367743f9f9d5476c483678c Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 30 Jun 2011 11:47:52 +0000 Subject: [PATCH 0053/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E8=B0=83=E6=95=B4=EF=BC=8Clogger=E7=9A=84=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E7=BB=9F=E4=B8=80=E4=B8=BAwind::logger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2092 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/router/WindUrlBasedRouter.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wind/core/router/WindUrlBasedRouter.php b/wind/core/router/WindUrlBasedRouter.php index f069f0ce..44cd4c12 100644 --- a/wind/core/router/WindUrlBasedRouter.php +++ b/wind/core/router/WindUrlBasedRouter.php @@ -60,8 +60,10 @@ public function getHandler() { //add log if (IS_DEBUG) { /* @var $logger WindLogger */ - $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); - $logger->debug('do getHandler of ' . __CLASS__); + //TODO 调试信息的输出 + Wind::log('do getHandler of ' . __CLASS__, WindLogger::LEVEL_DEBUG, 'wind.debug'); + // $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); + // $logger->debug('do getHandler of ' . __CLASS__); } return $_path; From e03e2abaf3617841b3b673eeb37a36fd7e3c6962 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 1 Jul 2011 03:55:28 +0000 Subject: [PATCH 0054/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2093 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 88 +++++++-------------------------------------------- 1 file changed, 11 insertions(+), 77 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 14f1def2..2ffed626 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -2,13 +2,16 @@ /* 框架版本信息 */ define('VERSION', '0.5'); define('PHPVERSION', '5.1.2'); -!defined('IS_DEBUG') && define('IS_DEBUG', 1); -!defined('DEBUG_TIME') && define('DEBUG_TIME', microtime(true)); /* 路径相关配置信息 */ !defined('D_S') && define('D_S', DIRECTORY_SEPARATOR); !defined('WIND_PATH') && define('WIND_PATH', dirname(__FILE__) . D_S); !defined('COMPILE_PATH') && define('COMPILE_PATH', WIND_PATH . D_S); !defined('COMPILE_LIBRARY_PATH') && define('COMPILE_LIBRARY_PATH', WIND_PATH . 'windBasic.php'); +/* debug/log */ +!defined('IS_DEBUG') && define('IS_DEBUG', 1); +!defined('DEBUG_TIME') && define('DEBUG_TIME', microtime(true)); +!defined('LOG_DIR') && define('LOG_DIR', COMPILE_PATH . 'log' . D_S); +!defined('LOG_WRITE_LEVEL') && define('LOG_WRITE_LEVEL', 1); /** * the last known user to change this file in the repository <$LastChangedBy: yishuo $> * @author Qiong Wu @@ -186,9 +189,7 @@ public static function perLoadCoreLibrary($libPath) { $fileList = array(); foreach (self::$_imports as $key => $value) { $_key = self::getRealPath($key . '.' . self::$_extensions); - $fileList[$_key] = array( - $key, - $value); + $fileList[$_key] = array($key, $value); } $pack->packFromFileList($fileList, $libPath, WindPack::STRIP_PHP, true); } @@ -219,7 +220,7 @@ public static function log($message, $level = WindLogger::LEVEL_INFO, $type = 'w * @param $type */ public static function profileBegin($token, $message = '', $type = 'wind.core') { - if (IS_DEBUG && IS_DEBUG >= WindLogger::LEVEL_PROFILE) { + if (IS_DEBUG && WindLogger::LEVEL_PROFILE >= IS_DEBUG) { $msg = $token . ':' . $message; self::getLogger()->profileBegin($msg, $type); } @@ -231,7 +232,7 @@ public static function profileBegin($token, $message = '', $type = 'wind.core') * @param $type */ public static function profileEnd($token, $message = '', $type = 'wend.core') { - if (IS_DEBUG && IS_DEBUG >= WindLogger::LEVEL_PROFILE) { + if (IS_DEBUG && WindLogger::LEVEL_PROFILE >= IS_DEBUG) { $msg = $token . ':' . $message; self::getLogger()->profileEnd($msg, $type); } @@ -243,11 +244,11 @@ public static function profileEnd($token, $message = '', $type = 'wend.core') { */ public static function getLogger() { if (self::$_logger === null) { - self::$_logger = new WindLogger(COMPILE_PATH . '/log/' , WindLogger::WRITE_LEVEL); + self::$_logger = new WindLogger(LOG_DIR, LOG_WRITE_LEVEL); } return self::$_logger; } - + /** * 系统命名空间注册方法 * @return @@ -335,74 +336,7 @@ private static function _checkPhpVersion() { * @return */ private static function _coreLib() { - return array( - 'AbstractWindServer' => 'WIND:core.AbstractWindServer', - 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', - 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', - 'WindConfig' => 'WIND:core.config.WindConfig', - 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', - 'WindDaoCacheListener' => 'WIND:core.dao.listener.WindDaoCacheListener', - 'WindActionException' => 'WIND:core.exception.WindActionException', - 'WindCacheException' => 'WIND:core.exception.WindCacheException', - 'WindDaoException' => 'WIND:core.exception.WindDaoException', - 'WindException' => 'WIND:core.exception.WindException', - 'WindFinalException' => 'WIND:core.exception.WindFinalException', - 'WindSqlException' => 'WIND:core.exception.WindSqlException', - 'WindViewException' => 'WIND:core.exception.WindViewException', - 'IWindFactory' => 'WIND:core.factory.IWindFactory', - 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', - 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', - 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', - 'WindComponentDefinition' => 'WIND:core.factory.WindComponentDefinition', - 'WindComponentFactory' => 'WIND:core.factory.WindComponentFactory', - 'WindFactory' => 'WIND:core.factory.WindFactory', - 'WindFilter' => 'WIND:core.filter.WindFilter', - 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', - 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', - 'IWindRequest' => 'WIND:core.request.IWindRequest', - 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', - 'IWindResponse' => 'WIND:core.response.IWindResponse', - 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', - 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', - 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', - 'AbstractWindTemplateCompiler' => 'WIND:core.viewer.AbstractWindTemplateCompiler', - 'AbstractWindViewTemplate' => 'WIND:core.viewer.AbstractWindViewTemplate', - 'WindTemplateCompilerAction' => 'WIND:core.viewer.compiler.WindTemplateCompilerAction', - 'WindTemplateCompilerComponent' => 'WIND:core.viewer.compiler.WindTemplateCompilerComponent', - 'WindTemplateCompilerEcho' => 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', - 'WindTemplateCompilerInternal' => 'WIND:core.viewer.compiler.WindTemplateCompilerInternal', - 'WindTemplateCompilerPage' => 'WIND:core.viewer.compiler.WindTemplateCompilerPage', - 'WindTemplateCompilerScript' => 'WIND:core.viewer.compiler.WindTemplateCompilerScript', - 'WindTemplateCompilerTemplate' => 'WIND:core.viewer.compiler.WindTemplateCompilerTemplate', - 'WindViewTemplate' => 'WIND:core.viewer.compiler.WindViewTemplate', - 'IWindViewerResolver' => 'WIND:core.viewer.IWindViewerResolver', - 'WindViewCacheListener' => 'WIND:core.viewer.listener.WindViewCacheListener', - 'WindLayout' => 'WIND:core.viewer.WindLayout', - 'WindView' => 'WIND:core.viewer.WindView', - 'WindViewerResolver' => 'WIND:core.viewer.WindViewerResolver', - 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', - 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', - 'IWindApplication' => 'WIND:core.web.IWindApplication', - 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', - 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', - 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', - 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', - 'WindAction' => 'WIND:core.web.WindAction', - 'WindController' => 'WIND:core.web.WindController', - 'WindDispatcher' => 'WIND:core.web.WindDispatcher', - 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', - 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', - 'WindFormController' => 'WIND:core.web.WindFormController', - 'WindForward' => 'WIND:core.web.WindForward', - 'WindFrontController' => 'WIND:core.web.WindFrontController', - 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', - 'WindWebApplication' => 'WIND:core.web.WindWebApplication', - 'WindComponentModule' => 'WIND:core.WindComponentModule', - 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', - 'WindHelper' => 'WIND:core.WindHelper', - 'WindModule' => 'WIND:core.WindModule', - 'WindLogger' => 'COM:log.WindLogger'); + return array('AbstractWindServer' => 'WIND:core.AbstractWindServer', 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', 'WindConfig' => 'WIND:core.config.WindConfig', 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', 'WindDaoCacheListener' => 'WIND:core.dao.listener.WindDaoCacheListener', 'WindActionException' => 'WIND:core.exception.WindActionException', 'WindCacheException' => 'WIND:core.exception.WindCacheException', 'WindDaoException' => 'WIND:core.exception.WindDaoException', 'WindException' => 'WIND:core.exception.WindException', 'WindFinalException' => 'WIND:core.exception.WindFinalException', 'WindSqlException' => 'WIND:core.exception.WindSqlException', 'WindViewException' => 'WIND:core.exception.WindViewException', 'IWindFactory' => 'WIND:core.factory.IWindFactory', 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', 'WindComponentDefinition' => 'WIND:core.factory.WindComponentDefinition', 'WindComponentFactory' => 'WIND:core.factory.WindComponentFactory', 'WindFactory' => 'WIND:core.factory.WindFactory', 'WindFilter' => 'WIND:core.filter.WindFilter', 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', 'IWindRequest' => 'WIND:core.request.IWindRequest', 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', 'IWindResponse' => 'WIND:core.response.IWindResponse', 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', 'AbstractWindTemplateCompiler' => 'WIND:core.viewer.AbstractWindTemplateCompiler', 'AbstractWindViewTemplate' => 'WIND:core.viewer.AbstractWindViewTemplate', 'WindTemplateCompilerAction' => 'WIND:core.viewer.compiler.WindTemplateCompilerAction', 'WindTemplateCompilerComponent' => 'WIND:core.viewer.compiler.WindTemplateCompilerComponent', 'WindTemplateCompilerEcho' => 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', 'WindTemplateCompilerInternal' => 'WIND:core.viewer.compiler.WindTemplateCompilerInternal', 'WindTemplateCompilerPage' => 'WIND:core.viewer.compiler.WindTemplateCompilerPage', 'WindTemplateCompilerScript' => 'WIND:core.viewer.compiler.WindTemplateCompilerScript', 'WindTemplateCompilerTemplate' => 'WIND:core.viewer.compiler.WindTemplateCompilerTemplate', 'WindViewTemplate' => 'WIND:core.viewer.compiler.WindViewTemplate', 'IWindViewerResolver' => 'WIND:core.viewer.IWindViewerResolver', 'WindViewCacheListener' => 'WIND:core.viewer.listener.WindViewCacheListener', 'WindLayout' => 'WIND:core.viewer.WindLayout', 'WindView' => 'WIND:core.viewer.WindView', 'WindViewerResolver' => 'WIND:core.viewer.WindViewerResolver', 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', 'IWindApplication' => 'WIND:core.web.IWindApplication', 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', 'WindAction' => 'WIND:core.web.WindAction', 'WindController' => 'WIND:core.web.WindController', 'WindDispatcher' => 'WIND:core.web.WindDispatcher', 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', 'WindFormController' => 'WIND:core.web.WindFormController', 'WindForward' => 'WIND:core.web.WindForward', 'WindFrontController' => 'WIND:core.web.WindFrontController', 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', 'WindWebApplication' => 'WIND:core.web.WindWebApplication', 'WindComponentModule' => 'WIND:core.WindComponentModule', 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', 'WindHelper' => 'WIND:core.WindHelper', 'WindModule' => 'WIND:core.WindModule', 'WindLogger' => 'COM:log.WindLogger'); } } Wind::init(); From 1dc131833a2ba847092d14ec0d6061892bc6ab4a Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 1 Jul 2011 03:55:35 +0000 Subject: [PATCH 0055/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2094 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 312635a6..033fffb9 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -244,12 +244,13 @@ public function lastInsterId($name = '') { */ public function execute($params = array(), $rowCount = true) { try { - $this->init(); Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); + $this->init(); $this->bindValues($params); $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); + Wind::profileEnd('component.db.WindSqlStatement._init'); return $_result; } catch (PDOException $e) { Wind::log("component.db.WindSqlStatement.execute throw exception,exception message: " . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); @@ -307,7 +308,6 @@ public function init() { Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. ", WindLogger::LEVEL_INFO, "component.db"); Wind::profileBegin("component.db.WindSqlStatement._init", " SQL: " . $this->getQueryString(), "component.db"); $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString()); - Wind::profileEnd('component.db.WindSqlStatement._init'); Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. This statement is " . get_class($this->_statement), WindLogger::LEVEL_DEBUG, "component.db"); } catch (PDOException $e) { Wind::log("Component.db.WindSqlStatement._init Initialize DBStatement From 2328658019144bec237f35d48fe2193026f3ae6f Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 1 Jul 2011 03:55:41 +0000 Subject: [PATCH 0056/1065] WindLogger git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2095 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index cb1308db..d59ec8bb 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -27,7 +27,13 @@ class WindLogger extends WindComponentModule { private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; - private $_writeType = '0'; //0只按照log记录打印全部结果,1并且按照level打印结果,2并且按照type打印结果 + /** + * 0: 打印全部日志信息结果 + * 1: 按照level分文件存储日志记录 + * 2: 按照type分文件存储日志记录 + * @var int + */ + private $_writeType = '0'; private $_types = array(); /** @@ -94,7 +100,7 @@ public function profileEnd($msg, $type = 'wind.core') { */ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { if ($this->_writeType == self::WRITE_TYPE) - (count($this->_types[$type]) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); + (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) @@ -105,7 +111,9 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; - if ($this->_writeType == self::WRITE_TYPE) $this->_types[$type] = isset($this->_types[$type]) ? count($this->_types[$type]) + 1 : 1; + if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { + $this->_types[] = $type; + } } /** @@ -116,9 +124,11 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); + $_l = array(); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { + $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { @@ -148,14 +158,16 @@ public function flush() { } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { + $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } - } else { - if ($fileName = $this->_getFileName()) WindFile::write($fileName, join("", $this->_logs), 'a'); + } + if ($fileName = $this->_getFileName()) { + WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; @@ -349,7 +361,7 @@ private function _buildArg($arg) { */ private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; - $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix . '_' : '') . '.txt'; + $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { @@ -378,7 +390,6 @@ public function setLogDir($logDir) { public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } - } \ No newline at end of file From b4488a9f8e5dbc21ee7f10f9af4b2f9490c8e1e0 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 1 Jul 2011 05:40:18 +0000 Subject: [PATCH 0057/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=EF=BC=8C=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E8=B0=83=E6=95=B4=EF=BC=8C=E8=A1=A8=E5=89=8D=E7=BC=80?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2096 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 1 + wind/component/db/WindSqlStatement.php | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 9e7e16af..ba72609a 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -215,6 +215,7 @@ public function setConfig($config) { if (!$this->_pwd) $this->_pwd = $this->getConfig(self::PWD, '', $this->_pwd); if (!$this->_enableLog) $this->_enableLog = $this->getConfig(self::ENABLELOG, '', $this->_enableLog); if (!$this->_charset) $this->_charset = $this->getConfig(self::CHARSET, '', $this->_charset); + if (!$this->_tablePrefix) $this->_tablePrefix = $this->getConfig(self::TABLEPREFIX, '', $this->_tablePrefix); } } ?> \ No newline at end of file diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 033fffb9..ccdb616a 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -231,9 +231,9 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { */ public function lastInsterId($name = '') { if ($name) - return $this->getDbHandle()->lastInsertId($name); + return $this->getConnection()->getDbHandle()->lastInsertId($name); else - return $this->getDbHandle()->lastInsertId(); + return $this->getConnection()->getDbHandle()->lastInsertId(); } /** @@ -265,11 +265,26 @@ public function execute($params = array(), $rowCount = true) { public function setQueryString($queryString) { if (!$queryString) return $this; if ($_prefix = $this->getConnection()->getTablePrefix()) { - $queryString = preg_replace('/{{(.*?)}}/', $_prefix . '\1', $queryString); + $queryString = $this->buildTablePrefix($_prefix, $queryString); } $this->_queryString = $queryString; return $this; } + + /** + * 查找并替换表前缀。 + * 表前缀配置$prefix允许就设置一个,即添加一个表前缀,或是设置两个并以|分割,则在|左侧的前缀,将会替换|右侧的前缀。 + * @param string $prefix + * @param string $queryString + * @return string + */ + private function buildTablePrefix($prefix, $queryString) { + if (strpos($prefix, '|') === false) return preg_replace('/{{(.*?)}}/', $_prefix . '\1', $queryString); + list($new, $old) = explode('|', $prefix); + preg_match('/{{(.*?)}}/', $queryString, $match); + if (!$match) return $queryString; + return str_replace($match[0], str_replace($old, $new, $match[1]), $queryString); + } /** * @return the $_queryString From 7e6fbb842d2cf9ded7d948b50dd099a5d501424f Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 1 Jul 2011 07:34:12 +0000 Subject: [PATCH 0058/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2097 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index ccdb616a..817fb31b 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -265,26 +265,12 @@ public function execute($params = array(), $rowCount = true) { public function setQueryString($queryString) { if (!$queryString) return $this; if ($_prefix = $this->getConnection()->getTablePrefix()) { - $queryString = $this->buildTablePrefix($_prefix, $queryString); + list($new, $old) = explode('|', $_prefix); + $queryString = (preg_replace('/{(' . $old . ')?(.*?)}/', $new . '\2', $queryString)); } $this->_queryString = $queryString; return $this; } - - /** - * 查找并替换表前缀。 - * 表前缀配置$prefix允许就设置一个,即添加一个表前缀,或是设置两个并以|分割,则在|左侧的前缀,将会替换|右侧的前缀。 - * @param string $prefix - * @param string $queryString - * @return string - */ - private function buildTablePrefix($prefix, $queryString) { - if (strpos($prefix, '|') === false) return preg_replace('/{{(.*?)}}/', $_prefix . '\1', $queryString); - list($new, $old) = explode('|', $prefix); - preg_match('/{{(.*?)}}/', $queryString, $match); - if (!$match) return $queryString; - return str_replace($match[0], str_replace($old, $new, $match[1]), $queryString); - } /** * @return the $_queryString From 84ca83b5f14dca86ce722ac7cedf2da60ee7b47c Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 1 Jul 2011 07:42:56 +0000 Subject: [PATCH 0059/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2098 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 817fb31b..d7e0d18e 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -265,8 +265,8 @@ public function execute($params = array(), $rowCount = true) { public function setQueryString($queryString) { if (!$queryString) return $this; if ($_prefix = $this->getConnection()->getTablePrefix()) { - list($new, $old) = explode('|', $_prefix); - $queryString = (preg_replace('/{(' . $old . ')?(.*?)}/', $new . '\2', $queryString)); + list($new, $old) = strpos($_prefix, '|') !== false ? explode('|', $_prefix) : array($_prefix, ''); + $queryString = preg_replace('/{(' . $old . ')?(.*?)}/', $new . '\2', $queryString); } $this->_queryString = $queryString; return $this; From 34e111361e244e3ba39c5a6f07dcbd247ac5933e Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 4 Jul 2011 08:55:33 +0000 Subject: [PATCH 0060/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2101 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/request/WindHttpRequest.php | 30 +++++++++++---------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php index 9ed04c08..97c0c414 100644 --- a/wind/core/request/WindHttpRequest.php +++ b/wind/core/request/WindHttpRequest.php @@ -5,7 +5,6 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ - Wind::import('WIND:core.request.IWindRequest'); /** * the last known user to change this file in the repository <$LastChangedBy$> @@ -14,55 +13,45 @@ * @package */ class WindHttpRequest implements IWindRequest { - /** * 访问的端口号 * @var int */ private $_port = null; - /** * 客户端IP * @var string */ private $_clientIp = null; - /** * 语言信息 * @var string */ private $_language = null; - /** * 路径信息 * @var string */ private $_pathInfo = null; - /** * @var string */ private $_scriptUrl = null; - /** * @var string */ private $_requestUri = null; - /** * 基础路径信息 * @var string */ private $_baseUrl = null; - private $_hostInfo = null; - /** * 请求参数信息 * @var array */ private $_attribute = array(); - /** * @var WindHttpResponse */ @@ -91,13 +80,12 @@ public function setAttribute($name, $value) { /** * 根据名称获得服务器和执行环境信息 - * * @param string|null $name */ public function getAttribute($name, $value = '') { - if (isset($this->_attribute[$name])) { + if (isset($this->_attribute[$name])) return $this->_attribute[$name]; - } else if (isset($_GET[$name])) + else if (isset($_GET[$name])) return $_GET[$name]; else if (isset($_POST[$name])) return $_POST[$name]; @@ -113,6 +101,16 @@ public function getAttribute($name, $value = '') { return $value; } + /** + * 返回 + * @param string $name | attribute name + */ + public function getRequest($name, $defaultValue = null) { + if (isset($_GET[$name])) return $_GET[$name]; + if (isset($_POST[$name])) return $_POST[$name]; + return $defaultValue; + } + /** * 从query中取值 * @@ -572,7 +570,6 @@ private function initRequestUri() { */ private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); - $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; @@ -629,10 +626,7 @@ private function _initPathInfo() { $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(''); - if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); - $this->_pathInfo = trim($pathInfo, '/'); } - } \ No newline at end of file From 4b510b73a6fd11fbc00a38300ce10749046f6a72 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 4 Jul 2011 08:56:27 +0000 Subject: [PATCH 0061/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2102 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/request/WindHttpRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php index 97c0c414..946769df 100644 --- a/wind/core/request/WindHttpRequest.php +++ b/wind/core/request/WindHttpRequest.php @@ -102,7 +102,7 @@ public function getAttribute($name, $value = '') { } /** - * 返回 + * 返回$_GET,$_POST的值,未设置则返回default * @param string $name | attribute name */ public function getRequest($name, $defaultValue = null) { From 03dc65e8e03a6b1fbbea59d8318071a99a8718e1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 4 Jul 2011 09:13:52 +0000 Subject: [PATCH 0062/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2104 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/request/WindHttpRequest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php index 946769df..61e72b9f 100644 --- a/wind/core/request/WindHttpRequest.php +++ b/wind/core/request/WindHttpRequest.php @@ -105,7 +105,8 @@ public function getAttribute($name, $value = '') { * 返回$_GET,$_POST的值,未设置则返回default * @param string $name | attribute name */ - public function getRequest($name, $defaultValue = null) { + public function getRequest($name = '', $defaultValue = null) { + if (!$name) return array_merge($_POST, $_GET); if (isset($_GET[$name])) return $_GET[$name]; if (isset($_POST[$name])) return $_POST[$name]; return $defaultValue; From fc92836c5058ec599cde075c9ed0b1f594c42609 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 4 Jul 2011 09:15:48 +0000 Subject: [PATCH 0063/1065] =?UTF-8?q?NEW=20-=20bug=20145:=20Task:=20DB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=20=E5=BA=95=E5=B1=82PDO=20http://bugs.phpwin?= =?UTF-8?q?d-inc.com/show=5Fbug.cgi=3Fid=3D145?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2105 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/request/WindHttpRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php index 61e72b9f..8bc91af0 100644 --- a/wind/core/request/WindHttpRequest.php +++ b/wind/core/request/WindHttpRequest.php @@ -105,7 +105,7 @@ public function getAttribute($name, $value = '') { * 返回$_GET,$_POST的值,未设置则返回default * @param string $name | attribute name */ - public function getRequest($name = '', $defaultValue = null) { + public function getRequest($name = null, $defaultValue = null) { if (!$name) return array_merge($_POST, $_GET); if (isset($_GET[$name])) return $_GET[$name]; if (isset($_POST[$name])) return $_POST[$name]; From 1471f29570c2dde424ae1c4586ef86018af3ec21 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 5 Jul 2011 01:47:32 +0000 Subject: [PATCH 0064/1065] =?UTF-8?q?bug=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=EF=BC=8C=E5=9C=A8=E8=8E=B7=E5=8F=96=E9=85=8D=E7=BD=AE=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=A6=82=E6=9E=9C=E4=BC=A0=E5=85=A5=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E5=B0=86=E4=BC=9A=E7=94=A8=E4=BD=9C=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=95=B0=E7=BB=84=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E7=BC=BA?= =?UTF-8?q?=E7=9C=81=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2107 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindComponentModule.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php index d013f5bc..34cf5342 100644 --- a/wind/core/WindComponentModule.php +++ b/wind/core/WindComponentModule.php @@ -60,12 +60,12 @@ public function setAttribute($alias, $object = null) { * * @param string $configName 键名 * @param string $subConfigName 二级键名 - * @param array $default 缺省的数组格式 + * @param array $config 提供的数组 * @return string|array */ - public function getConfig($configName = '', $subConfigName = '', $default = '') { + public function getConfig($configName = '', $subConfigName = '', $config = '') { if (null === $this->_config) return ''; - return $this->_config->getConfig($configName, $subConfigName, array(), $default); + return $this->_config->getConfig($configName, $subConfigName, $config, array()); } /** From d917b0e5e85628746fac4c72cb7859f7fbe4bdbe Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 5 Jul 2011 02:47:28 +0000 Subject: [PATCH 0065/1065] =?UTF-8?q?bug=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=EF=BC=8C=E5=9C=A8=E8=8E=B7=E5=8F=96=E9=85=8D=E7=BD=AE=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=A6=82=E6=9E=9C=E4=BC=A0=E5=85=A5=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E5=B0=86=E4=BC=9A=E7=94=A8=E4=BD=9C=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=95=B0=E7=BB=84=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E7=BC=BA?= =?UTF-8?q?=E7=9C=81=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2108 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 12 ++++++------ wind/core/WindComponentModule.php | 5 +++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index ba72609a..429a0741 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -210,12 +210,12 @@ public function init() { */ public function setConfig($config) { parent::setConfig($config); - if (!$this->_dsn) $this->_dsn = $this->getConfig(self::DSN, '', $this->_dsn); - if (!$this->_user) $this->_user = $this->getConfig(self::USER, '', $this->_user); - if (!$this->_pwd) $this->_pwd = $this->getConfig(self::PWD, '', $this->_pwd); - if (!$this->_enableLog) $this->_enableLog = $this->getConfig(self::ENABLELOG, '', $this->_enableLog); - if (!$this->_charset) $this->_charset = $this->getConfig(self::CHARSET, '', $this->_charset); - if (!$this->_tablePrefix) $this->_tablePrefix = $this->getConfig(self::TABLEPREFIX, '', $this->_tablePrefix); + if (!$this->_dsn) $this->_dsn = $this->getConfig(self::DSN, '', array(), $this->_dsn); + if (!$this->_user) $this->_user = $this->getConfig(self::USER, '', array(), $this->_user); + if (!$this->_pwd) $this->_pwd = $this->getConfig(self::PWD, '', array(), $this->_pwd); + if (!$this->_enableLog) $this->_enableLog = $this->getConfig(self::ENABLELOG, '', array(), $this->_enableLog); + if (!$this->_charset) $this->_charset = $this->getConfig(self::CHARSET, '', array(), $this->_charset); + if (!$this->_tablePrefix) $this->_tablePrefix = $this->getConfig(self::TABLEPREFIX, '', array(), $this->_tablePrefix); } } ?> \ No newline at end of file diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php index 34cf5342..a4a3a73a 100644 --- a/wind/core/WindComponentModule.php +++ b/wind/core/WindComponentModule.php @@ -61,11 +61,12 @@ public function setAttribute($alias, $object = null) { * @param string $configName 键名 * @param string $subConfigName 二级键名 * @param array $config 提供的数组 + * @param array $default 提供的数组 * @return string|array */ - public function getConfig($configName = '', $subConfigName = '', $config = '') { + public function getConfig($configName = '', $subConfigName = '', $config = '', $default = '') { if (null === $this->_config) return ''; - return $this->_config->getConfig($configName, $subConfigName, $config, array()); + return $this->_config->getConfig($configName, $subConfigName, $config, $default); } /** From 8073de3ce39003c8693f3dbdd879a465e6524869 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 5 Jul 2011 04:44:26 +0000 Subject: [PATCH 0066/1065] =?UTF-8?q?bug=EF=BC=8C=E5=A4=9A=E9=A4=98?= =?UTF-8?q?=E8=AE=8A=E9=87=8F=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2109 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/mail/WindMail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/mail/WindMail.php b/wind/component/mail/WindMail.php index b3116b3f..b4efd04b 100644 --- a/wind/component/mail/WindMail.php +++ b/wind/component/mail/WindMail.php @@ -150,7 +150,7 @@ public function createBody(){ if(self::ONLYTEXT === $mime){ return self::encode($this->getBodyText(),$this->encode); }elseif(self::ONLYHTML === $mime){ - return $body .= self::encode($this->getBodyHtml(),$this->encode).self::CRLF; + return self::encode($this->getBodyHtml(),$this->encode).self::CRLF; }elseif(self::TEXTHTML === $mime){ $boundary = $this->boundaryLine(); $body = $boundary.$this->getTextHeader().self::encode($this->getBodyText(),$this->encode).self::CRLF; From ca0b3d2e40c0309dfee8f4fd7a9e9a0525d83a43 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 5 Jul 2011 05:34:27 +0000 Subject: [PATCH 0067/1065] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8?= =?UTF-8?q?=EF=BC=9A=20execute=E7=BB=91=E5=AE=9A=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E9=87=87=E7=94=A8execute=E6=9C=AC=E8=BA=AB=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2110 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index d7e0d18e..995552f1 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -246,8 +246,12 @@ public function execute($params = array(), $rowCount = true) { try { Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); $this->init(); - $this->bindValues($params); - $this->getStatement()->execute(); +// $this->bindValues($params); + if (empty($params)) { + $this->getStatement()->execute(); + } else { + $this->getStatement()->execute($params); + } $_result = $rowCount ? $this->getStatement()->rowCount() : true; Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); Wind::profileEnd('component.db.WindSqlStatement._init'); From 0e605e2cc56f7b1dee5af560b5eefe1a4486a6ef Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 5 Jul 2011 06:33:50 +0000 Subject: [PATCH 0068/1065] =?UTF-8?q?=E5=BC=80=E6=94=BEinit=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=B8=BA=E7=94=A8=E6=88=B7=E5=8F=AF=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2111 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 2ffed626..18dfe17a 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -10,7 +10,7 @@ /* debug/log */ !defined('IS_DEBUG') && define('IS_DEBUG', 1); !defined('DEBUG_TIME') && define('DEBUG_TIME', microtime(true)); -!defined('LOG_DIR') && define('LOG_DIR', COMPILE_PATH . 'log' . D_S); +!defined('LOG_DIR') && define('LOG_DIR', COMPILE_PATH . 'log'); !defined('LOG_WRITE_LEVEL') && define('LOG_WRITE_LEVEL', 1); /** * the last known user to change this file in the repository <$LastChangedBy: yishuo $> @@ -197,7 +197,7 @@ public static function perLoadCoreLibrary($libPath) { /** * 初始化框架 */ - final public static function init() { + public static function init() { self::_checkEnvironment(); self::_setDefaultSystemNamespace(); self::_registerAutoloader(); From 285b8d8aa9a4e4e6057bea48955004f50864ec8d Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 06:44:19 +0000 Subject: [PATCH 0069/1065] =?UTF-8?q?=E5=AF=B9=E4=BA=8EsetConfig=20?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E4=B8=AA=E5=8F=82=E6=95=B0=EF=BC=8C=E5=AF=B9?= =?UTF-8?q?=E4=BA=8E=E6=99=AE=E9=80=9A=E7=9A=84module=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E4=B8=8D=E5=BC=80=E5=8F=91=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2112 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindComponentModule.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php index a4a3a73a..3202366b 100644 --- a/wind/core/WindComponentModule.php +++ b/wind/core/WindComponentModule.php @@ -57,16 +57,14 @@ public function setAttribute($alias, $object = null) { /** * 根据配置名取得相应的配置 - * * @param string $configName 键名 * @param string $subConfigName 二级键名 - * @param array $config 提供的数组 - * @param array $default 提供的数组 + * @param array $default 默认值 * @return string|array */ - public function getConfig($configName = '', $subConfigName = '', $config = '', $default = '') { + public function getConfig($configName = '', $subConfigName = '', $default = '') { if (null === $this->_config) return ''; - return $this->_config->getConfig($configName, $subConfigName, $config, $default); + return $this->_config->getConfig($configName, $subConfigName, array(), $default); } /** From 9960929f69d872a6f94eb64c05ba6e0a0477d6b8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 06:44:34 +0000 Subject: [PATCH 0070/1065] =?UTF-8?q?=E5=AF=B9=E4=BA=8EsetConfig=20?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E4=B8=AA=E5=8F=82=E6=95=B0=EF=BC=8C=E5=AF=B9?= =?UTF-8?q?=E4=BA=8E=E6=99=AE=E9=80=9A=E7=9A=84module=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E4=B8=8D=E5=BC=80=E5=8F=91=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2113 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 429a0741..ba72609a 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -210,12 +210,12 @@ public function init() { */ public function setConfig($config) { parent::setConfig($config); - if (!$this->_dsn) $this->_dsn = $this->getConfig(self::DSN, '', array(), $this->_dsn); - if (!$this->_user) $this->_user = $this->getConfig(self::USER, '', array(), $this->_user); - if (!$this->_pwd) $this->_pwd = $this->getConfig(self::PWD, '', array(), $this->_pwd); - if (!$this->_enableLog) $this->_enableLog = $this->getConfig(self::ENABLELOG, '', array(), $this->_enableLog); - if (!$this->_charset) $this->_charset = $this->getConfig(self::CHARSET, '', array(), $this->_charset); - if (!$this->_tablePrefix) $this->_tablePrefix = $this->getConfig(self::TABLEPREFIX, '', array(), $this->_tablePrefix); + if (!$this->_dsn) $this->_dsn = $this->getConfig(self::DSN, '', $this->_dsn); + if (!$this->_user) $this->_user = $this->getConfig(self::USER, '', $this->_user); + if (!$this->_pwd) $this->_pwd = $this->getConfig(self::PWD, '', $this->_pwd); + if (!$this->_enableLog) $this->_enableLog = $this->getConfig(self::ENABLELOG, '', $this->_enableLog); + if (!$this->_charset) $this->_charset = $this->getConfig(self::CHARSET, '', $this->_charset); + if (!$this->_tablePrefix) $this->_tablePrefix = $this->getConfig(self::TABLEPREFIX, '', $this->_tablePrefix); } } ?> \ No newline at end of file From f5aa281c14e0126a299f53adb15a2aacf7345e40 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 07:23:10 +0000 Subject: [PATCH 0071/1065] =?UTF-8?q?bindValues=20bindParams=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=97=A0?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=E6=95=B0=E7=BB=84=E5=8F=82=E6=95=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2114 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 1 - wind/component/db/WindSqlStatement.php | 27 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index ba72609a..920b1704 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -31,7 +31,6 @@ class WindConnection extends WindComponentModule { * @var PDO */ private $_dbHandle = null; - private $_filterArray = array(); /** * @param string $dsn diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 995552f1..652e9569 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -73,15 +73,19 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu * @return WindSqlStatement */ public function bindParams(&$parameters) { + if (!is_array($parameters) || empty($parameters)) { + throw new WindSqlException('[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters)); + } + $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1)); foreach ($parameters as $key => $value) { + $_key = $keied ? $key : $key + 1; if (is_array($value)) { - $dataType = isset($value[1]) ? $value[1] : null; + $dataType = isset($value[1]) ? $value[1] : $this->_getPdoDataType($value[0]); $length = isset($value[2]) ? $value[2] : null; $driverOptions = isset($value[3]) ? $value[3] : null; - $this->bindParam($key, $parameters[$key][0], $dataType, $length, $driverOptions); - } else { - $this->bindParam($key, $parameters[$key], $this->_getPdoDataType($value)); - } + $this->bindParam($_key, $parameters[$key][0], $dataType, $length, $driverOptions); + } else + $this->bindParam($_key, $parameters[$key], $this->_getPdoDataType($value)); } return $this; } @@ -111,7 +115,12 @@ public function bindValue($parameter, $value, $data_type = null) { * @param array $values */ public function bindValues($values) { + if (!is_array($values) || empty($values)) { + throw new WindSqlException('[component.db.WindSqlStatement.bindValues] Error unexpected paraments type ' . gettype($values)); + } + $keied = (array_keys($values) !== range(0, sizeof($values) - 1)); foreach ($values as $key => $value) { + if (!$keied) $key = $key + 1; $this->bindValue($key, $value, $this->_getPdoDataType($value)); } return $this; @@ -246,12 +255,8 @@ public function execute($params = array(), $rowCount = true) { try { Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); $this->init(); -// $this->bindValues($params); - if (empty($params)) { - $this->getStatement()->execute(); - } else { - $this->getStatement()->execute($params); - } + $this->bindValues($params); + $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); Wind::profileEnd('component.db.WindSqlStatement._init'); From 26f3982b29f501f10d6327d25283e28395c469ba Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 07:29:33 +0000 Subject: [PATCH 0072/1065] =?UTF-8?q?bindValues=20bindParams=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=97=A0?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=E6=95=B0=E7=BB=84=E5=8F=82=E6=95=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2115 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 652e9569..953927b0 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -1,4 +1,5 @@ @@ -74,7 +75,7 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu */ public function bindParams(&$parameters) { if (!is_array($parameters) || empty($parameters)) { - throw new WindSqlException('[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters)); + throw new WindDbException('[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters)); } $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1)); foreach ($parameters as $key => $value) { From 59d64c9df7f2a59656ab5fb6ed60a4878d071a10 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 07:31:29 +0000 Subject: [PATCH 0073/1065] =?UTF-8?q?bindValues=20bindParams=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=97=A0?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=E6=95=B0=E7=BB=84=E5=8F=82=E6=95=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2116 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 6b363b26..25abd1e7 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -46,8 +46,8 @@ public function processRequest() { } catch (WindActionException $actionException) { $this->sendErrorMessage($actionException); - } catch (WindSqlException $windSqlException) { - $this->sendErrorMessage($windSqlException->getMessage()); + } catch (WindDbException $e) { + $this->sendErrorMessage($e); } catch (WindViewException $windViewException) { From b0746113c100e0a472e680394aa1d780b1295d24 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 07:32:27 +0000 Subject: [PATCH 0074/1065] =?UTF-8?q?bindValues=20bindParams=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=97=A0?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=E6=95=B0=E7=BB=84=E5=8F=82=E6=95=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2117 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 25abd1e7..d23188a8 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -46,10 +46,10 @@ public function processRequest() { } catch (WindActionException $actionException) { $this->sendErrorMessage($actionException); - } catch (WindDbException $e) { - $this->sendErrorMessage($e); + } catch (WindDbException $dbException) { + $this->sendErrorMessage($dbException); - } catch (WindViewException $windViewException) { + } catch (WindViewException $viewException) { } } From 4fa9246fded0196ad43133d3db1f3b33777fd81c Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 08:41:56 +0000 Subject: [PATCH 0075/1065] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2118 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindComponentModule.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php index 3202366b..a387fd20 100644 --- a/wind/core/WindComponentModule.php +++ b/wind/core/WindComponentModule.php @@ -27,6 +27,11 @@ abstract class WindComponentModule extends WindModule { */ protected $windFactory; + /** + * 初始化方法 + */ + public function init() {} + /** * Enter description here ... */ From 41e84958de242576c1d411255224a5e57259bde7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 08:42:28 +0000 Subject: [PATCH 0076/1065] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2119 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnectionManager.php | 42 ++++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/wind/component/db/WindConnectionManager.php b/wind/component/db/WindConnectionManager.php index 9a25ac50..cef8ec51 100644 --- a/wind/component/db/WindConnectionManager.php +++ b/wind/component/db/WindConnectionManager.php @@ -1,4 +1,5 @@ * @author Qiong Wu @@ -6,13 +7,44 @@ * @package */ class WindConnectionManager extends WindComponentModule { + const CONNECTION_MODE_RAND = '0'; + private $connections = array(); /** - * @param string $dsn - * @param string $username - * @param string $password + * 根据链接名称返回链接句柄,name为空则返回随机返回一个俩接句柄 + * @param unknown_type $name + * @return WindConnection */ - public function __construct($dsn = '', $username = '', $password = '') { - + public function getConnection($name = '') { + if (isset($this->connections[$name])) return $this->connections[$name]; + $configs = $this->getConfig(); + if (!is_array($configs) || empty($configs)) { + throw new WindDbException('[component.db.WindConnectionManager.getConnection] empty config.'); + } + $config = array(); + if ($name !== '') { + foreach ($configs as $value) { + if ($value['name'] == $name) { + $config = $value; + break; + } + } + } else { + $config = $this->getCurrentConnection(); + $name = $config['name']; + } + $connection = new WindConnection(); + $connection->setConfig($config); + $connection->init(); + $this->connections[$name] = $connection; + return $this->connections[$name]; + } + + /** + * 返回当前连接句柄的配置信息 + */ + protected function getCurrentConnection() { + $configs = $this->getConfig(); + return count($configs) > 1 ? $configs[rand(0, count($configs) - 1)] : $configs[0]; } } \ No newline at end of file From 11118c728095aa9786a58ede0be410e6ac04badc Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 08:43:17 +0000 Subject: [PATCH 0077/1065] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=8F=A5=E6=9F=84=E8=BF=94=E5=9B=9E=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2120 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDaoFactory.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index b99a4a76..8ebc7b81 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -93,7 +93,7 @@ protected function createDbConnection($daoObject) { $this->windFactory->addClassDefinitions($defintion); $this->dbConnections[$_dbClass] = $this->windFactory->getInstance($defintion->getAlias()); } - return $this->getHandler($_dbClass); + return $this->dbConnections[$_dbClass]; } /** @@ -112,20 +112,6 @@ protected function createCacheHandler($daoObject) { return $this->caches[$_cacheClass]; } - /** - * @param string $key - * @return WindConnection - */ - private function getHandler($key) { - $connection = $this->dbConnections[$key]; - if ($connection === null) return null; - if ($connection instanceof WindConnectionManager) { - return $connection->getConnection(); - } elseif ($connection instanceof WindConnection) { - return $connection; - } - } - /** * @return WindFactory */ From fc97577a91586e39b858e816ab2f1db9fff711e2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 08:43:27 +0000 Subject: [PATCH 0078/1065] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=8F=A5=E6=9F=84=E8=BF=94=E5=9B=9E=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2121 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 920b1704..56759842 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -181,6 +181,7 @@ public function close() { * @return */ public function init() { + parent::init(); if ($this->_dbHandle !== null) return; try { Wind::log("component.db.WindConnection._init() Initialize DB handle, set default attributes and charset.", WindLogger::LEVEL_INFO); From 01d0de7e459a6a21ceff8b2150cbcfc98854b556 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 09:54:28 +0000 Subject: [PATCH 0079/1065] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=8F=A5=E6=9F=84=E8=BF=94=E5=9B=9E=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2123 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDaoFactory.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index 8ebc7b81..e52d4928 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -86,14 +86,17 @@ private function registerCacheListener($daoInstance) { * @return WindConnection */ protected function createDbConnection($daoObject) { - $_dbClass = $daoObject->getDbClass(); - if (!isset($this->dbConnections[$_dbClass])) { + $defintion = $daoObject->getDbDefinition(); + $_className = $defintion->getClassName(); + $_classConfig = $defintion->getConfig(); + $_alias = md5($_className + serialize($_classConfig)); + if (!isset($this->dbConnections[$_alias])) { $this->_getWindFactory(); - $defintion = $daoObject->getDbDefinition(); $this->windFactory->addClassDefinitions($defintion); - $this->dbConnections[$_dbClass] = $this->windFactory->getInstance($defintion->getAlias()); + $this->dbConnections[$_alias] = $this->windFactory->getInstance($defintion->getAlias()); } - return $this->dbConnections[$_dbClass]; + print_r($this->dbConnections); + return $this->dbConnections[$_alias]; } /** From ee1817a1bfb684a1e3958fdb5cc64af945dfbe55 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 09:54:57 +0000 Subject: [PATCH 0080/1065] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=8F=A5=E6=9F=84=E8=BF=94=E5=9B=9E=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2124 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDaoFactory.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index e52d4928..e8f76f49 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -95,7 +95,6 @@ protected function createDbConnection($daoObject) { $this->windFactory->addClassDefinitions($defintion); $this->dbConnections[$_alias] = $this->windFactory->getInstance($defintion->getAlias()); } - print_r($this->dbConnections); return $this->dbConnections[$_alias]; } From 834b49b315cb10b21e978c49097ffc35d32555a7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 10:04:26 +0000 Subject: [PATCH 0081/1065] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E5=8F=A5=E6=9F=84=E8=BF=94=E5=9B=9E=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2125 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDaoFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index e8f76f49..7dfbb2ab 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -89,7 +89,7 @@ protected function createDbConnection($daoObject) { $defintion = $daoObject->getDbDefinition(); $_className = $defintion->getClassName(); $_classConfig = $defintion->getConfig(); - $_alias = md5($_className + serialize($_classConfig)); + $_alias = $_className . '_' . md5(serialize($_classConfig)); if (!isset($this->dbConnections[$_alias])) { $this->_getWindFactory(); $this->windFactory->addClassDefinitions($defintion); From 1e1b10a38503470d531e3f1d6e63f982abc9a09d Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 11:04:24 +0000 Subject: [PATCH 0082/1065] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2126 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnectionManager.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wind/component/db/WindConnectionManager.php b/wind/component/db/WindConnectionManager.php index cef8ec51..a7566827 100644 --- a/wind/component/db/WindConnectionManager.php +++ b/wind/component/db/WindConnectionManager.php @@ -8,6 +8,11 @@ */ class WindConnectionManager extends WindComponentModule { const CONNECTION_MODE_RAND = '0'; + /** + * 链接句柄 + * + * @var array + */ private $connections = array(); /** From b1474e6a9fb8951016d33f399323c80877006fd8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 5 Jul 2011 11:04:37 +0000 Subject: [PATCH 0083/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2127 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 953927b0..69b10783 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -74,7 +74,7 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu * @return WindSqlStatement */ public function bindParams(&$parameters) { - if (!is_array($parameters) || empty($parameters)) { + if (!is_array($parameters)) { throw new WindDbException('[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters)); } $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1)); @@ -116,7 +116,7 @@ public function bindValue($parameter, $value, $data_type = null) { * @param array $values */ public function bindValues($values) { - if (!is_array($values) || empty($values)) { + if (!is_array($values)) { throw new WindSqlException('[component.db.WindSqlStatement.bindValues] Error unexpected paraments type ' . gettype($values)); } $keied = (array_keys($values) !== range(0, sizeof($values) - 1)); @@ -162,12 +162,6 @@ public function bindColumns($columns, &$param = array()) { } } - /** - * Enter description here ... - * @param unknown_type $columns - */ - public function setColumns($columns) {} - /** * 执行SQL语句,并返回更新影响行数 * @param array $params From e800636bba7220cb786458feb4cab5405777ffb8 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 6 Jul 2011 06:06:45 +0000 Subject: [PATCH 0084/1065] =?UTF-8?q?Notice=20=E6=8F=90=E7=A4=BA=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E5=A3=B0=E6=98=8E=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2128 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index d59ec8bb..3bae0f85 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -203,6 +203,7 @@ public function getMemoryUsage($peak = true) { */ private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace("
", "\r\n", trim($msg))); + $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; From d0bc1e35fe53920ab94b5964848c9427c30a5514 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 7 Jul 2011 09:19:16 +0000 Subject: [PATCH 0085/1065] =?UTF-8?q?NEW=20-=20bug=20149:=20=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=B7=BB=E5=8A=A0=EF=BC=8C=E8=A1=A8=E5=8D=95=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=8A=E4=BC=A0=E7=BB=84=E4=BB=B6=E7=B1=BB=20http:/?= =?UTF-8?q?/bugs.phpwind-inc.com/show=5Fbug.cgi=3Fid=3D149?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2130 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/AbstractWindUpload.php | 82 +++++++-- wind/component/upload/WindCurlUpload.php | 15 +- wind/component/upload/WindFormUpload.php | 165 +++++++++++++++++-- 3 files changed, 230 insertions(+), 32 deletions(-) diff --git a/wind/component/upload/AbstractWindUpload.php b/wind/component/upload/AbstractWindUpload.php index 2220c26b..fc5d0da1 100644 --- a/wind/component/upload/AbstractWindUpload.php +++ b/wind/component/upload/AbstractWindUpload.php @@ -1,23 +1,79 @@ - 2010-12-13 * @link http://www.phpwind.com * @copyright Copyright © 2003-2110 phpwind.com * @license - */ -Wind::import ( 'WIND:component.utility.Security' ); -Wind::import ( 'WIND:component.utility.WindFile' ); + */ +Wind::import('WIND:component.utility.Security'); +Wind::import('WIND:component.utility.WindFile'); /** - * the last known user to change this file in the repository <$LastChangedBy$> + * the last known user to change this file in the repository <$LastChangedBy: yishuo $> * @author Qian Su - * @version $Id$ + * @version $Id: AbstractWindUpload.php 1994 2011-06-16 04:19:05Z yishuo $ * @package - */ -abstract class AbstractWindUpload{ + */ +abstract class AbstractWindUpload { + + protected $hasError = false; + /** - * @param string $name - * @param string $newName - * @param string $path - */ - public abstract function upload($name, $newName, $path); + * 上传文件 + * @param string $saveDir + * @param string $fileName + * @param array $allowType 格式为 array(ext=>size) size单位为b + * @return array|string + */ + public abstract function upload($saveDir, $fileName = '', $allowType = array()); + + /** + * 返回是否含有错误 + * @return boolean + */ + public function hasError() { + return $this->hasError; + } + + /** + * 返回错误信息 + * @param string $errorType + * @return string|mixed + */ + public abstract function getErrorInfo($errorType = ''); + + /** + * 檢查文件是否允許上傳 + * @param string $ext + * @param array $allowType + * @return bool + */ + protected function checkAllowType($ext, $allowType) { + return $allowType ? in_array($ext, (array)$allowType) : true; + } + + /** + * 判断是否使图片,如果使图片则返回 + * @param string $ext; + * @return boolean + */ + protected function isImage($ext) { + return in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'swf')); + } + + + /** + * 创建文件夹 + * @param string $path + * @return boolean + */ + protected function createFolder($path) { + if (!is_dir($path)) { + $this->createFolder(dirname($path)); + @mkdir($path); + @chmod($path, 0777); + @fclose(@fopen($path . '/index.html', 'w')); + @chmod($path . '/index.html', 0777); + } + return true; + } } \ No newline at end of file diff --git a/wind/component/upload/WindCurlUpload.php b/wind/component/upload/WindCurlUpload.php index 317830ac..447f3fa5 100644 --- a/wind/component/upload/WindCurlUpload.php +++ b/wind/component/upload/WindCurlUpload.php @@ -1,16 +1,23 @@ + * the last known user to change this file in the repository <$LastChangedBy: weihu $> * @author Qian Su - * @version $Id$ + * @version $Id: WindCurlUpload.php 1710 2011-03-08 12:09:38Z weihu $ * @package * tags */ class WindCurlUpload extends AbstractWindUpload{ - public function upload($name, $newName, $path) { + public function upload($newName, $path) { + + } + + public function hasError() { + + } + + public function getErrorInfo($type = '') { } - } \ No newline at end of file diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index 8f2d4930..c753ad7a 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -1,24 +1,159 @@ - 2010-12-13 * @link http://www.phpwind.com * @copyright Copyright © 2003-2110 phpwind.com * @license - */ - -Wind::import ( 'WIND:component.upload.AbstractWindUpload'); - + */ + +Wind::import('WIND:component.upload.AbstractWindUpload'); + /** - * the last known user to change this file in the repository <$LastChangedBy$> + * the last known user to change this file in the repository <$LastChangedBy: yishuo $> * @author Qian Su - * @version $Id$ + * @version $Id: WindFormUpload.php 1994 2011-06-16 04:19:05Z yishuo $ * @package - */ -class WindFormUpload extends AbstractWindUpload{ - - public function upload($name, $newName, $path) { - - } - - + */ +class WindFormUpload extends AbstractWindUpload { + private $errorInfo = array('type' => array(), 'size' => array(), 'upload' => array()); + + private $allowType = array();//允许上传的类型及对应的大小,array(ext=>size); + + public function __construct($allowType = array()) { + $allowType && $this->allowType = $allowType; + } + + /** + * + * (non-PHPdoc) + * @see AbstractWindUpload::upload() + */ + public function upload($saveDir, $preFileName = '', $allowType = array()) { + $allowType = $allowType ? (array)$allowType : $this->allowType; + $atc_attachment = ''; + $uploaddb = $error = array(); + foreach ($_FILES as $key => $value) { + if (!$this->hasUploadedFile($value['tmp_name'])) continue; + $atc_attachment = $value['tmp_name']; + $upload = $this->initCurrUpload($key, $value); + + if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'], array_keys($allowType))) { + $error['type'][] = $upload; + $this->hasError = true; + continue; + } + if ($upload['size'] < 1 || $upload['size'] > $allowType[$upload['ext']]) { + $upload['maxSize'] = $allowType[$upload['ext']]; + $error['size'][] = $upload; + $this->hasError = true; + continue; + } + $fileName = $this->getFileName($upload, $preFileName); + $source = $this->getSavePath($fileName, $saveDir); + + if (!$this->postUpload($atc_attachment, $source)) { + $upload['savePath'] = $source; + $error['upload'][] = $upload; + $this->hasError = true; + continue; + } + clearstatcache(); + $upload['size'] = ceil(filesize($source) / 1024); + $upload['savePath'] = $source; + $uploaddb[] = $upload; + } + $this->errorInfo = $error; + return $uploaddb;/*array($uploaddb, $errorType, $errorSize, $uploadError)*/; + } + + /** + * (non-PHPdoc) + * @see AbstractWindUpload::getErrorInfo() + */ + public function getErrorInfo($type = 'all') { + return isset($this->errorInfo[$type]) ? $this->errorInfo[$type] : $this->errorInfo; + } + + /** + * 设置允许上传的类型 + * @param array $allowType + * @return + */ + public function setAllowType($allowType) { + $allowType && $this->allowType = $allowType; + } + + /** + * 执行上传操作 + */ + private function postUpload($tmp_name, $filename) { + if (strpos($filename, '..') !== false || strpos($filename, '.php.') !== false || preg_match("/\.php$/", $filename)) { + exit('illegal file type!'); + } + $this->createFolder(dirname($filename)); + if (function_exists("move_uploaded_file") && @move_uploaded_file($tmp_name, $filename)) { + @chmod($filename, 0777); + return true; + } elseif (@copy($tmp_name, $filename)) { + @chmod($filename, 0777); + return true; + } elseif (is_readable($tmp_name)) { + Wind::import('WIND:component.utility.WindFile'); + WindFile::write($filename, WindFile::read($tmp_name)); + if (file_exists($filename)) { + @chmod($filename, 0777); + return true; + } + } + return false; + } + + /** + * 获得保存路径 + * @param string $fileName + * @param string $saveDir + * @return string + */ + private function getSavePath($fileName, $saveDir) { + return rtrim($saveDir, '\\/') . '/' . $fileName; + } + + /** + * 获得文件名字 + * @param array $info + * @param string $preFileName + * @return string + */ + private function getFileName($info, $preFileName = '') { + $fileName = mt_rand(1, 10) . time() . substr(md5(time() . $info['id'] . mt_rand(1, 10)), 10, 15) . '.' . $info['ext']; + return $preFileName ? $preFileName . $fileName : $fileName; + } + + /** + * 判断是否有上传文件 + * @param string $tmp_name + * @return boolean + */ + private function hasUploadedFile($tmp_name) { + if (!$tmp_name || $tmp_name == 'none') { + return false; + } elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmp_name) && !is_uploaded_file(str_replace('\\\\', '\\', $tmp_name))) { + return false; + } else { + return true; + } + } + + /** + * 初始化上传的文件信息 + * @param string $key + * @param string $value + */ + private function initCurrUpload($key, $value) { + list($t, $i) = explode('_', $key); + $arr = array('id' => intval($i), 'attname' => $t, 'name' => $value['name'], 'size' => intval($value['size']), 'type' => 'zip', 'ifthumb' => 0, 'fileuploadurl' => ''); + $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1)); + return $arr; + } + } \ No newline at end of file From c0ab384e95b6873f3d2425347578440d14a6e96d Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 11 Jul 2011 02:30:26 +0000 Subject: [PATCH 0086/1065] =?UTF-8?q?NEW=20-=20bug=20151:=20=E5=85=B3?= =?UTF-8?q?=E4=BA=8ECall=20to=20undefined=20method=20WindDbException::getE?= =?UTF-8?q?rror()=20=E7=9A=84=E5=BC=82=E5=B8=B8=E9=94=99=E8=AF=AF=EF=BC=9A?= =?UTF-8?q?=20http://bugs.phpwind-inc.com/show=5Fbug.cgi=3Fid=3D151?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2134 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index d23188a8..ecaf8c99 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -47,7 +47,7 @@ public function processRequest() { $this->sendErrorMessage($actionException); } catch (WindDbException $dbException) { - $this->sendErrorMessage($dbException); + $this->sendErrorMessage($dbException->getMessage()); } catch (WindViewException $viewException) { @@ -136,11 +136,11 @@ protected function getHandler() { /** * 错误请求 - * @param WindActionException actionException + * @param WindActionException|string actionException */ protected function sendErrorMessage($actionException) { $forward = $this->windFactory->getInstance(COMPONENT_FORWARD); - $_tmp = $actionException->getError(); + $_tmp = is_object($actionException) ? $actionException->getError() : $actionException; if (is_string($_tmp)) { Wind::import('WIND:core.web.WindErrorMessage'); $_tmp = new WindErrorMessage($_tmp); From a8167e9420d119e92ecd91ea322c84ef6d55506b Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 14 Jul 2011 07:20:44 +0000 Subject: [PATCH 0087/1065] =?UTF-8?q?DB/DAO=E4=BB=A3=E7=A0=81=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E5=AE=8C=E5=96=84=EF=BC=8C=E5=87=86=E5=A4=87DOC?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2139 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDao.php | 10 +- wind/component/dao/WindDaoFactory.php | 15 +- wind/component/db/WindConnection.php | 34 +++-- wind/component/db/WindResultSet.php | 55 ++++--- wind/component/db/WindSqlStatement.php | 143 ++++++++++++------ .../db/mysql/WindMysqlPdoAdapter.php | 6 +- 6 files changed, 169 insertions(+), 94 deletions(-) diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php index e59fe1ab..f6756d29 100644 --- a/wind/component/dao/WindDao.php +++ b/wind/component/dao/WindDao.php @@ -9,6 +9,10 @@ */ class WindDao extends WindModule { protected $dbClass = 'WIND:component.db.WindConnection'; + /** + * 链接配置文件或是配置数组 + * @var string|array + */ protected $dbConfig = ''; protected $cacheClass = ''; protected $cacheConfig = ''; @@ -23,7 +27,7 @@ class WindDao extends WindModule { */ private $cacheHandler = null; - /* + /** * @see WindModule::getWriteTableForGetterAndSetter() */ protected function getWriteTableForGetterAndSetter() { @@ -65,13 +69,14 @@ public function getCacheDefinition() { /** * 获得需要缓存的处理的方法名称数组 * array('methodName1'=>'WIND:component') - * @return multitype: + * @return array */ public function getCacheMethods() { return array(); } /** + * 获得链接对象 * @return WindConnection $connection */ public function getConnection() { @@ -79,6 +84,7 @@ public function getConnection() { } /** + * 设置链接对象 * @param WindConnection $windConnection */ public function setConnection($windConnection) { diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index 7dfbb2ab..b735b159 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -50,14 +50,16 @@ public function getDao($className) { } /** - * @return the $daoResource + * 获得dao存放的目录 + * @return string $daoResource */ public function getDaoResource() { return $this->daoResource; } /** - * @param field_type $daoResource + * 设置dao的获取目录 + * @param string $daoResource */ public function setDaoResource($daoResource) { $this->daoResource = $daoResource; @@ -65,7 +67,7 @@ public function setDaoResource($daoResource) { /** * 注册Dao缓存监听 - * @param AbstractWindDao daoInstance + * @param WindDao daoInstance */ private function registerCacheListener($daoInstance) { $caches = (array) $daoInstance->getCacheMethods(); @@ -81,7 +83,7 @@ private function registerCacheListener($daoInstance) { } /** - * 返回DbHandler + * 返回链接对象 * @param WindDao $daoObject * @return WindConnection */ @@ -100,7 +102,7 @@ protected function createDbConnection($daoObject) { /** * 返回Cache对象 - * @param AbstractWindDao $daoObject + * @param WindDao $daoObject * @return AbstractWindCache */ protected function createCacheHandler($daoObject) { @@ -115,7 +117,8 @@ protected function createCacheHandler($daoObject) { } /** - * @return WindFactory + * 获得ComponentFactory对象 + * @return WindComponentFactory */ private function _getWindFactory() { if ($this->windFactory === null) { diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 56759842..737b7eec 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -54,14 +54,16 @@ public function createStatement($sql = null) { } /** - * @return PDO + * 返回数据库链接对象 + * @return WindMysqlPdoAdapter */ public function getDbHandle() { return $this->_dbHandle; } /** - * @param int $attribute + * 获得链接相关属性设置 + * @param string $attribute * @return string * */ public function getAttribute($attribute = '') { @@ -73,8 +75,9 @@ public function getAttribute($attribute = '') { } /** - * @param $attribute - * @param $value + * 设置链接相关属性 + * @param string $attribute + * @param string $value * @return * */ public function setAttribute($attribute, $value = null) { @@ -100,13 +103,15 @@ public function getDriverName() { } /** - * @return the $enableLog + * 获得是否启用日志记录功能 + * @return boolean $enableLog */ public function getEnableLog() { return $this->_enableLog; } /** + * 设置是否启用日志记录功能 * @param boolean $enableLog */ public function setEnableLog($enableLog) { @@ -114,13 +119,15 @@ public function setEnableLog($enableLog) { } /** - * @return the $tablePrefix + * 获得表前缀 + * @return string $tablePrefix */ public function getTablePrefix() { return $this->_tablePrefix; } /** + * 设置表前缀 * @param string $tablePrefix */ public function setTablePrefix($tablePrefix) { @@ -128,8 +135,9 @@ public function setTablePrefix($tablePrefix) { } /** + * 执行一条sql语句 同时返回影响行数 * @param string $sql | SQL statement - * @return row count + * @return int */ public function execute($sql) { try { @@ -142,8 +150,9 @@ public function execute($sql) { } /** + * 执行一条查询同时返回结果集 * @param string $sql | SQL statement - * @return PDOStatement + * @return WindResultSet */ public function query($sql) { try { @@ -155,14 +164,16 @@ public function query($sql) { } /** - * @param array $array + * (non-PHPdoc) + * @see WindMysqlPdoAdapter::filterArray() */ public function quoteArray($array) { return $this->getDbHandle()->filterArray($array); } /** - * @param string $string + * (non-PHPdoc) + * @see WindMysqlPdoAdapter::quote() */ public function quote($string) { return $this->getDbHandle()->quote($string); @@ -205,7 +216,8 @@ public function init() { } } - /* (non-PHPdoc) + /** + * (non-PHPdoc) * @see WindComponentModule::setConfig() */ public function setConfig($config) { diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 3f859819..2855a277 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -22,7 +22,11 @@ class WindResultSet { private $_columns = array(); /** - * @param WindSqlStatement $sqlStatement + * 构造函数 + * + * @param WindSqlStatement $sqlStatement 预处理对象 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL */ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { if ($sqlStatement instanceof WindSqlStatement) { @@ -35,8 +39,10 @@ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { } /** - * @param $fetchMode - * @return + * 设置获取模式 + * + * @param int $fetchMode 设置获取的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM... + * @param boolean $flush 是否统一设置所有PDOStatement中的获取方式 */ public function setFetchMode($fetchMode, $flush = false) { $this->_fetchMode = $fetchMode; @@ -48,6 +54,7 @@ public function setFetchMode($fetchMode, $flush = false) { /** * 返回最后一条Sql语句的影响行数 + * * @return int */ public function rowCount() { @@ -56,6 +63,7 @@ public function rowCount() { /** * 返回结果集中的列数 + * * @return number */ public function columnCount() { @@ -63,9 +71,9 @@ public function columnCount() { } /** - * Fetches the next row from a result set - * @param int $fetchMode - * @param int $fetchType + * 获得结果集的下一行 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,设置Statement的属性设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL * @return array */ public function fetch($fetchMode = 0, $fetchType = 0) { @@ -75,9 +83,8 @@ public function fetch($fetchMode = 0, $fetchType = 0) { } /** - * @param $fetchMode - * @param $fetchType - * @return array + * (non-PHPdoc) + * @see WindResult::fetch() */ private function _fetch($fetchMode, $fetchType) { if (!empty($this->_columns)) $fetchMode = PDO::FETCH_BOUND; @@ -94,24 +101,23 @@ private function _fetch($fetchMode, $fetchType) { /** * 返回所有的查询结果 - * @param int $fetchType 设置返回的方式 + * + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM * @return array */ public function fetchAll($fetchMode = 0) { if ($fetchMode === 0) $fetchMode = $this->_fetchMode; - if (empty($this->_columns)) - return $this->_statement->fetchAll($fetchMode); - else { - $result = array(); - while ($row = $this->fetch($fetchMode)) - $result[] = $row; - return $result; - } + if (empty($this->_columns)) return $this->_statement->fetchAll($fetchMode); + $result = array(); + while ($row = $this->fetch($fetchMode)) + $result[] = $row; + return $result; } /** - * 从下一行记录中获得下标使$index的值,如果获取失败则返回false - * @param int $index + * 从下一行记录中获得下标是$index的值,如果获取失败则返回false + * + * @param int $index 列下标 * @return string|bool */ public function fetchColumn($index = 0) { @@ -119,10 +125,11 @@ public function fetchColumn($index = 0) { } /** - * Fetches the next row and returns it as an object - * @param string $className - * @param array $ctor_args - * @return array + * 获得结果集中的下一行,同时根据设置的类返回如果没有设置则返回的使StdClass对象 + * + * @param string $className 使用的类 + * @param array $ctor_args 初始化参数 + * @return object */ public function fetchObject($className = '', $ctor_args = array()) { if ($className === '') diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 69b10783..a66b7922 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -31,8 +31,10 @@ class WindSqlStatement { private $_columns = array(); /** - * @param WindConnection $connection - * @param string $query + * 构造函数 + * + * @param WindConnection $connection WindConnection对象 + * @param string $query 预定义语句 */ public function __construct($connection, $query) { $this->_connection = $connection; @@ -41,12 +43,14 @@ public function __construct($connection, $query) { /** * 参数绑定 - * @param string $parameter - * @param string $variable - * @param string $dataType - * @param int $length - * @param $driverOptions - * @return + * + * @param mixed $parameter 预定义语句的待绑定的位置 + * @param mixed &$variable 绑定的值 + * @param int $dataType 值的类型(PDO::PARAM_STR/PDO::PARAM_INT...) + * @param int $length 绑定值的长度 + * @param mixed $driverOptions + * @throws WindDbException + * @return WindSqlStatement */ public function bindParam($parameter, &$variable, $dataType = null, $length = null, $driverOptions = null) { try { @@ -68,9 +72,12 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu /** * 批量绑定变量 + * * 如果是一维数组,则使用key=>value的形式,key代表变量位置,value代表替换的值,而替换值需要的类型则通过该值的类型来判断---不准确 * 如果是一个二维数组,则允许,key=>array(0=>value, 1=>data_type, 2=>length, 3=>driver_options)的方式来传递变量。 + * * @param array $parameters + * @throws WindDbException * @return WindSqlStatement */ public function bindParams(&$parameters) { @@ -92,10 +99,13 @@ public function bindParams(&$parameters) { } /** - * @param string $parameter - * @param string $value - * @param int $data_type - * @return + * 参数绑定 + * + * @param string $parameter 预定义语句的待绑定的位置 + * @param string $value 绑定的值 + * @param int $data_type 值的类型 + * @throws WindDbException + * @return WindSqlStatement */ public function bindValue($parameter, $value, $data_type = null) { try { @@ -113,7 +123,11 @@ public function bindValue($parameter, $value, $data_type = null) { } /** - * @param array $values + * 调用bindValue的批量绑定参数 + * + * @param array $values 待绑定的参数值 + * @throws WindDbException + * @return WindSqlStatement */ public function bindValues($values) { if (!is_array($values)) { @@ -128,13 +142,15 @@ public function bindValues($values) { } /** - * 将列值绑定到php变量 - * @param $column - * @param $param - * @param $type - * @param $maxlen - * @param $driverdata + * 绑定输出结果集的列到PHP变量 + * + * @param mixed $column 需要被绑定的字段列表,可以是字段名,也可以是字段的对应的下标 + * @param mixed &$param 需要被绑定的php变量 + * @param int $type 参数的数据类型 PDO::PARAM_* + * @param int $maxlen A hint for pre-allocation. + * @param mixed $driverdata Optional parameter(s) for the driver. * @throws WindDbException + * @return WindSqlStatement */ public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $driverdata = null) { try { @@ -155,28 +171,38 @@ public function bindColumn($column, &$param = '', $type = null, $maxlen = null, } } + /** + * 批量绑定输出结果集的列到PHP变量 + * + * @param array $columns 待绑定的列 + * @param array &$param 需要绑定的php变量 + * @return WindSqlStatement + */ public function bindColumns($columns, &$param = array()) { $int = 0; foreach ($columns as $value) { $this->bindColumn($value, $param[$int++]); } + return $this; } /** - * 执行SQL语句,并返回更新影响行数 - * @param array $params + * 绑定参数,执行SQL语句,并返回更新影响行数 + * @param array $params 预定义语句中需要绑定的参数 * @param boolean $rowCount 是否返回影响行数 * @throws WindDbException + * @return int|boolean */ public function update($params = array(), $rowCount = false) { return $this->execute($params, $rowCount); } /** - * 执行SQL语句,并返回查询结果 - * @param array $params - * @param int $fetchMode - * @param int $fetchType + * 绑定参数,执行SQL语句,并返回查询结果 + * + * @param array $params 预定义语句中需要绑定的参数 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL * @return WindResultSet */ public function query($params = array(), $fetchMode = 0, $fetchType = 0) { @@ -185,12 +211,13 @@ public function query($params = array(), $fetchMode = 0, $fetchType = 0) { } /** - * 执行SQL语句,并返回查询结果 - * @param array $params - * @param string $index 索引 - * @param int $fetchMode - * @param int $fetchType - * @return array + * 绑定参数,执行SQL语句,并返回查询结果 + * + * @param array $params 预定义语句中需要绑定的参数 + * @param string $index 返回的数组的下标对应的字段 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL + * @return array 返回处理后的结果 */ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) { $this->execute($params, false); @@ -204,11 +231,11 @@ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchT } /** - * 执行SQL语句,并返回查询结果 - * @param array $params - * @param int $fetchMode - * @param int $fetchType - * @return string + * 绑定参数,执行SQL语句,并返回查询到的结果集中某一个列的值 + * + * @param array $params 预定义语句中需要绑定的参数 + * @param int $column 列的下标,默认为0即第一列 + * @return string */ public function getValue($params = array(), $column = 0) { $this->execute($params, false); @@ -217,10 +244,11 @@ public function getValue($params = array(), $column = 0) { } /** - * 执行SQL语句,并返回查询结果 - * @param array $params - * @param int $fetchMode - * @param int $fetchType + * 绑定参数,执行SQL语句,并返回一行查询结果 + * + * @param array $params 预定义语句中需要绑定的参数 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL * @return array */ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { @@ -231,7 +259,9 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { /** * 返回最后一条插入数据ID - * @param $name + * + * @param string $name + * @return int */ public function lastInsterId($name = '') { if ($name) @@ -241,9 +271,10 @@ public function lastInsterId($name = '') { } /** - * 执行sql,$params为变量信息,并返回结果集 - * @param array $params -- 注意:绑定的变量数组下标将从0开始索引, - * @param boolean $rowCount + * 绑定参数,执行SQL语句,并返回影响行数 + * + * @param array $params -- 绑定的参数和bindValues的参数一样 + * @param boolean $rowCount 是否返回受印象行数 * @return rowCount */ public function execute($params = array(), $rowCount = true) { @@ -263,7 +294,9 @@ public function execute($params = array(), $rowCount = true) { } /** - * @param string $queryString + * 设置查询预定义语句 + * + * @param string $queryString * @return WindSqlStatement */ public function setQueryString($queryString) { @@ -277,13 +310,17 @@ public function setQueryString($queryString) { } /** - * @return the $_queryString + * 获得查询的预定义语句 + * + * @return string $_queryString */ public function getQueryString() { return $this->_queryString; } /** + * 获得PDO链接对象 + * * @return WindConnection */ public function getConnection() { @@ -291,6 +328,8 @@ public function getConnection() { } /** + * 获得PDOStatement对象 + * * @return PDOStatement */ public function getStatement() { @@ -298,14 +337,16 @@ public function getStatement() { } /** - * @return the $_columns + * 获得需要绑定的结果输出的列值 + * + * @return array $_columns */ public function getColumns() { return $this->_columns; } /** - * @return + * 初始化数据库链接信息 */ public function init() { if ($this->_statement === null) { @@ -323,8 +364,10 @@ public function init() { } /** - * @param variable - * @param data_type + * 获得绑定参数的类型 + * + * @param string $variable + * @return int */ private function _getPdoDataType($variable) { return isset($this->_typeMap[gettype($variable)]) ? $this->_typeMap[gettype($variable)] : PDO::PARAM_STR; diff --git a/wind/component/db/mysql/WindMysqlPdoAdapter.php b/wind/component/db/mysql/WindMysqlPdoAdapter.php index e0e0de7e..4c4031ba 100644 --- a/wind/component/db/mysql/WindMysqlPdoAdapter.php +++ b/wind/component/db/mysql/WindMysqlPdoAdapter.php @@ -6,7 +6,11 @@ * @package */ class WindMysqlPdoAdapter extends PDO { - + + /** + * 设置链接使用字符集 + * @param string $charset + */ public function setCharset($charset) { if (!$charset) $charset = 'gbk'; $this->query("set names " . $this->quote($charset) . ";"); From 4b71a0c1d67e6893ed46fca1145f4b7d57f0397d Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 14 Jul 2011 08:39:28 +0000 Subject: [PATCH 0088/1065] =?UTF-8?q?NEW=20-=20bug=20152:=20WindConnection?= =?UTF-8?q?=E4=B8=AD=E4=BD=BF=E7=94=A8=E8=AE=B0=E5=BD=95=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E7=9A=84bug=20http://bugs.phpwind-inc.com/show=5Fbug.cgi=3Fid?= =?UTF-8?q?=3D152?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2141 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 737b7eec..a5f30853 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -208,7 +208,7 @@ public function init() { $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->_dbHandle->setCharset($this->_charset); - Wind::log("component.db.WindConnection._init() \r\n dsn: " . $this->_dsn() . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, WindLogger::LEVEL_DEBUG); + Wind::log("component.db.WindConnection._init() \r\n dsn: " . $this->_dsn . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, WindLogger::LEVEL_DEBUG); } catch (PDOException $e) { $this->close(); Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", WindLogger::LEVEL_TRACE); From f691d10279b932f8487e9174f11d14fe4e07e73d Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 15 Jul 2011 02:05:15 +0000 Subject: [PATCH 0089/1065] =?UTF-8?q?=E5=BA=94=E7=94=A8=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2143 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/ini/db_config.ini | 12 +++---- docs/configtemplate/ini/wind_config.ini | 21 ++++++++++--- docs/configtemplate/php/wind_config.php | 31 ++++++++++--------- .../properties/wind_config.properties | 21 ++++++++++--- docs/configtemplate/wind_config.xml | 10 ++++-- 5 files changed, 62 insertions(+), 33 deletions(-) diff --git a/docs/configtemplate/ini/db_config.ini b/docs/configtemplate/ini/db_config.ini index 4a7a05b6..863c976b 100644 --- a/docs/configtemplate/ini/db_config.ini +++ b/docs/configtemplate/ini/db_config.ini @@ -1,10 +1,6 @@ ;dbConfig的配置信息 ;可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 -myConnection.driver=mysql -myConnection.type=master -myConnection.host=localhost -myConnection.user=root -myConnection.password= -myConnection.port=3306 -myConnection.name=phpwind -myConnection.charset=utf8 +connection.dsn=mysql:host=localhost;dbname=p9 +connection.user=xxx +connection.pwd=xxx +connection.charset=utf8 diff --git a/docs/configtemplate/ini/wind_config.ini b/docs/configtemplate/ini/wind_config.ini index 64c3d0f5..513531af 100644 --- a/docs/configtemplate/ini/wind_config.ini +++ b/docs/configtemplate/ini/wind_config.ini @@ -3,8 +3,19 @@ ;default:为应用的name default.class=windWebApp default.root-path= -;配置default应用的路径规则 -;配置default应用的路由配置信息,module配置 + +;工厂配置 +default.factory.class-definition=components +default.factory.class=WIND:core.factory.WindComponentFactory + +;过滤链配置 +default.filters.class=WIND:core.filter.WindFilterChain +default.filters.filter1.class=WIND:core.web.filter.WindLoggerFilter +default.filters.filter2.class=WIND:core.web.filter.WindUrlFilter + +;配置default应用的路由配置信息, +default.router.class=urlBasedRouter +;module配置 default.router.config.module.url-param=m default.router.config.module.default-value=default ;controller配置 @@ -18,11 +29,13 @@ default.router.config.action.default-value=run ;如下,配置了一个名为default的模块,及该default模块下该有的一些配置项信息 ;default模块的路径信息 default.modules.default.path=controller -;default模块的error controller类 -default.modules.default.error-handler.class=WIND:core.web.WindErrorHandler ;default模块的controller后缀信息 default.modules.default.controller-suffix.value=Controller +;default模块的error controller类 +default.modules.default.error-handler.class=WIND:core.web.WindErrorHandler + ;default模块的视图配置 +default.modules.default.view.class=windView ;模板文件路径 default.modules.default.view.config.template-dir.value=template ;模板后缀 diff --git a/docs/configtemplate/php/wind_config.php b/docs/configtemplate/php/wind_config.php index 06833ba5..07501248 100644 --- a/docs/configtemplate/php/wind_config.php +++ b/docs/configtemplate/php/wind_config.php @@ -11,8 +11,18 @@ 'default' => array( 'class' => 'windWebApp', 'root-path' => '', + 'factory' => array( + 'class-definition' => 'components', + 'class' => 'WIND:core.factory.WindComponentFactory', + ), + 'filters' => array( + 'class' => 'WIND:core.filter.WindFilterChain', + 'filter1' => array('class' => 'WIND:core.web.filter.WindLoggerFilter'), + 'filter2' => array('class' => 'WIND:core.web.filter.WindUrlFilter'), + ), /*配置default应用的路由规则*/ 'router' => array( + 'class' => 'urlBasedRouter', 'config' => array( /*配置路径中module的规则*/ 'module' => array( @@ -38,28 +48,19 @@ /*default模块的路径*/ 'path' => 'controller', /*default模块的中controller的后缀*/ - 'controller-suffix' => array( - 'value' => 'controller', - ), + 'controller-suffix' => array('value' => 'Controller',), /*default模块中处理error的Action controller路径*/ - 'error-handler' => array( - 'class' => 'WIND:core.web.WindErrorHandler', - ), + 'error-handler' => array('class' => 'WIND:core.web.WindErrorHandler',), /*default模块的试图配置*/ 'view' => array( + 'class' => 'windView', 'config' => array( /*模板路径*/ - 'template-dir' => array( - 'value' => 'template', - ), + 'template-dir' => array('value' => 'template',), /*模板后缀*/ - 'template-ext' => array( - 'value' => 'htm', - ), + 'template-ext' => array('value' => 'htm',), /*模板编译路径*/ - 'compile-dir' => array( - 'value' => 'compile.template', - ), + 'compile-dir' => array('value' => 'compile.template',), ), ), ), diff --git a/docs/configtemplate/properties/wind_config.properties b/docs/configtemplate/properties/wind_config.properties index 10c7433c..927586eb 100644 --- a/docs/configtemplate/properties/wind_config.properties +++ b/docs/configtemplate/properties/wind_config.properties @@ -3,8 +3,19 @@ #default:为应用的name default.class=windWebApp default.root-path= -#配置default应用的路径规则 -#配置default应用的路由配置信息,module配置 + +#工厂配置 +default.factory.class-definition=components +default.factory.class=WIND:core.factory.WindComponentFactory + +#过滤链配置 +default.filters.class=WIND:core.filter.WindFilterChain +default.filters.filter1.class=WIND:core.web.filter.WindLoggerFilter +default.filters.filter2.class=WIND:core.web.filter.WindUrlFilter + +#配置default应用的路由配置信息, +default.router.class=urlBasedRouter +#module配置 default.router.config.module.url-param=m default.router.config.module.default-value=default #controller配置 @@ -18,11 +29,13 @@ default.router.config.action.default-value=run #如下,配置了一个名为default的模块,及该default模块下该有的一些配置项信息 #default模块的路径信息 default.modules.default.path=controller -#default模块的error controller类 -default.modules.default.error-handler.class=WIND:core.web.WindErrorHandler #default模块的controller后缀信息 default.modules.default.controller-suffix.value=Controller +#default模块的error controller类 +default.modules.default.error-handler.class=WIND:core.web.WindErrorHandler + #default模块的视图配置 +default.modules.default.view.class=windView #模板文件路径 default.modules.default.view.config.template-dir.value=template #模板后缀 diff --git a/docs/configtemplate/wind_config.xml b/docs/configtemplate/wind_config.xml index d43dc009..5860357d 100644 --- a/docs/configtemplate/wind_config.xml +++ b/docs/configtemplate/wind_config.xml @@ -9,8 +9,14 @@ root-path: 指定该应用的入口地址 --> + + + + + - + @@ -33,7 +39,7 @@ - + From 7f12704fecf35dfc6ef2d3d552060d5c3729faef Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 15 Jul 2011 02:05:34 +0000 Subject: [PATCH 0090/1065] =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2144 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/parser/WindIniParser.php | 2 +- wind/component/parser/WindPropertiesParser.php | 2 +- wind/core/config/parser/WindConfigParser.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/component/parser/WindIniParser.php b/wind/component/parser/WindIniParser.php index 91997407..c9a8974d 100644 --- a/wind/component/parser/WindIniParser.php +++ b/wind/component/parser/WindIniParser.php @@ -85,7 +85,7 @@ public function formatDataArray(&$original, &$data = array()) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } - $this->formatDataArray($tValue, &$data[$tkey]); + $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } diff --git a/wind/component/parser/WindPropertiesParser.php b/wind/component/parser/WindPropertiesParser.php index 9f4f7a65..67479af4 100644 --- a/wind/component/parser/WindPropertiesParser.php +++ b/wind/component/parser/WindPropertiesParser.php @@ -133,7 +133,7 @@ public function formatDataArray(&$original, &$data = array()) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } - $this->formatDataArray($tValue, &$data[$tkey]); + $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } diff --git a/wind/core/config/parser/WindConfigParser.php b/wind/core/config/parser/WindConfigParser.php index c7bdae44..32403d9d 100644 --- a/wind/core/config/parser/WindConfigParser.php +++ b/wind/core/config/parser/WindConfigParser.php @@ -59,7 +59,7 @@ public function parse($configPath, $alias = '', $append = '') { $append = !$append ? '' : trim($append); $alias && $cacheFileName = ($append ? $this->buildCacheFilePath($append) : $this->buildCacheFilePath($alias)); if ($alias) { - $append && $config = $this->getCacheContent($cacheFileName); + $config = $this->getCacheContent($cacheFileName); if (isset($config[$alias]) && !$this->needCompiled()) { return $config[$alias]; } From 4c06449dd5a037f6409cff09f4f92d66576b479f Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 15 Jul 2011 02:16:02 +0000 Subject: [PATCH 0091/1065] =?UTF-8?q?DB=E9=85=8D=E7=BD=AE=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2145 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/db_config.xml | 20 +++++++------------ docs/configtemplate/ini/db_config.ini | 7 ++++--- docs/configtemplate/php/db_config.php | 11 ++++------ .../properties/db_config.properties | 13 +++++------- 4 files changed, 20 insertions(+), 31 deletions(-) diff --git a/docs/configtemplate/db_config.xml b/docs/configtemplate/db_config.xml index 46e52d46..0343c17a 100644 --- a/docs/configtemplate/db_config.xml +++ b/docs/configtemplate/db_config.xml @@ -1,15 +1,9 @@ - - - mysql - master - localhost - root - - 3306 - phpwind - utf8 - - - + + mysql:host=localhost;dbname=test + root + root + utf8 + pw_ + diff --git a/docs/configtemplate/ini/db_config.ini b/docs/configtemplate/ini/db_config.ini index 863c976b..c9d37049 100644 --- a/docs/configtemplate/ini/db_config.ini +++ b/docs/configtemplate/ini/db_config.ini @@ -1,6 +1,7 @@ ;dbConfig的配置信息 ;可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 -connection.dsn=mysql:host=localhost;dbname=p9 -connection.user=xxx -connection.pwd=xxx +connection.dsn=mysql:host=localhost;dbname=test +connection.user=root +connection.pwd=root connection.charset=utf8 +connection.tablePrefix=pw_ diff --git a/docs/configtemplate/php/db_config.php b/docs/configtemplate/php/db_config.php index df364c20..9deab458 100644 --- a/docs/configtemplate/php/db_config.php +++ b/docs/configtemplate/php/db_config.php @@ -10,14 +10,11 @@ * 可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 */ return array( - 'myConnection' => array( - 'driver' => 'mysql', - 'host' => 'localhost', - 'type' => 'master', + 'connection' => array( + 'dsn' => 'mysql:host=localhost;dbname=test', 'user' => 'root', - 'password' => '', - 'port' => '3306', - 'name' => 'phpwind', + 'pwd' => 'root', 'charset' => 'utf8', + 'tablePrefix' => 'pw_' ), ); \ No newline at end of file diff --git a/docs/configtemplate/properties/db_config.properties b/docs/configtemplate/properties/db_config.properties index f983f053..82b27b5a 100644 --- a/docs/configtemplate/properties/db_config.properties +++ b/docs/configtemplate/properties/db_config.properties @@ -1,10 +1,7 @@ #dbconfig的配置 #可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 -myConnection.driver=mysql -myConnection.type=master -myConnection.host=localhost -myConnection.user=root -myConnection.password= -myConnection.port=3306 -myConnection.name=phpwind -myConnection.charset=utf8 +connection.dsn=mysql:host=localhost;dbname=test +connection.user=root +connection.pwd=root +connection.charset=utf8 +connection.tablePrefix=pw_ From 5c5e521c503dcfc9e00b63f5276cf5c4ec354e7f Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 15 Jul 2011 04:28:55 +0000 Subject: [PATCH 0092/1065] =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E8=A7=A3=E6=9E=90bug=E4=BF=AE=E5=A4=8D=EF=BC=8Cproperties?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=BC=95=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2146 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/parser/WindPropertiesParser.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/wind/component/parser/WindPropertiesParser.php b/wind/component/parser/WindPropertiesParser.php index 67479af4..074119c6 100644 --- a/wind/component/parser/WindPropertiesParser.php +++ b/wind/component/parser/WindPropertiesParser.php @@ -36,6 +36,10 @@ public function parse($filename, $process = true, $build = true) { return $build ? $this->buildData($data) : $data; } + private function delComment($filename, $process) { + + } + /** * 载入一个由 filename 指定的 properties 文件, * 并将其中的设置作为一个联合数组返回。 @@ -61,7 +65,7 @@ public function parse_properties_file($filename, $process = true) { if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } - $tmp = explode('=', $value); + $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); @@ -71,7 +75,7 @@ public function parse_properties_file($filename, $process = true) { continue; } $tmp[0] = trim($tmp[0]); - $tmp[1] = trim($tmp[1]); + $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; From 8891b4f156305c79a4dad7bb8402853a466e9a49 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 15 Jul 2011 04:34:55 +0000 Subject: [PATCH 0093/1065] =?UTF-8?q?DB=E9=85=8D=E7=BD=AE=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2147 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/ini/db_config.ini | 12 ++++++------ docs/configtemplate/php/db_config.php | 12 +++++------- docs/configtemplate/properties/db_config.properties | 11 +++++------ 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/docs/configtemplate/ini/db_config.ini b/docs/configtemplate/ini/db_config.ini index c9d37049..0caf4e56 100644 --- a/docs/configtemplate/ini/db_config.ini +++ b/docs/configtemplate/ini/db_config.ini @@ -1,7 +1,7 @@ ;dbConfig的配置信息 -;可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 -connection.dsn=mysql:host=localhost;dbname=test -connection.user=root -connection.pwd=root -connection.charset=utf8 -connection.tablePrefix=pw_ + +dsn='mysql:host=localhost;dbname=test' +user=root +pwd=root +charset=utf8 +tablePrefix=pw_ diff --git a/docs/configtemplate/php/db_config.php b/docs/configtemplate/php/db_config.php index 9deab458..094ebbf0 100644 --- a/docs/configtemplate/php/db_config.php +++ b/docs/configtemplate/php/db_config.php @@ -10,11 +10,9 @@ * 可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 */ return array( - 'connection' => array( - 'dsn' => 'mysql:host=localhost;dbname=test', - 'user' => 'root', - 'pwd' => 'root', - 'charset' => 'utf8', - 'tablePrefix' => 'pw_' - ), + 'dsn' => 'mysql:host=localhost;dbname=test', + 'user' => 'root', + 'pwd' => 'root', + 'charset' => 'utf8', + 'tablePrefix' => 'pw_' ); \ No newline at end of file diff --git a/docs/configtemplate/properties/db_config.properties b/docs/configtemplate/properties/db_config.properties index 82b27b5a..bbb147a2 100644 --- a/docs/configtemplate/properties/db_config.properties +++ b/docs/configtemplate/properties/db_config.properties @@ -1,7 +1,6 @@ #dbconfig的配置 -#可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 -connection.dsn=mysql:host=localhost;dbname=test -connection.user=root -connection.pwd=root -connection.charset=utf8 -connection.tablePrefix=pw_ +dsn='mysql:host=localhost;dbname=test' +user=root +pwd=root +charset=utf8 +tablePrefix=pw_ From 831b3cce3db1cef48af0b91746bc49dc5fd515b7 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 15 Jul 2011 10:40:08 +0000 Subject: [PATCH 0094/1065] =?UTF-8?q?DB=20=20=E6=B7=BB=E5=8A=A0=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BD=9E=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2149 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 13 +++++++--- .../db/mysql/WindMysqlPdoAdapter.php | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index a5f30853..3f27f663 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -163,21 +163,26 @@ public function query($sql) { } } - /** - * (non-PHPdoc) + /* (non-PHPdoc) * @see WindMysqlPdoAdapter::filterArray() */ public function quoteArray($array) { return $this->getDbHandle()->filterArray($array); } - /** - * (non-PHPdoc) + /* (non-PHPdoc) * @see WindMysqlPdoAdapter::quote() */ public function quote($string) { return $this->getDbHandle()->quote($string); } + + /* (non-PHPdoc) + * @see WindMysqlPdoAdapter::sqlSingle() + */ + public function sqlSingle($array) { + return $this->getDbHandle()->sqlSingle($array); + } /** * 关闭数据库连接 diff --git a/wind/component/db/mysql/WindMysqlPdoAdapter.php b/wind/component/db/mysql/WindMysqlPdoAdapter.php index 4c4031ba..472b3a8b 100644 --- a/wind/component/db/mysql/WindMysqlPdoAdapter.php +++ b/wind/component/db/mysql/WindMysqlPdoAdapter.php @@ -40,5 +40,30 @@ public function filterArray($variable, $result = '') { } return $result; } + + /** + * 组装单条 key=value 形式的SQL查询语句值 insert/update + * @param $array + * @param $strip + * @return string + */ + public function sqlSingle($array) { + if (!is_array($array)) return ''; + $str = ''; + foreach ($array as $key => $val) { + $str .= ($str ? ', ' : ' ') . $this->fieldMeta($key) . '=' . $this->quote($val); + } + return $str; + } + + /** + * 过滤SQL元数据,数据库对象(如表名字,字段等) + * @param $data 元数据 + * @return string 经过转义的元数据字符串 + */ + private function fieldMeta($data) { + $data = str_replace(array('`', ' '), '',$data); + return ' `'.$data.'` '; + } } ?> \ No newline at end of file From 25a04c7cf814855b485c21e69397939018a7a2d0 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 15 Jul 2011 10:40:20 +0000 Subject: [PATCH 0095/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2150 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/utility/WindSecurity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/utility/WindSecurity.php b/wind/component/utility/WindSecurity.php index 974c76ca..6f046699 100644 --- a/wind/component/utility/WindSecurity.php +++ b/wind/component/utility/WindSecurity.php @@ -238,7 +238,7 @@ public static function sqlMulti($array, $strip = true) { * @return string 经过转义的元数据字符串 */ public static function sqlMetadata($data ,$tlists=array()) { - if (empty($tlists) || !is_array($data , $tlists)) { + if (empty($tlists) || !in_array($data , $tlists)) { $data = str_replace(array('`', ' '), '',$data); } return ' `'.$data.'` '; From f0601936f1fedfc8658a01fb2d945c4c05104acd Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 18 Jul 2011 05:26:10 +0000 Subject: [PATCH 0096/1065] =?UTF-8?q?WindConnection=E4=B8=AD=E6=8F=90?= =?UTF-8?q?=E4=BE=9BlastInsertId=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2151 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 13 +++++++++++++ wind/component/db/WindSqlStatement.php | 12 +++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 3f27f663..cc03f870 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -183,6 +183,19 @@ public function quote($string) { public function sqlSingle($array) { return $this->getDbHandle()->sqlSingle($array); } + + /** + * 返回最后一条插入数据ID + * + * @param string $name + * @return int + */ + public function lastInsterId($name = '') { + if ($name) + return $this->getDbHandle()->lastInsertId($name); + else + return $this->getDbHandle()->lastInsertId(); + } /** * 关闭数据库连接 diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index a66b7922..8eb663c7 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -257,17 +257,11 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { return $rs->fetch(); } - /** - * 返回最后一条插入数据ID - * - * @param string $name - * @return int + /* (non-PHPdoc) + * @see WindConnection::lastInsterId() */ public function lastInsterId($name = '') { - if ($name) - return $this->getConnection()->getDbHandle()->lastInsertId($name); - else - return $this->getConnection()->getDbHandle()->lastInsertId(); + return $this->getConnection($name); } /** From cb2e1a756919731abc947605f9ff30cecfb8b3f5 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 18 Jul 2011 06:57:26 +0000 Subject: [PATCH 0097/1065] =?UTF-8?q?WindConnection=E4=B8=AD=E8=B0=83?= =?UTF-8?q?=E7=94=A8WindResult?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2153 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index cc03f870..46a384ea 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -1,5 +1,7 @@ * @version $Id$ From e23ffa44813ae913a92a8a62565aeda3808f3d76 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 18 Jul 2011 08:43:16 +0000 Subject: [PATCH 0098/1065] =?UTF-8?q?WindResultSet=E4=B8=AD=E8=B0=83?= =?UTF-8?q?=E7=94=A8FetchAll=E6=B7=BB=E5=8A=A0=E4=B8=8B=E6=A0=87=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2155 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 2855a277..73022000 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -102,15 +102,16 @@ private function _fetch($fetchMode, $fetchType) { /** * 返回所有的查询结果 * + * @param string $index 输出数组下标 * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM * @return array */ - public function fetchAll($fetchMode = 0) { + public function fetchAll($index = '', $fetchMode = 0) { if ($fetchMode === 0) $fetchMode = $this->_fetchMode; if (empty($this->_columns)) return $this->_statement->fetchAll($fetchMode); $result = array(); while ($row = $this->fetch($fetchMode)) - $result[] = $row; + isset($row[$index]) ? $result[$row[$index]] = $row : $result[] = $row; return $result; } From 9c04d63af08f8e17c22d4dab7047077f32d5d301 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 18 Jul 2011 08:46:12 +0000 Subject: [PATCH 0099/1065] =?UTF-8?q?WindResultSet=E4=B8=AD=E8=B0=83?= =?UTF-8?q?=E7=94=A8FetchAll=E6=B7=BB=E5=8A=A0=E4=B8=8B=E6=A0=87=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2156 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindSqlStatement.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 8eb663c7..faab768c 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -222,12 +222,7 @@ public function query($params = array(), $fetchMode = 0, $fetchType = 0) { public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) { $this->execute($params, false); $rs = new WindResultSet($this, $fetchMode, $fetchType); - if (!$index) return $rs->fetchAll(); - $result = array(); - while ($one = $rs->fetch()) { - isset($one[$index]) ? $result[$one[$index]] = $one : $result[] = $one; - } - return $result; + return $rs->fetchAll($index); } /** From 7b39568c8fe371e0aa725c3e8b84d98c0127cc04 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 18 Jul 2011 08:58:23 +0000 Subject: [PATCH 0100/1065] =?UTF-8?q?WindResultSet=E4=B8=AD=E8=B0=83?= =?UTF-8?q?=E7=94=A8FetchAll=E6=B7=BB=E5=8A=A0=E4=B8=8B=E6=A0=87=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2157 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 73022000..07bce006 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -108,7 +108,7 @@ private function _fetch($fetchMode, $fetchType) { */ public function fetchAll($index = '', $fetchMode = 0) { if ($fetchMode === 0) $fetchMode = $this->_fetchMode; - if (empty($this->_columns)) return $this->_statement->fetchAll($fetchMode); + if (!empty($this->_columns)) return $this->_statement->fetchAll($fetchMode); $result = array(); while ($row = $this->fetch($fetchMode)) isset($row[$index]) ? $result[$row[$index]] = $row : $result[] = $row; From 94755bf381474672d8eaa19b53ac3e359fa6664c Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 18 Jul 2011 09:04:45 +0000 Subject: [PATCH 0101/1065] =?UTF-8?q?WindResultSet=E4=B8=AD=E8=B0=83?= =?UTF-8?q?=E7=94=A8FetchAll=E6=B7=BB=E5=8A=A0=E4=B8=8B=E6=A0=87=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2158 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 07bce006..66cb024e 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -108,7 +108,7 @@ private function _fetch($fetchMode, $fetchType) { */ public function fetchAll($index = '', $fetchMode = 0) { if ($fetchMode === 0) $fetchMode = $this->_fetchMode; - if (!empty($this->_columns)) return $this->_statement->fetchAll($fetchMode); + if ('' === $index) return $this->_statement->fetchAll($fetchMode); $result = array(); while ($row = $this->fetch($fetchMode)) isset($row[$index]) ? $result[$row[$index]] = $row : $result[] = $row; From 336286c8503aa807d0a98ca65bfe2e9bc5403da8 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 18 Jul 2011 09:27:04 +0000 Subject: [PATCH 0102/1065] =?UTF-8?q?comment/upload/WindFormUpload=20=20bu?= =?UTF-8?q?g=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2159 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindFormUpload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index c753ad7a..0963b43b 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -42,7 +42,7 @@ public function upload($saveDir, $preFileName = '', $allowType = array()) { $this->hasError = true; continue; } - if ($upload['size'] < 1 || $upload['size'] > $allowType[$upload['ext']]) { + if ($upload['size'] < 1 || ($allowType && $upload['size'] > $allowType[$upload['ext']])) { $upload['maxSize'] = $allowType[$upload['ext']]; $error['size'][] = $upload; $this->hasError = true; From c521457fe3acf612aa64191c66fc12e1357f7443 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 06:27:09 +0000 Subject: [PATCH 0103/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2161 18ba2127-5a84-46d4-baec-3457e417f034 --- .../helloworld/controller/IndexController.php | 19 -- demos/helloworld/index.php | 7 - wind/Wind.php | 131 +++++-- wind/_compile/compile.php | 32 ++ wind/{ => _compile}/components_config.xml | 27 +- wind/_compile/wind_imports.php | 44 +++ wind/component/cache/AbstractWindCache.php | 14 +- .../cache}/exception/WindCacheException.php | 0 wind/component/cache/strategy/WindCacheDb.php | 4 +- .../component/cache/strategy/WindCacheMem.php | 4 +- wind/component/dao/WindDao.php | 109 +++--- wind/component/dao/WindDaoFactory.php | 120 ++++--- .../dao}/exception/WindDaoException.php | 0 wind/component/db/WindConnection.php | 16 +- wind/component/db/WindConnectionManager.php | 2 +- wind/component/db/WindSqlStatement.php | 44 ++- wind/component/log/WindLogger.php | 122 +++---- wind/component/utility/WindFile.php | 19 +- wind/component/utility/WindUtility.php | 37 +- .../viewer/AbstractWindTemplateCompiler.php | 58 ++-- .../viewer/AbstractWindViewTemplate.php | 50 +-- .../viewer/IWindViewerResolver.php | 7 - .../{core => component}/viewer/WindLayout.php | 0 wind/component/viewer/WindView.php | 231 +++++++++++++ wind/component/viewer/WindViewerResolver.php | 153 +++++++++ .../compiler/WindTemplateCompilerAction.php | 49 +++ .../WindTemplateCompilerComponent.php | 3 +- .../compiler/WindTemplateCompilerEcho.php | 7 +- .../compiler/WindTemplateCompilerInternal.php | 4 +- .../compiler/WindTemplateCompilerPage.php | 48 ++- .../compiler/WindTemplateCompilerScript.php | 5 +- .../compiler/WindTemplateCompilerTemplate.php | 21 +- .../viewer/compiler/WindViewTemplate.php | 100 +++--- .../viewer}/exception/WindViewException.php | 7 +- .../viewer/listener/WindViewCacheListener.php | 0 wind/components_config.php | 129 +++++-- wind/core/AbstractWindServer.php | 159 --------- wind/core/WindComponentModule.php | 101 ------ wind/core/WindEnableValidateModule.php | 185 +++++----- wind/core/WindHelper.php | 2 +- wind/core/WindModule.php | 271 +++++++++++---- wind/core/config/WindConfig.php | 17 +- wind/core/config/WindSystemConfig.php | 113 ++++-- wind/core/config/parser/WindConfigParser.php | 7 +- wind/core/exception/WindActionException.php | 5 - wind/core/exception/WindException.php | 27 +- wind/core/exception/WindSqlException.php | 119 ------- wind/core/factory/IWindFactory.php | 19 +- wind/core/factory/WindClassDefinition.php | 322 +++++++++++------- wind/core/factory/WindComponentDefinition.php | 144 -------- wind/core/factory/WindComponentFactory.php | 18 - wind/core/factory/WindFactory.php | 131 +++---- wind/core/factory/proxy/IWindClassProxy.php | 8 - wind/core/factory/proxy/WindClassProxy.php | 141 ++++---- wind/core/filter/WindHandlerInterceptor.php | 25 +- .../filter/WindHandlerInterceptorChain.php | 35 +- wind/core/request/WindHttpRequest.php | 198 ++++++----- wind/core/response/WindHttpResponse.php | 117 +++---- wind/core/router/AbstractWindRouter.php | 163 +++++---- wind/core/router/WindUrlBasedRouter.php | 60 +--- wind/core/viewer/WindView.php | 226 ------------ wind/core/viewer/WindViewerResolver.php | 139 -------- .../compiler/WindTemplateCompilerAction.php | 53 --- wind/core/web/IWindApplication.php | 7 +- wind/core/web/WindController.php | 62 ---- wind/core/web/WindDispatcher.php | 210 +++++++----- wind/core/web/WindErrorHandler.php | 36 +- wind/core/web/WindErrorMessage.php | 4 +- wind/core/web/WindFormController.php | 56 --- wind/core/web/WindForward.php | 173 +++++++--- wind/core/web/WindFrontController.php | 189 +++++----- wind/core/web/WindUrlHelper.php | 24 +- wind/core/web/WindWebApplication.php | 170 +++------ wind/core/web/controller/IWindController.php | 31 ++ wind/core/web/controller/WindController.php | 105 ++++++ .../WindSimpleController.php} | 218 ++++++------ 76 files changed, 2843 insertions(+), 2870 deletions(-) delete mode 100644 demos/helloworld/controller/IndexController.php delete mode 100644 demos/helloworld/index.php create mode 100644 wind/_compile/compile.php rename wind/{ => _compile}/components_config.xml (72%) create mode 100644 wind/_compile/wind_imports.php rename wind/{core => component/cache}/exception/WindCacheException.php (100%) rename wind/{core => component/dao}/exception/WindDaoException.php (100%) rename wind/{core => component}/viewer/AbstractWindTemplateCompiler.php (94%) rename wind/{core => component}/viewer/AbstractWindViewTemplate.php (57%) rename wind/{core => component}/viewer/IWindViewerResolver.php (74%) rename wind/{core => component}/viewer/WindLayout.php (100%) create mode 100644 wind/component/viewer/WindView.php create mode 100644 wind/component/viewer/WindViewerResolver.php create mode 100644 wind/component/viewer/compiler/WindTemplateCompilerAction.php rename wind/{core => component}/viewer/compiler/WindTemplateCompilerComponent.php (93%) rename wind/{core => component}/viewer/compiler/WindTemplateCompilerEcho.php (91%) rename wind/{core => component}/viewer/compiler/WindTemplateCompilerInternal.php (87%) rename wind/{core => component}/viewer/compiler/WindTemplateCompilerPage.php (68%) rename wind/{core => component}/viewer/compiler/WindTemplateCompilerScript.php (89%) rename wind/{core => component}/viewer/compiler/WindTemplateCompilerTemplate.php (79%) rename wind/{core => component}/viewer/compiler/WindViewTemplate.php (71%) rename wind/{core => component/viewer}/exception/WindViewException.php (70%) rename wind/{core => component}/viewer/listener/WindViewCacheListener.php (100%) delete mode 100644 wind/core/AbstractWindServer.php delete mode 100644 wind/core/WindComponentModule.php delete mode 100644 wind/core/exception/WindSqlException.php delete mode 100644 wind/core/factory/WindComponentDefinition.php delete mode 100644 wind/core/factory/WindComponentFactory.php delete mode 100644 wind/core/viewer/WindView.php delete mode 100644 wind/core/viewer/WindViewerResolver.php delete mode 100644 wind/core/viewer/compiler/WindTemplateCompilerAction.php delete mode 100644 wind/core/web/WindController.php delete mode 100644 wind/core/web/WindFormController.php create mode 100644 wind/core/web/controller/IWindController.php create mode 100644 wind/core/web/controller/WindController.php rename wind/core/web/{WindAction.php => controller/WindSimpleController.php} (63%) diff --git a/demos/helloworld/controller/IndexController.php b/demos/helloworld/controller/IndexController.php deleted file mode 100644 index aaacbe8c..00000000 --- a/demos/helloworld/controller/IndexController.php +++ /dev/null @@ -1,19 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class IndexController extends WindController { - - public function run() { - echo 'Hello world'; - exit(); - } - -} -?> \ No newline at end of file diff --git a/demos/helloworld/index.php b/demos/helloworld/index.php deleted file mode 100644 index 4010fabc..00000000 --- a/demos/helloworld/index.php +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/wind/Wind.php b/wind/Wind.php index 18dfe17a..c10da5ad 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -6,12 +6,12 @@ !defined('D_S') && define('D_S', DIRECTORY_SEPARATOR); !defined('WIND_PATH') && define('WIND_PATH', dirname(__FILE__) . D_S); !defined('COMPILE_PATH') && define('COMPILE_PATH', WIND_PATH . D_S); -!defined('COMPILE_LIBRARY_PATH') && define('COMPILE_LIBRARY_PATH', WIND_PATH . 'windBasic.php'); +!defined('COMPILE_LIBRARY_PATH') && define('COMPILE_LIBRARY_PATH', WIND_PATH . 'wind_basic.php'); /* debug/log */ !defined('IS_DEBUG') && define('IS_DEBUG', 1); !defined('DEBUG_TIME') && define('DEBUG_TIME', microtime(true)); !defined('LOG_DIR') && define('LOG_DIR', COMPILE_PATH . 'log'); -!defined('LOG_WRITE_LEVEL') && define('LOG_WRITE_LEVEL', 1); +!defined('LOG_WRITE_LEVEL') && define('LOG_WRITE_LEVEL', 2); /** * the last known user to change this file in the repository <$LastChangedBy: yishuo $> * @author Qiong Wu @@ -19,25 +19,68 @@ * @package */ class Wind { + private static $_extensions = 'php'; + private static $_isAutoLoad = true; + private static $_logger = null; private static $_namespace = array(); private static $_imports = array(); private static $_classes = array(); - private static $_instances = array(); - private static $_extensions = 'php'; private static $_includePaths = array(); - private static $_isAutoLoad = true; - private static $_logger = null; + private static $_app = array(); + private static $_currentApp = array(); /** * 加载应用 + * * @param string $appName * @param string $config * @throws WindException * @return */ - public static function run($appName = '', $config = '') { - $frontController = new WindFrontController($appName, $config); - $frontController->run(); + public static function run($appName = 'default', $config = '') { + self::beforRun(); + if (!isset(self::$_app[$appName])) { + $frontController = new WindFrontController($appName, $config); + /* 将当前的app压入数组的开始 */ + $_cache = self::getAppName(); + array_unshift(self::$_currentApp, array($appName, $_cache)); + self::$_app[$appName] = $frontController; + } + self::getApp()->run(); + self::afterRun(); + } + + /** + * 返回当前appName + * + * @return string + */ + public static function getAppName() { + if (!isset(self::$_currentApp[0])) return ''; + return self::$_currentApp[0][0]; + } + + /** + * 返回当前的app应用 + * + * @param string $appName + * @return WindFrontController + */ + public static function getApp() { + $_appName = self::getAppName(); + if (isset(self::$_app[$_appName])) + return self::$_app[$_appName]; + else + throw new WindException('[wind.getApp] get application ' . $_appName . ' fail.', + WindException::ERROR_CLASS_NOT_EXIST); + } + + /** + * 开发环境脚本入口 + */ + public static function runWithCompile($appName = 'default', $config = '') { + require_once (self::getRealPath('WIND:_compile.compile.php')); + self::run($appName, $config); } /** @@ -178,22 +221,6 @@ public static function getRealPath($filePath, $isDir = false) { return $suffix ? $filePath . '.' . $suffix : $filePath; } - /** - * 将核心库文件打包 - * @throws Exception - * @return - */ - public static function perLoadCoreLibrary($libPath) { - self::import('COM:utility.WindPack'); - $pack = new WindPack(); - $fileList = array(); - foreach (self::$_imports as $key => $value) { - $_key = self::getRealPath($key . '.' . self::$_extensions); - $fileList[$_key] = array($key, $value); - } - $pack->packFromFileList($fileList, $libPath, WindPack::STRIP_PHP, true); - } - /** * 初始化框架 */ @@ -249,6 +276,52 @@ public static function getLogger() { return self::$_logger; } + /** + * 清理Wind import变量信息 + * @return + */ + public static function clear() { + self::$_imports = array(); + self::$_classes = array(); + } + + /** + * 重置当前应用 + * + * @return + */ + protected static function resetApp() { + if (!isset(self::$_currentApp[0])) return; + $_current = self::$_currentApp[0]; + if ($_current[1] === '') return; + foreach (self::$_currentApp as $key => $value) { + if ($value[0] == $_current[1]) { + array_unshift(self::$_currentApp, $value); + unset(self::$_currentApp[$key]); + } + } + } + + /** + * @return + */ + protected static function beforRun() { + self::profileBegin('WINDAPP', 'wind app run time profiles!', 'wind.profile'); + set_error_handler(array(new WindErrorHandler(), 'errorHandle'), error_reporting()); + set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); + } + + /** + * @return + */ + protected static function afterRun() { + self::resetApp(); + restore_error_handler(); + restore_exception_handler(); + self::profileEnd('WINDAPP'); + self::getLogger()->flush(); + } + /** * 系统命名空间注册方法 * @return @@ -263,7 +336,8 @@ private static function _setDefaultSystemNamespace() { * @return */ private static function _checkEnvironment() { - if (!self::_checkPhpVersion()) throw new Exception('php version is too old, php ' . PHPVERSION . ' or later.', E_WARNING); + if (!self::_checkPhpVersion()) throw new Exception('php version is too old, php ' . PHPVERSION . ' or later.', + E_WARNING); if (!defined('COMPILE_PATH')) throw new Exception('compile path undefined.'); function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); } @@ -336,7 +410,7 @@ private static function _checkPhpVersion() { * @return */ private static function _coreLib() { - return array('AbstractWindServer' => 'WIND:core.AbstractWindServer', 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', 'WindConfig' => 'WIND:core.config.WindConfig', 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', 'WindDaoCacheListener' => 'WIND:core.dao.listener.WindDaoCacheListener', 'WindActionException' => 'WIND:core.exception.WindActionException', 'WindCacheException' => 'WIND:core.exception.WindCacheException', 'WindDaoException' => 'WIND:core.exception.WindDaoException', 'WindException' => 'WIND:core.exception.WindException', 'WindFinalException' => 'WIND:core.exception.WindFinalException', 'WindSqlException' => 'WIND:core.exception.WindSqlException', 'WindViewException' => 'WIND:core.exception.WindViewException', 'IWindFactory' => 'WIND:core.factory.IWindFactory', 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', 'WindComponentDefinition' => 'WIND:core.factory.WindComponentDefinition', 'WindComponentFactory' => 'WIND:core.factory.WindComponentFactory', 'WindFactory' => 'WIND:core.factory.WindFactory', 'WindFilter' => 'WIND:core.filter.WindFilter', 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', 'IWindRequest' => 'WIND:core.request.IWindRequest', 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', 'IWindResponse' => 'WIND:core.response.IWindResponse', 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', 'AbstractWindTemplateCompiler' => 'WIND:core.viewer.AbstractWindTemplateCompiler', 'AbstractWindViewTemplate' => 'WIND:core.viewer.AbstractWindViewTemplate', 'WindTemplateCompilerAction' => 'WIND:core.viewer.compiler.WindTemplateCompilerAction', 'WindTemplateCompilerComponent' => 'WIND:core.viewer.compiler.WindTemplateCompilerComponent', 'WindTemplateCompilerEcho' => 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', 'WindTemplateCompilerInternal' => 'WIND:core.viewer.compiler.WindTemplateCompilerInternal', 'WindTemplateCompilerPage' => 'WIND:core.viewer.compiler.WindTemplateCompilerPage', 'WindTemplateCompilerScript' => 'WIND:core.viewer.compiler.WindTemplateCompilerScript', 'WindTemplateCompilerTemplate' => 'WIND:core.viewer.compiler.WindTemplateCompilerTemplate', 'WindViewTemplate' => 'WIND:core.viewer.compiler.WindViewTemplate', 'IWindViewerResolver' => 'WIND:core.viewer.IWindViewerResolver', 'WindViewCacheListener' => 'WIND:core.viewer.listener.WindViewCacheListener', 'WindLayout' => 'WIND:core.viewer.WindLayout', 'WindView' => 'WIND:core.viewer.WindView', 'WindViewerResolver' => 'WIND:core.viewer.WindViewerResolver', 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', 'IWindApplication' => 'WIND:core.web.IWindApplication', 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', 'WindAction' => 'WIND:core.web.WindAction', 'WindController' => 'WIND:core.web.WindController', 'WindDispatcher' => 'WIND:core.web.WindDispatcher', 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', 'WindFormController' => 'WIND:core.web.WindFormController', 'WindForward' => 'WIND:core.web.WindForward', 'WindFrontController' => 'WIND:core.web.WindFrontController', 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', 'WindWebApplication' => 'WIND:core.web.WindWebApplication', 'WindComponentModule' => 'WIND:core.WindComponentModule', 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', 'WindHelper' => 'WIND:core.WindHelper', 'WindModule' => 'WIND:core.WindModule', 'WindLogger' => 'COM:log.WindLogger'); + return array(); } } Wind::init(); @@ -352,10 +426,11 @@ private static function _coreLib() { !defined('COMPONENT_TEMPLATE') && define('COMPONENT_TEMPLATE', 'template'); !defined('COMPONENT_ERRORMESSAGE') && define('COMPONENT_ERRORMESSAGE', 'errorMessage'); !defined('COMPONENT_DB') && define('COMPONENT_DB', 'db'); +!defined('COMPONENT_DISPATCHER') && define('COMPONENT_DISPATCHER', 'dispatcher'); //TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 //********************约定变量*********************************** define('WIND_M_ERROR', 'windError'); -define('WIND_CONFIG_CACHE', 'wind_components_config'); +define('WIND_CONFIG_CACHE', '_wind_config'); //**********配置*******通用常量定义*************************************** define('WIND_CONFIG_CONFIG', 'config'); define('WIND_CONFIG_CLASS', 'class'); diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php new file mode 100644 index 00000000..06412fe4 --- /dev/null +++ b/wind/_compile/compile.php @@ -0,0 +1,32 @@ + $value) { + $content[$value] = $key; + $_key = Wind::getRealPath($key . '.' . self::$_extensions); + $fileList[$_key] = array( + $key, + $value); +} +$pack->packFromFileList($fileList, COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); +/* import信息写入编译文件 */ +WindFile::write(_COMPILE_PATH . 'wind_imports.php', 'parse(_COMPILE_PATH . 'components_config.xml'); +WindFile::write($_systemConfig, ' - - + @@ -10,20 +10,17 @@ + scope='singleton'> + + + - - - - - @@ -31,7 +28,7 @@ + scope="prototype"> @@ -51,28 +48,26 @@ - - - - - - + diff --git a/wind/_compile/wind_imports.php b/wind/_compile/wind_imports.php new file mode 100644 index 00000000..4637fe72 --- /dev/null +++ b/wind/_compile/wind_imports.php @@ -0,0 +1,44 @@ + 'WIND:core.config.parser.IWindConfigParser', + 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', + 'WindConfig' => 'WIND:core.config.WindConfig', + 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', + 'WindActionException' => 'WIND:core.exception.WindActionException', + 'WindException' => 'WIND:core.exception.WindException', + 'WindFinalException' => 'WIND:core.exception.WindFinalException', + 'IWindFactory' => 'WIND:core.factory.IWindFactory', + 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', + 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', + 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', + 'WindFactory' => 'WIND:core.factory.WindFactory', + 'WindFilter' => 'WIND:core.filter.WindFilter', + 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', + 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', + 'IWindRequest' => 'WIND:core.request.IWindRequest', + 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', + 'IWindResponse' => 'WIND:core.response.IWindResponse', + 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', + 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', + 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', + 'IWindController' => 'WIND:core.web.controller.IWindController', + 'WindController' => 'WIND:core.web.controller.WindController', + 'WindSimpleController' => 'WIND:core.web.controller.WindSimpleController', + 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', + 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', + 'IWindApplication' => 'WIND:core.web.IWindApplication', + 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', + 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', + 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', + 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', + 'WindDispatcher' => 'WIND:core.web.WindDispatcher', + 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', + 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', + 'WindForward' => 'WIND:core.web.WindForward', + 'WindFrontController' => 'WIND:core.web.WindFrontController', + 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', + 'WindWebApplication' => 'WIND:core.web.WindWebApplication', + 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', + 'WindHelper' => 'WIND:core.WindHelper', + 'WindModule' => 'WIND:core.WindModule', +); \ No newline at end of file diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index eb5cf5e2..53c56066 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -1,5 +1,4 @@ @@ -7,62 +6,52 @@ * @version $Id$ * @package */ -abstract class AbstractWindCache extends WindComponentModule { - +abstract class AbstractWindCache extends WindModule { /** * key的安全码 * @var string */ private $securityCode = ''; - /** * 缓存前缀 * @var sting */ private $keyPrefix = ''; - /** * 缓存过期时间 * @var int */ private $expire = ''; - /** * 缓存依赖的类名称 * @var string */ const DEPENDENCYCLASS = 'dependencyclass'; - /** * 标志存储时间 * @var string */ const STORETIME = 'store'; - /** * 标志存储数据 * @var string */ const DATA = 'data'; - /** * 配置文件中标志过期时间名称定义(也包含缓存元数据中过期时间 的定义) * @var string */ const EXPIRE = 'expires'; - /** * 配置文件中标志缓存依赖名称的定义 * @var string */ const DEPENDENCY = 'dependency'; - /** * 配置文件中缓存安全码名称的定义 * @var string */ const SECURITY = 'security'; - /** * 配置文件中缓存键的前缀名称的定义 * @var string @@ -233,5 +222,4 @@ public function setKeyPrefix($keyPrefix) { public function setExpire($expire) { $this->expire = $expire; } - } \ No newline at end of file diff --git a/wind/core/exception/WindCacheException.php b/wind/component/cache/exception/WindCacheException.php similarity index 100% rename from wind/core/exception/WindCacheException.php rename to wind/component/cache/exception/WindCacheException.php diff --git a/wind/component/cache/strategy/WindCacheDb.php b/wind/component/cache/strategy/WindCacheDb.php index bcbb78ee..28bfa87d 100644 --- a/wind/component/cache/strategy/WindCacheDb.php +++ b/wind/component/cache/strategy/WindCacheDb.php @@ -182,8 +182,8 @@ public function setDbHandler(AbstractWindDbAdapter $dbHandler) { $this->dbHandler = $dbHandler; } - /* - * @see WindComponentModule#setConfig() + /* (non-PHPdoc) + * @see WindModule::setConfig() */ public function setConfig($config) { parent::setConfig($config); diff --git a/wind/component/cache/strategy/WindCacheMem.php b/wind/component/cache/strategy/WindCacheMem.php index daf313b9..2b9c7a83 100644 --- a/wind/component/cache/strategy/WindCacheMem.php +++ b/wind/component/cache/strategy/WindCacheMem.php @@ -74,8 +74,8 @@ public function clear() { return $this->memcache->flush(); } - /* - * @see WindComponentModule::setConfig() + /* (non-PHPdoc) + * @see WindModule::setConfig() */ public function setConfig($config) { parent::setConfig($config); diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php index f6756d29..21ff5929 100644 --- a/wind/component/dao/WindDao.php +++ b/wind/component/dao/WindDao.php @@ -8,87 +8,102 @@ * @package */ class WindDao extends WindModule { - protected $dbClass = 'WIND:component.db.WindConnection'; + /** + * db链接类型定义 + * + * @var string + */ + protected $dbClass = 'COM:db.WindConnection'; + /** + * db配置路径定义 + * + * @var string + */ /** * 链接配置文件或是配置数组 * @var string|array */ protected $dbConfig = ''; + /** + * cache类型定义 + * + * @var string + */ protected $cacheClass = ''; - protected $cacheConfig = ''; - protected $isDataCache = false; - protected $dbDefinition = null; /** - * @var WindConnection 数据库链接对象 + * cache配置信息 + * + * @var string */ + protected $cacheConfig = ''; + private $connection = null; + private $cacheHandler = null; + /** - * @var AbstractWindCache 缓存操作句柄 + * 获得需要缓存的处理的方法名称数组 + * array('methodName1'=>'WIND:component') + * @return multitype: */ - private $cacheHandler = null; + public function getCacheMethods() { + return array(); + } /** - * @see WindModule::getWriteTableForGetterAndSetter() + * @return WindConnection */ - protected function getWriteTableForGetterAndSetter() { - return array('dbClass', 'dbConfig', 'cacheClass', 'isDataCache', 'dbHandler', 'cacheConfig', 'cacheHandler'); + public function getConnection() { + return $this->_getConnection(); } /** - * 获得DB类定义 - * @return WindComponentDefinition + * @return WindCacheDb */ - public function getDbDefinition() { - Wind::import('WIND:core.factory.WindComponentDefinition'); - $definition = new WindComponentDefinition(); - $definition->setPath($this->dbClass); - $definition->setScope(WindComponentDefinition::SCOPE_SINGLETON); - $definition->setAlias($this->dbClass); - $definition->setInitMethod('init'); - if (is_array($this->dbConfig)) - $definition->setConfig($this->dbConfig); - else - $definition->setConfig(array(WindComponentDefinition::RESOURCE => $this->dbConfig)); - return $definition; + public function getCacheHandler() { + return $this->_getCacheHandler(); } /** - * 获得Cache类定义 - * @return WindComponentDefinition + * @return the $dbClass */ - public function getCacheDefinition() { - Wind::import('WIND:core.factory.WindComponentDefinition'); - $definition = new WindComponentDefinition(); - $definition->setPath($this->cacheClass); - $definition->setScope(WindComponentDefinition::SCOPE_SINGLETON); - $definition->setAlias($this->cacheClass); - $definition->setConfig(array(WindComponentDefinition::RESOURCE => $this->cacheConfig)); - return $definition; + public function getDbClass() { + return $this->dbClass; } /** - * 获得需要缓存的处理的方法名称数组 - * array('methodName1'=>'WIND:component') - * @return array + * @return the $dbConfig */ - public function getCacheMethods() { - return array(); + public function getDbConfig() { + return $this->dbConfig; } /** - * 获得链接对象 - * @return WindConnection $connection + * @return the $cacheClass */ - public function getConnection() { - return $this->connection; + public function getCacheClass() { + return $this->cacheClass; } /** - * 设置链接对象 - * @param WindConnection $windConnection + * @return the $cacheConfig */ - public function setConnection($windConnection) { - $this->connection = $windConnection; + public function getCacheConfig() { + return $this->cacheConfig; } + + /** + * @param field_type $connection + */ + public function setConnection($connection) { + $this->connection = $connection; + } + + /** + * @param field_type $cacheHandler + */ + public function setCacheHandler($cacheHandler) { + $this->cacheHandler = $cacheHandler; + } + } ?> \ No newline at end of file diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index b735b159..50e1d905 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -1,6 +1,5 @@ getDaoResource()) { - $_path = $this->getDaoResource() . '.' . $className; - } else { - $_path = $className; + if (strpos($className, ":") === false && strpos($className, ".") === false) { + $className = $this->getDaoResource() . '.' . $className; } - $className = Wind::import($_path); + if (isset($this->daos[$className])) return $this->daos[$className]; + + $className = Wind::import($className); $daoInstance = WindFactory::createInstance($className); - $daoInstance->setConnection($this->createDbConnection($daoInstance)); - if (!$daoInstance->getIsDataCache()) return $daoInstance; - $daoInstance->setCacheHandler($this->createCacheHandler($daoInstance)); - $daoInstance->setClassProxy(new WindClassProxy()); - $daoInstance = $daoInstance->getClassProxy(); - $this->registerCacheListener($daoInstance); + $this->createDbConnection($daoInstance); + $this->createCacheHandler($daoInstance); return $daoInstance; } catch (Exception $exception) { - throw new WindDaoException($exception->getMessage()); + Wind::log( + '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . + $exception->getMessage(), WindLogger::LEVEL_DEBUG, 'wind.component'); + throw new WindDaoException( + '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . + $exception->getMessage()); } } @@ -83,49 +92,56 @@ private function registerCacheListener($daoInstance) { } /** - * 返回链接对象 + * 创建db链接句柄 + * * @param WindDao $daoObject - * @return WindConnection */ protected function createDbConnection($daoObject) { - $defintion = $daoObject->getDbDefinition(); - $_className = $defintion->getClassName(); - $_classConfig = $defintion->getConfig(); - $_alias = $_className . '_' . md5(serialize($_classConfig)); - if (!isset($this->dbConnections[$_alias])) { - $this->_getWindFactory(); - $this->windFactory->addClassDefinitions($defintion); - $this->dbConnections[$_alias] = $this->windFactory->getInstance($defintion->getAlias()); + if (!($_className = $daoObject->getDbClass())) return; + $_classConfig = $daoObject->getDbConfig(); + $_alias = $_className . '_' . md5((is_string($_classConfig) ? $_classConfig : serialize($_classConfig))); + if (!$this->getSystemFactory()->checkAlias($_alias)) { + $definition = new WindClassDefinition(); + $definition->setPath($_className); + $definition->setAlias($_alias); + $definition->setInitMethod('init'); + $definition->setScope(WindClassDefinition::SCOPE_SINGLETON); + if (is_array($_classConfig)) + $definition->setConfig($_classConfig); + else + $definition->setConfig(array(WindClassDefinition::RESOURCE => $_classConfig)); + + $this->getSystemFactory()->addClassDefinitions($definition); } - return $this->dbConnections[$_alias]; + $daoObject->setDelayAttributes(array('connection' => array(WindClassDefinition::REF => $_alias))); } /** - * 返回Cache对象 + * 创建cache句柄 + * * @param WindDao $daoObject - * @return AbstractWindCache */ protected function createCacheHandler($daoObject) { - $_cacheClass = $daoObject->getCacheClass(); - if (!isset($this->caches[$_cacheClass])) { - $this->_getWindFactory(); - $defintion = $daoObject->getCacheDefinition(); - $this->windFactory->addClassDefinitions($defintion); - $this->caches[$_cacheClass] = $this->windFactory->getInstance($defintion->getAlias()); + if (!($_className = $daoObject->getCacheClass())) return; + $_classConfig = $daoObject->getCacheConfig(); + $_alias = $_className . '_' . md5((is_string($_classConfig) ? $_classConfig : serialize($_classConfig))); + if (!$this->getSystemFactory()->checkAlias($_alias)) { + $definition = new WindClassDefinition(); + $definition->setPath($_className); + $definition->setAlias($_alias); + $definition->setInitMethod('init'); + $definition->setScope(WindClassDefinition::SCOPE_SINGLETON); + if (is_array($_classConfig)) + $definition->setConfig($_classConfig); + else + $definition->setConfig(array(WindClassDefinition::RESOURCE => $_classConfig)); + + $this->getSystemFactory()->addClassDefinitions($definition); } - return $this->caches[$_cacheClass]; + $daoObject->setDelayAttributes(array('cacheHandler' => array(WindClassDefinition::REF => $_alias))); + $daoObject = new WindClassProxy($daoObject); + $this->registerCacheListener($daoObject); } - /** - * 获得ComponentFactory对象 - * @return WindComponentFactory - */ - private function _getWindFactory() { - if ($this->windFactory === null) { - Wind::import('WIND:core.factory.WindComponentFactory'); - $this->windFactory = new WindComponentFactory(); - } - return $this->windFactory; - } } ?> \ No newline at end of file diff --git a/wind/core/exception/WindDaoException.php b/wind/component/dao/exception/WindDaoException.php similarity index 100% rename from wind/core/exception/WindDaoException.php rename to wind/component/dao/exception/WindDaoException.php diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 46a384ea..062c5baa 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -1,5 +1,5 @@ _dbHandle !== null) return; try { - Wind::log("component.db.WindConnection._init() Initialize DB handle, set default attributes and charset.", WindLogger::LEVEL_INFO); + Wind::log("component.db.WindConnection._init() Initialize DB handle, set default attributes and charset.", + WindLogger::LEVEL_INFO); $driverName = $this->getDriverName(); if ($driverName) { $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; @@ -228,7 +229,10 @@ public function init() { $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->_dbHandle->setCharset($this->_charset); - Wind::log("component.db.WindConnection._init() \r\n dsn: " . $this->_dsn . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, WindLogger::LEVEL_DEBUG); + Wind::log( + "component.db.WindConnection.init() \r\n dsn: " . $this->_dsn . " \r\n username: " . $this->_user . + " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, + WindLogger::LEVEL_DEBUG); } catch (PDOException $e) { $this->close(); Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", WindLogger::LEVEL_TRACE); @@ -238,7 +242,7 @@ public function init() { /** * (non-PHPdoc) - * @see WindComponentModule::setConfig() + * @see WindModule::setConfig() */ public function setConfig($config) { parent::setConfig($config); diff --git a/wind/component/db/WindConnectionManager.php b/wind/component/db/WindConnectionManager.php index a7566827..9594e90b 100644 --- a/wind/component/db/WindConnectionManager.php +++ b/wind/component/db/WindConnectionManager.php @@ -6,7 +6,7 @@ * @version $Id$ * @package */ -class WindConnectionManager extends WindComponentModule { +class WindConnectionManager extends WindModule { const CONNECTION_MODE_RAND = '0'; /** * 链接句柄 diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index faab768c..6c4b24ff 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -1,6 +1,6 @@ * @author Qiong Wu @@ -27,7 +27,8 @@ class WindSqlStatement { * * @var array */ - private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); + private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'string' => PDO::PARAM_STR, + 'NULL' => PDO::PARAM_NULL); private $_columns = array(); /** @@ -54,7 +55,8 @@ public function __construct($connection, $query) { */ public function bindParam($parameter, &$variable, $dataType = null, $length = null, $driverOptions = null) { try { - Wind::log("component.db.WindSqlStatement.bindParam. parameter:" . $parameter . " variable:" . $variable, WindLogger::LEVEL_INFO, "component.db"); + Wind::log("component.db.WindSqlStatement.bindParam. parameter:" . $parameter . " variable:" . $variable, + WindLogger::LEVEL_INFO, "component.db"); $this->init(); if ($dataType === null) { $dataType = $this->_getPdoDataType($variable); @@ -65,7 +67,8 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, $driverOptions); return $this; } catch (PDOException $e) { - Wind::log("component.db.WindSqlStatement.bindParam. exception message:" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); + Wind::log("component.db.WindSqlStatement.bindParam. exception message:" . $e->getMessage(), + WindLogger::LEVEL_TRACE, "component.db"); throw new WindDbException($e->getMessage()); } } @@ -82,7 +85,8 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu */ public function bindParams(&$parameters) { if (!is_array($parameters)) { - throw new WindDbException('[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters)); + throw new WindDbException( + '[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters)); } $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1)); foreach ($parameters as $key => $value) { @@ -109,7 +113,8 @@ public function bindParams(&$parameters) { */ public function bindValue($parameter, $value, $data_type = null) { try { - Wind::log("component.db.WindSqlStatement.bindValue. parameter:" . $parameter . " variable:" . $value, WindLogger::LEVEL_INFO, "component.db"); + Wind::log("component.db.WindSqlStatement.bindValue. parameter:" . $parameter . " variable:" . $value, + WindLogger::LEVEL_INFO, "component.db"); $this->init(); if ($data_type === null) { $data_type = $this->_getPdoDataType($value); @@ -117,7 +122,8 @@ public function bindValue($parameter, $value, $data_type = null) { $this->getStatement()->bindValue($parameter, $value, $data_type); return $this; } catch (PDOException $e) { - Wind::log("component.db.WindSqlStatement.bindValue. exception message:" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); + Wind::log("component.db.WindSqlStatement.bindValue. exception message:" . $e->getMessage(), + WindLogger::LEVEL_TRACE, "component.db"); throw new WindDbException($e->getMessage()); } } @@ -131,7 +137,8 @@ public function bindValue($parameter, $value, $data_type = null) { */ public function bindValues($values) { if (!is_array($values)) { - throw new WindSqlException('[component.db.WindSqlStatement.bindValues] Error unexpected paraments type ' . gettype($values)); + throw new WindSqlException( + '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type ' . gettype($values)); } $keied = (array_keys($values) !== range(0, sizeof($values) - 1)); foreach ($values as $key => $value) { @@ -166,7 +173,8 @@ public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $this->_columns[$column] = & $param; return $this; } catch (PDOException $e) { - Wind::log("component.db.WindSqlStatement.bindColumn. exception message" . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); + Wind::log("component.db.WindSqlStatement.bindColumn. exception message" . $e->getMessage(), + WindLogger::LEVEL_TRACE, "component.db"); throw new WindDbException($e->getMessage()); } } @@ -273,11 +281,13 @@ public function execute($params = array(), $rowCount = true) { $this->bindValues($params); $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; - Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, "component.db"); + Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, + "component.db"); Wind::profileEnd('component.db.WindSqlStatement._init'); return $_result; } catch (PDOException $e) { - Wind::log("component.db.WindSqlStatement.execute throw exception,exception message: " . $e->getMessage(), WindLogger::LEVEL_TRACE, "component.db"); + Wind::log("component.db.WindSqlStatement.execute throw exception,exception message: " . $e->getMessage(), + WindLogger::LEVEL_TRACE, "component.db"); throw new WindDbException($e->getMessage()); } } @@ -340,10 +350,14 @@ public function getColumns() { public function init() { if ($this->_statement === null) { try { - Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. ", WindLogger::LEVEL_INFO, "component.db"); - Wind::profileBegin("component.db.WindSqlStatement._init", " SQL: " . $this->getQueryString(), "component.db"); + Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. ", WindLogger::LEVEL_INFO, + "component.db"); + Wind::profileBegin("component.db.WindSqlStatement._init", " SQL: " . $this->getQueryString(), + "component.db"); $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString()); - Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. This statement is " . get_class($this->_statement), WindLogger::LEVEL_DEBUG, "component.db"); + Wind::log( + "component.db.WindSqlStatement._init Initialize DBStatement. This statement is " . + get_class($this->_statement), WindLogger::LEVEL_DEBUG, "component.db"); } catch (PDOException $e) { Wind::log("Component.db.WindSqlStatement._init Initialize DBStatement failed.", WindLogger::LEVEL_TRACE, "component.db"); diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index 3bae0f85..fba0a5d5 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -6,7 +6,7 @@ * @version $Id$ * @package */ -class WindLogger extends WindComponentModule { +class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; @@ -202,7 +202,7 @@ public function getMemoryUsage($peak = true) { * @return string */ private function _build($msg, $level, $type, $timer = 0, $mem = 0) { - $msg = stripslashes(str_replace("
", "\r\n", trim($msg))); + $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: @@ -241,7 +241,8 @@ private function _buildProfile($msg, $type, $timer, $mem) { if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); - $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); + $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, + $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); @@ -325,72 +326,73 @@ private function _buildError($msg) { private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; - $traces = debug_backtrace(false); + $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; - if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; - $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; - $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; - if ($function == 'WindBase::log') continue; - $args = array_map(array($this, '_buildArg'), $trace['args']); - $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; + if ((isset($trace['class']) && $trace['class'] == __CLASS__) || + isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; + $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; + $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; + if ($function == 'WindBase::log') continue; + $args = array_map(array($this, '_buildArg'), $trace['args']); + $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; + } + return $info; } - return $info; - } - /** - * 组装输出的trace中的参数组装 - * @param mixed $arg - */ - private function _buildArg($arg) { - switch (gettype($arg)) { - case 'array': - return 'Array'; - break; - case 'object': - return 'Object ' . get_class($arg); - break; - default: - return "'" . $arg . "'"; - break; + /** + * 组装输出的trace中的参数组装 + * @param mixed $arg + */ + private function _buildArg($arg) { + switch (gettype($arg)) { + case 'array': + return 'Array'; + break; + case 'object': + return 'Object ' . get_class($arg); + break; + default: + return "'" . $arg . "'"; + break; + } } - } - /** - * 取得日志文件名 - * @return string - */ - private function _getFileName($suffix = '') { - $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; - $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; - if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { - $counter = 0; - do { - $counter++; - $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); - } while (is_file($_newFile)); - @rename($_logfile, $_newFile); + /** + * 取得日志文件名 + * @return string + */ + private function _getFileName($suffix = '') { + $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; + $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; + if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { + $counter = 0; + do { + $counter++; + $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); + } while (is_file($_newFile)); + @rename($_logfile, $_newFile); + } + return $_logfile; } - return $_logfile; - } - public function __destruct() { - $this->flush(); - } + public function __destruct() { + $this->flush(); + } - /** - * @param field_type $_logFile - */ - public function setLogDir($logDir) { - $this->_logDir = $logDir; - } + /** + * @param field_type $_logFile + */ + public function setLogDir($logDir) { + $this->_logDir = $logDir; + } - /** - * @param field_type $_maxFileSize - */ - public function setMaxFileSize($maxFileSize) { - $this->_maxFileSize = (int) $maxFileSize; - } -} + /** + * @param field_type $_maxFileSize + */ + public function setMaxFileSize($maxFileSize) { + $this->_maxFileSize = (int) $maxFileSize; + } + } \ No newline at end of file diff --git a/wind/component/utility/WindFile.php b/wind/component/utility/WindFile.php index 2cf1795a..5ba47fe5 100644 --- a/wind/component/utility/WindFile.php +++ b/wind/component/utility/WindFile.php @@ -1,11 +1,4 @@ 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - /** * 文件工具类 * the last known user to change this file in the repository <$LastChangedBy$> @@ -14,32 +7,32 @@ * @package */ class WindFile { - + /** * @var string 以读的方式打开文件,具有较强的平台移植性 */ const READ = 'rb'; - + /** * @var string 以读写的方式打开文件,具有较强的平台移植性 */ const READWRITE = 'rb+'; - + /** * @var string 以写的方式打开文件,具有较强的平台移植性 */ const WRITE = 'wb'; - + /** * @var string 以读写的方式打开文件,具有较强的平台移植性 */ const WRITEREAD = 'wb+'; - + /** * @var string 以追加写入方式打开文件,具有较强的平台移植性 */ const APPEND_WRITE = 'ab'; - + /** * @var string 以追加读写入方式打开文件,具有较强的平台移植性 */ diff --git a/wind/component/utility/WindUtility.php b/wind/component/utility/WindUtility.php index acaa99cd..fcfd1050 100644 --- a/wind/component/utility/WindUtility.php +++ b/wind/component/utility/WindUtility.php @@ -1,5 +1,4 @@ $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } + } ?> \ No newline at end of file diff --git a/wind/core/viewer/AbstractWindTemplateCompiler.php b/wind/component/viewer/AbstractWindTemplateCompiler.php similarity index 94% rename from wind/core/viewer/AbstractWindTemplateCompiler.php rename to wind/component/viewer/AbstractWindTemplateCompiler.php index 98cfc9f8..c25ddf26 100644 --- a/wind/core/viewer/AbstractWindTemplateCompiler.php +++ b/wind/component/viewer/AbstractWindTemplateCompiler.php @@ -1,9 +1,7 @@ * @author Qiong Wu @@ -11,21 +9,21 @@ * @package */ abstract class AbstractWindTemplateCompiler extends WindHandlerInterceptor { - + protected $tags = array(); - + /** * @var WindViewTemplate */ protected $windViewTemplate = null; - + /** * @var WindViewerResolver */ protected $windViewerResolver = null; - + protected $request = null; - + protected $response = null; /** @@ -53,16 +51,14 @@ public function __construct($tags, $windViewTemplate, $windViewerResolver, $requ abstract public function compile($key, $content); /** - * 解析属性值 - * @param string $content + * 编译前预处理 */ - protected function compileProperty($content) { - foreach ($this->getProperties() as $value) { - if (!$value) continue; - preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', $content, $result); - if ($result) $this->$value = trim(str_replace($result[1], '', $result[0])); - } - } + protected function preCompile() {} + + /** + * 编译后处理结果 + */ + protected function postCompile() {} /** * 返回该标签支持的属性信息 @@ -71,8 +67,17 @@ protected function getProperties() { return array(); } - protected function preCompile() { - + /** + * 解析属性值 + * + * @param string $content + */ + protected function compileProperty($content) { + foreach ($this->getProperties() as $value) { + if (!$value) continue; + preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', $content, $result); + if ($result) $this->$value = trim(str_replace($result[1], '', $result[0])); + } } /* (non-PHPdoc) @@ -90,12 +95,10 @@ public function preHandle() { $this->postCompile(); } - /** - * 编译后处理结果 + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() */ - protected function postCompile() { - - } + public function postHandle() {} /* (non-PHPdoc) * @see WindHandlerInterceptor::handle() @@ -109,13 +112,8 @@ public function handle() { call_user_func_array(array($this, 'postHandle'), $args); } - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() {} - /** - * @return WindViewTemplate $windViewTemplate + * @return WindViewTemplate */ protected function getWindViewTemplate() { return $this->windViewTemplate; diff --git a/wind/core/viewer/AbstractWindViewTemplate.php b/wind/component/viewer/AbstractWindViewTemplate.php similarity index 57% rename from wind/core/viewer/AbstractWindViewTemplate.php rename to wind/component/viewer/AbstractWindViewTemplate.php index 7ecea651..fb8b9915 100644 --- a/wind/core/viewer/AbstractWindViewTemplate.php +++ b/wind/component/viewer/AbstractWindViewTemplate.php @@ -1,25 +1,16 @@ * @author Qiong Wu * @version $Id$ * @package */ -abstract class AbstractWindViewTemplate extends WindComponentModule { - +abstract class AbstractWindViewTemplate extends WindModule { const SUPPORT_TAGS = 'support-tags'; - const TAG = 'tag'; - const REGEX = 'regex'; - const COMPILER = 'compiler'; - const PATTERN = 'pattern'; /** @@ -31,16 +22,15 @@ abstract protected function doCompile($content, $windViewerResolver = null); /** * 进行视图渲染 + * + * * @param string $templateFile | 模板文件 - * @param string $compileFile | 编译后生成的文件 * @param WindViewerResolver $windViewerResolver */ - public function compile($templateFile, $compileFile, $windViewerResolver) { - if (!$this->checkReCompile($templateFile, $compileFile)) return null; + public function compile($templateFile, $windViewerResolver) { $_output = $this->getTemplateFileContent($templateFile); $_output = $this->compileDelimiter($_output); $_output = $this->doCompile($_output, $windViewerResolver); - $this->cacheCompileResult($compileFile, $_output); return $_output; } @@ -67,40 +57,9 @@ private function getTemplateFileContent($templateFile) { fclose($fp); } else throw new WindViewException('Unable to open the template file \'' . $templateFile . '\'.'); - return $_output; } - /** - * 将编译结果进行缓存 - * @param string $compileFile | 编译缓存文件 - * @param string $content | 模板内容 - */ - private function cacheCompileResult($compileFile, $content) { - //TODO 修复模板在非Debug模式下不能生成问题 - if (!$compileFile && !$content) return; - WindFile::write($compileFile, $content); - } - - /** - * 检查是否需要重新编译 - * - * @param string $templateFile - * @param string $compileFile - */ - private function checkReCompile($templateFile, $compileFile) { - $_reCompile = false; - if (IS_DEBUG) { - $_reCompile = true; - } elseif (false === ($compileFileModifyTime = @filemtime($compileFile))) { - $_reCompile = true; - } else { - $templateFileModifyTime = @filemtime($templateFile); - if ((int) $templateFileModifyTime >= $compileFileModifyTime) $_reCompile = true; - } - return $_reCompile; - } - /** * 返回模板支持的标签 * array('tagName'=>array('tag','compiler')) @@ -110,5 +69,4 @@ protected function getTags() { return $this->getConfig(self::SUPPORT_TAGS); } } - ?> \ No newline at end of file diff --git a/wind/core/viewer/IWindViewerResolver.php b/wind/component/viewer/IWindViewerResolver.php similarity index 74% rename from wind/core/viewer/IWindViewerResolver.php rename to wind/component/viewer/IWindViewerResolver.php index ea5556f4..994a92b6 100644 --- a/wind/core/viewer/IWindViewerResolver.php +++ b/wind/component/viewer/IWindViewerResolver.php @@ -1,11 +1,4 @@ 2010-11-15 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - /** * 视图引擎基类 * 通过继承该方法可以实现对视图模板的调用解析 diff --git a/wind/core/viewer/WindLayout.php b/wind/component/viewer/WindLayout.php similarity index 100% rename from wind/core/viewer/WindLayout.php rename to wind/component/viewer/WindLayout.php diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php new file mode 100644 index 00000000..42a4fda1 --- /dev/null +++ b/wind/component/viewer/WindView.php @@ -0,0 +1,231 @@ + + * + * + * + * + * + *
+ * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindView extends WindModule { + /* 视图配置信息 */ + const TEMPLATE_DIR = 'template-dir'; + const TEMPLATE_EXT = 'template-ext'; + const IS_CACHE = 'is-cache'; + /** + * 模板路径信息 + * + * @var string + */ + protected $templateDir; + /** + * 模板文件的扩展名 + * + * @var string + */ + protected $templateExt; + /** + * 模板名称 + * + * @var string + */ + protected $templateName; + /** + * 是否进行视图缓存 + * + * @var boolean + */ + protected $isCache = false; + /** + * 视图解析引擎 + * + * @var WindViewerResolver + */ + protected $viewResolver = null; + /** + * 布局文件 + * + * @var string + */ + protected $layout; + + /** + * 视图渲染 + * + * @param WindForward $forward + * @param WindUrlBasedRouter $router + */ + public function render($forward, $router, $display = false) { + if (!($_templateName = $forward->getTemplateName())) { + Wind::log('[component.viewer.WindView.render] view render fail. TemplateName is not defined.', + WindLogger::LEVEL_DEBUG, 'wind.component'); + return; + } + $this->setTemplateName($_templateName); + if ($_ext = $forward->getTemplateExt()) $this->setTemplateExt($_ext); + if ($_path = $forward->getTemplatePath()) $this->setTemplateDir($_path); + if ($_layout = $forward->getLayout()) $this->setLayout($_layout); + + $viewResolver = $this->getViewResolver(); + $viewResolver->windAssign($forward->getVars(), $_templateName); + if ($display === false) { + $this->getResponse()->setBody($viewResolver->windFetch(), $_templateName); + } else + $viewResolver->displayWindFetch(); + } + + /** + * 模板路径解析 + * 根据模板的逻辑名称,返回模板的绝对路径信息 + * + * @param string $templateName + * @param string $templateExt + * @return string | false + */ + public function getViewTemplate($template = '', $ext = '') { + return $this->parseFilePath($template, $ext, $this->getTemplateDir()); + } + + /** + * 模板编译路径解析 + * 根据模板的逻辑名称,返回模板的绝对路径信息 + * + * @param string $templateName + * @param string $templateExt + * @return string | false + */ + public function getCompileFile($template = '', $ext = '') { + return $this->parseFilePath($template, $ext, COMPILE_PATH . 'template', true); + } + + /** + * @param $fileName + * @param $fileExt + * @param $path + */ + private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) { + if (!$fileName) $fileName = $this->getTemplateName(); + if (!$fileExt) $fileExt = $this->getTemplateExt(); + if (strrpos($path, ':') === false) $path = Wind::getAppName() . ':' . $path; + if ($ifCheckPath) { + $dir = Wind::getRealPath($path, true); + if (!is_dir($dir)) { + @mkdir($dir); + Wind::log('[component.viewer.WindView.parseFilePath] template dir is not exist.', + WindLogger::LEVEL_DEBUG, 'wind.component'); + } + } + return Wind::getRealPath($path . '.' . $fileName . '.' . $fileExt); + } + + /** + * 初始哈windView类 + * + * @return + */ + public function init() { + $this->setTemplateDir($this->getConfig(self::TEMPLATE_DIR, WIND_CONFIG_VALUE)); + $this->setTemplateExt($this->getConfig(self::TEMPLATE_EXT, WIND_CONFIG_VALUE)); + $this->setIsCache($this->getConfig(self::IS_CACHE), WIND_CONFIG_VALUE); + } + + /** + * @return string + */ + public function getTemplateDir() { + return $this->templateDir; + } + + /** + * @return string + */ + public function getTemplateExt() { + return $this->templateExt; + } + + /** + * @return string + */ + public function getTemplateName() { + return $this->templateName; + } + + /** + * @return boolean + */ + public function getIsCache() { + return $this->isCache; + } + + /** + * @return WindLayout + */ + public function getLayout() { + return $this->layout; + } + + /** + * @param string $templateDir + */ + public function setTemplateDir($templateDir) { + $this->templateDir = $templateDir; + } + + /** + * @param string $templateExt + */ + public function setTemplateExt($templateExt) { + $this->templateExt = $templateExt; + } + + /** + * @param string $templateName + */ + public function setTemplateName($templateName) { + $this->templateName = $templateName; + } + + /** + * @param boolean $isCache + */ + public function setIsCache($isCache) { + $this->isCache = $isCache; + } + + /** + * @param string $layout + */ + public function setLayout($layout) { + $this->layout = $layout; + } + + /** + * @return WindViewerResolver + */ + public function getViewResolver() { + if ($this->viewResolver === null) { + $this->_getViewResolver(); + $this->viewResolver->setWindView($this); + /*$this->viewResolver->setDelayAttributes( + array('windView' => array(WindClassDefinition::REF => COMPONENT_VIEW)));*/ + } + return $this->viewResolver; + } + + /** + * @param WindViewerResolver $viewResolver + */ + public function setViewResolver($viewResolver) { + $this->viewResolver = $viewResolver; + } + +} \ No newline at end of file diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php new file mode 100644 index 00000000..4aa97e36 --- /dev/null +++ b/wind/component/viewer/WindViewerResolver.php @@ -0,0 +1,153 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewerResolver extends WindModule implements IWindViewerResolver { + /** + * @var WindUrlHelper + */ + protected $urlHelper = null; + + /** + * @var WindView + */ + protected $windView = null; + + /* (non-PHPdoc) + * @see IWindViewerResolver::windFetch() + */ + public function windFetch($template = '') { + if (!$template && null !== ($layout = $this->getWindView()->getLayout())) { + $template = $layout; + } + ob_start(); + $this->render($template); + return ob_get_clean(); + } + + /* (non-PHPdoc) + * @see IWindViewerResolver::windAssign() + */ + public function windAssign($vars, $key = '') { + if ($key === '') $key = $this->getWindView()->getTemplateName(); + $this->getResponse()->setData($vars, $key); + } + + /** + * 立即输出模板内容 + * + * @param string $template + * @param WindView $view + */ + public function displayWindFetch($template = '') { + echo $this->windFetch($template); + } + + /** + * 编译模板并返回编译后模板名称 + * + * @param string $template + * @param string $suffix + * @param boolean $output + * @return string + */ + public function compile($template, $suffix = '', $output = false) { + $templateFile = $this->getWindView()->getViewTemplate($template, $suffix); + if (!is_file($templateFile)) { + throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, + WindViewException::VIEW_NOT_EXIST); + } + $compileFile = $this->getWindView()->getCompileFile($template, 'tpl'); + + /* @var $_windTemplate WindViewTemplate */ + $_windTemplate = $this->getSystemFactory()->getInstance(COMPONENT_TEMPLATE); + $_output = $_windTemplate->compile($templateFile, $this); + + if (!$compileFile && !$_output) return array('', ''); + WindFile::write($compileFile, $_output); + return array($compileFile, $_output); + } + + /** + * 加载视图模板文件 + * + * @param template + */ + protected function render($template) { + list($_tmp, $_output) = $this->compile($template); + @extract((array) $this->getResponse()->getData($this->getWindView()->getTemplateName()), EXTR_REFS); + if (!include $_tmp) { + throw new WindViewException( + '[component.viewer.ViewerResolver.render] template:' . $template . ' compile template:' . $_tmp, + WindViewException::VIEW_NOT_EXIST); + } + } + + /** + * 检查是否需要重新编译 + * + * @param string $templateFile + * @param string $compileFile + */ + private function checkReCompile($templateFile, $compileFile) { + $_reCompile = false; + if (IS_DEBUG) { + $_reCompile = true; + } elseif (false === ($compileFileModifyTime = @filemtime($compileFile))) { + $_reCompile = true; + } else { + $templateFileModifyTime = @filemtime($templateFile); + if ((int) $templateFileModifyTime >= $compileFileModifyTime) $_reCompile = true; + } + return $_reCompile; + } + + /** + * 返回模板变量信息 + * + * @param string $var + * @param string $templateName + */ + private function getVar($var, $templateName) { + return $this->getResponse()->getData($templateName, $var); + } + + /** + * 当前模板内容 + * + * @param string $template + */ + private function getContent($template = '') { + if (!$template) $template = $this->getWindView()->getTemplateName(); + if ($template) $this->displayWindFetch($template); + } + + /** + * @return WindView + */ + public function getWindView() { + return $this->windView; + } + + /** + * @param WindView $windView + */ + public function setWindView($windView) { + $this->windView = $windView; + } + +} \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerAction.php b/wind/component/viewer/compiler/WindTemplateCompilerAction.php new file mode 100644 index 00000000..db76aef2 --- /dev/null +++ b/wind/component/viewer/compiler/WindTemplateCompilerAction.php @@ -0,0 +1,49 @@ + 标签解析脚本 + * 支持属性: action\controller + * + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerAction extends AbstractWindTemplateCompiler { + + protected $action = ''; + + protected $controller = ''; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + $_content = 'getScript() . ' ?>' . "\r\n"; + return $_content; + } + + /** + * @return string + */ + public function getScript() { + $_tmp = ''; + $_tmp .= '$_tpl_forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD);' . + '$_tpl_forward->setDisplay(true);' . + '$_tpl_forward->forwardAnotherAction(\'' . $this->action . '\', \'' . $this->controller . '\');' . + '$_tpl_app = $this->getSystemFactory()->getInstance(COMPONENT_WEBAPP);'. + '$_tpl_app->doDispatch($_tpl_forward);' . + ''. + 'echo $this->getWindView()->getTemplateName();'; + return $_tmp; + } + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::getProperties() + */ + public function getProperties() { + return array('action', 'controller'); + } + +} \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerComponent.php b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php similarity index 93% rename from wind/core/viewer/compiler/WindTemplateCompilerComponent.php rename to wind/component/viewer/compiler/WindTemplateCompilerComponent.php index d337ceca..e725fd1d 100644 --- a/wind/core/viewer/compiler/WindTemplateCompilerComponent.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php @@ -1,6 +1,5 @@ * @author Qiong Wu diff --git a/wind/core/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php similarity index 91% rename from wind/core/viewer/compiler/WindTemplateCompilerEcho.php rename to wind/component/viewer/compiler/WindTemplateCompilerEcho.php index 34380003..1d2b9b93 100644 --- a/wind/core/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -1,9 +1,8 @@ * @author Qiong Wu diff --git a/wind/core/viewer/compiler/WindTemplateCompilerInternal.php b/wind/component/viewer/compiler/WindTemplateCompilerInternal.php similarity index 87% rename from wind/core/viewer/compiler/WindTemplateCompilerInternal.php rename to wind/component/viewer/compiler/WindTemplateCompilerInternal.php index e205d20d..581b42c9 100644 --- a/wind/core/viewer/compiler/WindTemplateCompilerInternal.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerInternal.php @@ -1,7 +1,5 @@ getPageCode(); - - } + } + private function getPageCode() { empty($this->total) && $this->total = '0'; empty($this->page) && $this->page = '1'; empty($this->count) && $this->count = '0'; empty($this->per) && $this->per = '0'; empty($this->url) && $this->url = ''; - $strPageCode = - 'count . ';' . - '$_tplPagePer=(int)' . $this->per . ';' . - '$_tplPageTotal=(int)' . $this->total . ';' . - '$_tplPageCurrent=(int)' . $this->page . ';' . - '$_tplPageUrl=(string)"' . addslashes($this->url) . '";' . - 'if ($_tplPageCount > 0 && $_tplPagePer > 0) {' . - '$_tplTmpPageTotal = ceil($_tplPageCount / $_tplPagePer);' . - 'if ($_tplPageTotal > $_tplTmpPageTotal) $_tplPageTotal = $_tplTmpPageTotal;' . - '}' . - '$_tplPageCurrent > $_tplPageTotal && $_tplPageCurrent = $_tplPageTotal;' . - 'if ($_tplPageTotal > 1) {' . - "?>\r\n" . - $this->getTplContent() . - "\r\n"; + $strPageCode = 'count . ';' . '$_tplPagePer=(int)' . $this->per . ';' . + '$_tplPageTotal=(int)' . $this->total . ';' . '$_tplPageCurrent=(int)' . $this->page . ';' . + '$_tplPageUrl=(string)"' . addslashes($this->url) . '";' . 'if ($_tplPageCount > 0 && $_tplPagePer > 0) {' . + '$_tplTmpPageTotal = ceil($_tplPageCount / $_tplPagePer);' . + 'if ($_tplPageTotal > $_tplTmpPageTotal) $_tplPageTotal = $_tplTmpPageTotal;' . '}' . + '$_tplPageCurrent > $_tplPageTotal && $_tplPageCurrent = $_tplPageTotal;' . 'if ($_tplPageTotal > 1) {' . + "?>\r\n" . $this->getTplContent() . "\r\n"; return $strPageCode; } - + private function getTplContent() { if ($this->tpl) { list($compileFile, $content) = $this->windViewerResolver->compile($this->tpl, '', true); @@ -71,11 +61,11 @@ private function parsePageTags($content) { $arrPageVars = array('$_tplPageTotal', '$_tplPageCurrent', '$_tplPageUrl'); return str_ireplace($arrPageTags, $arrPageVars, $content); } - + private function getDefaultHtml() { return ''; } - + /* * @see AbstractWindTemplateCompiler::getProperties() */ diff --git a/wind/core/viewer/compiler/WindTemplateCompilerScript.php b/wind/component/viewer/compiler/WindTemplateCompilerScript.php similarity index 89% rename from wind/core/viewer/compiler/WindTemplateCompilerScript.php rename to wind/component/viewer/compiler/WindTemplateCompilerScript.php index 9dff218e..9e5a074c 100644 --- a/wind/core/viewer/compiler/WindTemplateCompilerScript.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerScript.php @@ -1,9 +1,6 @@ * @author Qiong Wu * @version $Id$ diff --git a/wind/core/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php similarity index 79% rename from wind/core/viewer/compiler/WindTemplateCompilerTemplate.php rename to wind/component/viewer/compiler/WindTemplateCompilerTemplate.php index e5a19890..f78712f0 100644 --- a/wind/core/viewer/compiler/WindTemplateCompilerTemplate.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php @@ -1,22 +1,19 @@ * @author Qiong Wu * @version $Id$ * @package */ class WindTemplateCompilerTemplate extends AbstractWindTemplateCompiler { - + protected $source = ''; - + protected $suffix = ''; - + protected $load = 'true'; - + protected $includeFiles = ''; /* (non-PHPdoc) @@ -27,10 +24,10 @@ public function compile($key, $content) { preg_match('/[\$\(\/\\]]/i', $this->source, $result); if (empty($result)) { if ($this->load === 'false') { - $content = 'windViewerResolver->compile($this->source, $this->suffix)) . '\'); ?>'; + list($_tmp) = $this->windViewerResolver->compile($this->source, $this->suffix); + $content = ''; } else { list($compileFile, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, true); - $this->includeFiles .= $this->source . ':' . filemtime($compileFile) . ' '; } } else @@ -39,10 +36,6 @@ public function compile($key, $content) { return $content; } - protected function postCompile() { - - } - /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::getProperties() */ diff --git a/wind/core/viewer/compiler/WindViewTemplate.php b/wind/component/viewer/compiler/WindViewTemplate.php similarity index 71% rename from wind/core/viewer/compiler/WindViewTemplate.php rename to wind/component/viewer/compiler/WindViewTemplate.php index b719bf56..854bd5b2 100644 --- a/wind/core/viewer/compiler/WindViewTemplate.php +++ b/wind/component/viewer/compiler/WindViewTemplate.php @@ -1,6 +1,6 @@ "; - + protected $compiledBlockData = array(); - + /** * 模板编译器支持的标签信息 * * @var array('targName','args info') */ protected $_compilerCache = array(); - + protected $windHandlerInterceptorChain = null; /* (non-PHPdoc) * @see AbstractWindViewTemplate::doCompile() */ protected function doCompile($content, $windViewerResolver = null) { - $content = $this->registerTags($content, $windViewerResolver); - if ($this->windHandlerInterceptorChain !== null) { - $this->windHandlerInterceptorChain->getHandler()->handle(); + try { + $content = $this->registerTags($content, $windViewerResolver); + if ($this->windHandlerInterceptorChain !== null) { + $this->windHandlerInterceptorChain->getHandler()->handle(); + } + foreach (array_reverse($this->compiledBlockData) as $key => $value) { + if (!$key) continue; + $content = str_replace($this->getBlockTag($key), ($value ? $value : ' '), $content); + } + $content = preg_replace('/\?>(\s|\n)*?<\?php/i', "\r\n", $content); + return $content; + } catch (Exception $e) { + throw new WindViewException('[component.viewer.WindViewTemplate.doCompile] compile fail.' . $e->getMessage(), + WindViewException::ERROR_SYSTEM_ERROR); } - foreach (array_reverse($this->compiledBlockData) as $key => $value) { - if (!$key) continue; - $content = str_replace($this->getBlockTag($key), ($value ? $value : ' '), $content); - } - $content = preg_replace('/\?>(\s|\n)*?<\?php/i', "\r\n", $content); - return $content; - } - - /* (non-PHPdoc) - * @see AbstractWindViewTemplate::getTags() - */ - protected function getTags() { - $_tags['internal'] = $this->createTag('internal', 'WIND:core.viewer.compiler.WindTemplateCompilerInternal', '/<\?php(.|\n)*?\?>/i'); - /*标签体增加在该位置*/ - $_tags['template'] = $this->createTag('template', 'WIND:core.viewer.compiler.WindTemplateCompilerTemplate'); - $_tags['page'] = $this->createTag('page', 'WIND:core.viewer.compiler.WindTemplateCompilerPage'); - $_tags['action'] = $this->createTag('action', 'WIND:core.viewer.compiler.WindTemplateCompilerAction'); - $_tags['component'] = $this->createTag('component', 'WIND:core.viewer.compiler.WindTemplateCompilerComponent'); - /*标签解析结束*/ - $_tags += (array) parent::getTags(); - $_tags['expression'] = $this->createTag('expression', 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', '/({@|{\$)[^{@=\n]*}/i'); - $_tags['echo'] = $this->createTag('echo', 'WIND:core.viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); - return $_tags; - } - - /** - * 创建tag配置 - * @param string $tag - * @param string $class - */ - private function createTag($tag, $class, $pattern = '') { - return array(self::TAG => $tag, self::PATTERN => $pattern, self::COMPILER => $class); } /** @@ -98,16 +77,44 @@ private function registerTags($content, $windViewerResolver = null) { private function creatTagCompiler($content, $compiler, $regex, $windViewerResolver = null) { $content = preg_replace_callback($regex, array($this, '_creatTagCompiler'), $content); if ($this->windHandlerInterceptorChain === null) { - Wind::import('WIND:core.filter.WindHandlerInterceptorChain'); $this->windHandlerInterceptorChain = new WindHandlerInterceptorChain(); } $_compilerClass = Wind::import($compiler); - if (!class_exists($_compilerClass)) return $content; - $this->windHandlerInterceptorChain->addInterceptors(new $_compilerClass($this->_compilerCache, $this, $windViewerResolver, $this->request, $this->response)); + $this->windHandlerInterceptorChain->addInterceptors( + new $_compilerClass($this->_compilerCache, $this, $windViewerResolver, $this->getRequest(), + $this->getResponse())); $this->_compilerCache = array(); return $content; } + /* (non-PHPdoc) + * @see AbstractWindViewTemplate::getTags() + */ + protected function getTags() { + $_tags['internal'] = $this->createTag('internal', 'COM:viewer.compiler.WindTemplateCompilerInternal', + '/<\?php(.|\n)*?\?>/i'); + /*标签体增加在该位置*/ + $_tags['template'] = $this->createTag('template', 'COM:viewer.compiler.WindTemplateCompilerTemplate'); + $_tags['page'] = $this->createTag('page', 'COM:viewer.compiler.WindTemplateCompilerPage'); + $_tags['action'] = $this->createTag('action', 'COM:viewer.compiler.WindTemplateCompilerAction'); + $_tags['component'] = $this->createTag('component', 'COM:viewer.compiler.WindTemplateCompilerComponent'); + /*标签解析结束*/ + $_tags += (array) parent::getTags(); + $_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', + '/({@|{\$)[^{@=\n]*}/i'); + $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); + return $_tags; + } + + /** + * 创建tag配置 + * @param string $tag + * @param string $class + */ + private function createTag($tag, $class, $pattern = '') { + return array(self::TAG => $tag, self::PATTERN => $pattern, self::COMPILER => $class); + } + /** * 将标签匹配到的模板内容设置到缓存中,并返回标识位到模板中进行内容站位 * @param string $content @@ -141,7 +148,6 @@ private function getBlockTag($key) { * @return string */ protected function getCompiledBlockKey() { - Wind::import('WIND:component.utility.WindUtility'); $key = WindUtility::generateRandStr(50); if (key_exists($key, $this->compiledBlockData)) { return $this->getCompiledBlockKey(); diff --git a/wind/core/exception/WindViewException.php b/wind/component/viewer/exception/WindViewException.php similarity index 70% rename from wind/core/exception/WindViewException.php rename to wind/component/viewer/exception/WindViewException.php index 2a51b3a5..59bfbd9c 100644 --- a/wind/core/exception/WindViewException.php +++ b/wind/component/viewer/exception/WindViewException.php @@ -10,8 +10,9 @@ * @package */ class WindViewException extends WindException { - + const VIEW_NOT_EXIST = '300'; + const COMPILE_NOT_EXIST = '400'; /** * 自定义异常号的对应异常信息 @@ -20,8 +21,8 @@ class WindViewException extends WindException { * @return string 返回异常号对应的异常组装信息原型 */ protected function messageMapper($code) { - $messages = array(self::VIEW_NOT_EXIST => 'Not exist view template file or Incorrect file path \'$message\'.'); - + $messages[self::VIEW_NOT_EXIST] = 'Not exist view template file or Incorrect file path \'$message\''; + $messages[self::COMPILE_NOT_EXIST] = 'Not exist view compile file or Incorrect file path \'$message\''; return isset($messages[$code]) ? $messages[$code] : '$message'; } } diff --git a/wind/core/viewer/listener/WindViewCacheListener.php b/wind/component/viewer/listener/WindViewCacheListener.php similarity index 100% rename from wind/core/viewer/listener/WindViewCacheListener.php rename to wind/component/viewer/listener/WindViewCacheListener.php diff --git a/wind/components_config.php b/wind/components_config.php index d6fe2660..60a2a379 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -1,26 +1,103 @@ - array('path' => 'WIND:core.web.WindWebApplication', 'scope' => 'request', - 'properties' => array('dispatcher' => array('ref' => 'dispatcher'))), - 'dispatcher' => array('path' => 'WIND:core.web.WindDispatcher', 'scope' => 'prototype'), - 'windLogger' => array('path' => 'WIND:component.log.WindLogger', 'scope' => 'request'), - 'forward' => array('path' => 'WIND:core.web.WindForward', 'scope' => 'prototype'), - 'urlBasedRouter' => array('path' => 'WIND:core.router.WindUrlBasedRouter', 'scope' => 'application', - 'config' => array('module' => array('url-param' => 'm', 'default-value' => 'default'), - 'controller' => array('url-param' => 'c', 'default-value' => 'index'), - 'action' => array('url-param' => 'a', 'default-value' => 'run'))), - 'urlHelper' => array('path' => 'WIND:core.web.WindUrlHelper', 'scope' => 'singleton', - 'properties' => array('windRouter' => array('ref' => 'urlBasedRouter')), - 'config' => array('url-pattern' => array('value' => '-/'), 'route-suffix' => array('value' => 'htm'), - 'route-param' => array('value' => 'r'))), - 'windView' => array('path' => 'WIND:core.viewer.WindView', 'scope' => 'prototype', - 'config' => array('template-dir' => array('value' => 'template'), 'template-ext' => array('value' => 'htm'), - 'is-cache' => array('value' => 'true'), 'cache-dir' => array('value' => 'cache'), - 'compile-dir' => array('value' => 'compile.template')), - 'properties' => array('viewResolver' => array('ref' => 'viewResolver'))), - 'viewResolver' => array('path' => 'WIND:core.viewer.WindViewerResolver', 'scope' => 'prototype', - 'properties' => array('urlHelper' => array('ref' => 'urlHelper'))), - 'template' => array('path' => 'WIND:core.viewer.compiler.WindViewTemplate', 'scope' => 'prototype', - 'config' => array('resource' => '')), - 'errorMessage' => array('path' => 'WIND:core.web.WindErrorMessage', 'scope' => 'prototype')); -?> \ No newline at end of file + array( + 'path' => 'WIND:core.web.WindWebApplication', + 'scope' => 'singleton', + 'properties' => array( + 'dispatcher' => array( + 'ref' => 'dispatcher', + ), + ), + ), + 'dispatcher' => array( + 'path' => 'WIND:core.web.WindDispatcher', + 'scope' => 'prototype', + 'properties' => array( + 'urlHelper' => array( + 'ref' => 'urlHelper', + ), + ), + ), + 'forward' => array( + 'path' => 'WIND:core.web.WindForward', + 'scope' => 'prototype', + ), + 'urlBasedRouter' => array( + 'path' => 'WIND:core.router.WindUrlBasedRouter', + 'scope' => 'prototype', + 'config' => array( + 'module' => array( + 'url-param' => 'm', + 'default-value' => 'default', + ), + 'controller' => array( + 'url-param' => 'c', + 'default-value' => 'index', + ), + 'action' => array( + 'url-param' => 'a', + 'default-value' => 'run', + ), + ), + ), + 'urlHelper' => array( + 'path' => 'WIND:core.web.WindUrlHelper', + 'scope' => 'singleton', + 'properties' => array( + 'windRouter' => array( + 'ref' => 'urlBasedRouter', + ), + ), + 'config' => array( + 'url-pattern' => array( + 'value' => '-/', + ), + 'route-suffix' => array( + 'value' => 'htm', + ), + 'route-param' => array( + 'value' => 'r', + ), + ), + ), + 'windView' => array( + 'init-method' => 'init', + 'path' => 'COM:viewer.WindView', + 'scope' => 'prototype', + 'config' => array( + 'template-dir' => array( + 'value' => 'template', + ), + 'template-ext' => array( + 'value' => 'htm', + ), + 'is-cache' => array( + 'value' => 'true', + ), + ), + 'properties' => array( + 'viewResolver' => array( + 'ref' => 'viewResolver', + ), + ), + ), + 'viewResolver' => array( + 'path' => 'COM:viewer.WindViewerResolver', + 'scope' => 'prototype', + 'properties' => array( + 'urlHelper' => array( + 'ref' => 'urlHelper', + ), + ), + ), + 'template' => array( + 'path' => 'COM:viewer.compiler.WindViewTemplate', + 'scope' => 'prototype', + 'config' => array( + 'resource' => '', + ), + ), + 'errorMessage' => array( + 'path' => 'WIND:core.web.WindErrorMessage', + 'scope' => 'prototype', + ), +); \ No newline at end of file diff --git a/wind/core/AbstractWindServer.php b/wind/core/AbstractWindServer.php deleted file mode 100644 index 7be412be..00000000 --- a/wind/core/AbstractWindServer.php +++ /dev/null @@ -1,159 +0,0 @@ - 2010-11-7 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class AbstractWindServer { - const METHOD_DELETE = "DELETE"; - const METHOD_HEAD = "HEAD"; - const METHOD_GET = "GET"; - const METHOD_OPTIONS = "OPTIONS"; - const METHOD_POST = "POST"; - const METHOD_PUT = "PUT"; - const METHOD_TRACE = "TRACE"; - private $request; - private $response; - - /** - * @throws Exception - */ - public function __construct() { - try { - Wind::import('WIND:core.request.WindHttpRequest'); - $this->request = new WindHttpRequest(); - $this->response = $this->request->getResponse(); - } catch (Exception $exception) { - throw new Exception('init action servlet failed!!'); - } - } - - /** - * 执行操作 - * @throws Exception - */ - public function run() { - if ($this->request === null || $this->response === null) { - throw new Exception('init action servlet failed!!'); - } - $this->beforeProcess($this->request, $this->response); - $this->service($this->request, $this->response); - $this->afterProcess($this->request, $this->response); - $this->response->sendResponse(); - } - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - */ - protected function beforeProcess(WindHttpRequest $request, WindHttpResponse $response) {} - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - */ - protected function afterProcess(WindHttpRequest $request, WindHttpResponse $response) {} - - /** - * 执行请求的操作 - */ - abstract protected function process(WindHttpRequest $request, WindHttpResponse $response); - - /** - * Receives standard HTTP requests from the public - * service method and dispatches - * them to the action methods defined in - * this class.There's no need to override this method. - * - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @throws Exception - */ - protected function service(WindHttpRequest $request, WindHttpResponse $response) { - $method = $request->getRequestMethod(); - if (strcasecmp($method, self::METHOD_GET) == 0) { - $this->doGet($request, $response); - } else if (strcasecmp($method, self::METHOD_POST) == 0) { - $this->doPost($request, $response); - } else if (strcasecmp($method, self::METHOD_PUT) == 0) { - $this->doPut($request, $response); - } else if (strcasecmp($method, self::METHOD_DELETE) == 0) { - $this->doDelete($request, $response); - } else if (strcasecmp($method, self::METHOD_HEAD) == 0) {} else if (strcasecmp($method, self::METHOD_OPTIONS) == 0) {} else if (strcasecmp($method, self::METHOD_TRACE) == 0) {} else { - $errMsg = 'your request method is not supported!!!'; - $response->sendError(WindHttpResponse::SC_METHOD_NOT_ALLOWED, $errMsg); - } - } - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @throws Exception - */ - protected function doPost(WindHttpRequest $request, WindHttpResponse $response) { - $protocol = $request->getProtocol(); - $msg = "The method post is not supported."; - if (!$protocol || (strpos($protocol, '1.1')) !== false) { - $response->sendError(WindHttpResponse::SC_METHOD_NOT_ALLOWED, $msg); - } else - $this->process($request, $response); - } - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @throws Exception - */ - protected function doGet(WindHttpRequest $request, WindHttpResponse $response) { - $protocol = $request->getProtocol(); - $msg = "The method get is not supported."; - if (!$protocol || (strpos($protocol, '1.1')) !== false) { - $response->sendError(WindHttpResponse::SC_METHOD_NOT_ALLOWED, $msg); - } else - $this->process($request, $response); - } - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @throws Exception - */ - protected function doPut(WindHttpRequest $request, WindHttpResponse $response) { - $this->process($request, $response); - } - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @throws Exception - */ - protected function doDelete(WindHttpRequest $request, WindHttpResponse $response) { - $this->process($request, $response); - } - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - */ - protected function doTrace(WindHttpRequest $request, WindHttpResponse $response) {} - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - */ - protected function doOptions(WindHttpRequest $request, WindHttpResponse $response) {} - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @throws Exception - */ - protected function doHead(WindHttpRequest $request, WindHttpResponse $response) {} -} \ No newline at end of file diff --git a/wind/core/WindComponentModule.php b/wind/core/WindComponentModule.php deleted file mode 100644 index a387fd20..00000000 --- a/wind/core/WindComponentModule.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @author Qiong Wu - * @version $Id: WindComponent.php 809 2010-12-22 11:28:28Z yishuo $ - * @package - */ -abstract class WindComponentModule extends WindModule { - private $_attribute = array(); - private $_config = null; - /** - * @var WindHttpRequest - */ - protected $request; - /** - * @var WindHttpResponse - */ - protected $response; - /** - * @var WindSystemConfig - */ - protected $windSystemConfig; - /** - * @var WindFactory - */ - protected $windFactory; - - /** - * 初始化方法 - */ - public function init() {} - - /** - * Enter description here ... - */ - protected function getAutoSetProperty() { - return array('request' => 'IWindRequest', 'response' => 'IWindResponse', 'windSystemConfig' => 'WindSystemConfig', 'windFactory' => 'WindFactory'); - } - - /** - * Enter description here ... - */ - public function getAttribute($alias = '') { - if ($alias === '') - return $this->_attribute; - else - return isset($this->_attribute[$alias]) ? $this->_attribute[$alias] : null; - } - - /** - * @param string $alias - * @param object $object - */ - public function setAttribute($alias, $object = null) { - if (is_array($alias)) - $this->_attribute += $alias; - elseif (is_string($alias)) - $this->_attribute[$alias] = $object; - } - - /** - * 根据配置名取得相应的配置 - * @param string $configName 键名 - * @param string $subConfigName 二级键名 - * @param array $default 默认值 - * @return string|array - */ - public function getConfig($configName = '', $subConfigName = '', $default = '') { - if (null === $this->_config) return ''; - return $this->_config->getConfig($configName, $subConfigName, array(), $default); - } - - /** - * @param string|array|windConfig $config - */ - public function setConfig($config) { - if (is_object($config)) { - $this->_config = $config; - } elseif (is_array($config)) { - $this->_config = new WindConfig($config); - } elseif (is_string($config)) { - Wind::import('WIND:core.config.parser.WindConfigParser'); - $configParser = new WindConfigParser(); - $this->_config = new WindConfig($config, $configParser, get_class($this), CONFIG_CACHE); - } - } - - /** - * 更改现有的config 或是合并 - * @param array $config - * @param boolean 是否合并现有 - * @return true - */ - public function updateConfig($config, $merge = false) { - if (null === $this->_config) return false; - $this->_config->setConfig($config, $merge); - return true; - } -} \ No newline at end of file diff --git a/wind/core/WindEnableValidateModule.php b/wind/core/WindEnableValidateModule.php index 44812fec..6bb20cff 100644 --- a/wind/core/WindEnableValidateModule.php +++ b/wind/core/WindEnableValidateModule.php @@ -1,11 +1,4 @@ - 2011-1-7 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:core.WindModule'); + * @version $Id$ * @package - */ -abstract class WindEnableValidateModule extends WindModule { - - protected $_validatorClass = 'WIND:component.utility.WindValidator'; - protected $errorController = ''; - protected $errorAction = ''; - - private $_validator = null; - - private $_errors = array(); - - private $_defaultMessage = 'the field validate fail.'; - + */ +class WindEnableValidateModule extends WindModule { + protected $_validatorClass = 'WIND:component.utility.WindValidator'; + protected $errorController = ''; + protected $errorAction = ''; + private $_validator = null; + private $_errors = array(); + private $_defaultMessage = 'the field validate fail.'; + /** * @return the $_errors - */ - public function getErrors() { - return $this->_errors; - } - - public function getErrorControllerAndAction() { - return array($this->errorController, $this->errorAction); - } + */ + public function getErrors() { + return $this->_errors; + } + + public function getErrorControllerAndAction() { + return array( + $this->errorController, + $this->errorAction); + } + /** * 返回验证规则 * * validator : required/not-required * @return multitype:multitype:string - */ - protected function validateRules() { - return array(); - } - + */ + protected function validateRules() { + return array(); + } + /** * 验证方法 * * @param array|WindModule $input - */ - public function validate(&$input) { - if (is_array($input)) - $this->validateArray($input); - elseif (is_object($input)) - $this->validateObject($input); - } - + */ + public function validate(&$input) { + if (is_array($input)) + $this->validateArray($input); + elseif (is_object($input)) + $this->validateObject($input); + } + /** * 验证数组类型的输入 * @param array $input - */ - private function validateArray(&$input) { - $rules = $this->validateRules(); - foreach ((array) $rules as $rule) { - $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; - $arg = (array) $rule['args']; - array_unshift($arg, $_input); - if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; - if ($rule['default'] === null) { - $this->_errors[$rule['field']] = $rule['message']; - continue; - } - $input[$rule['field']] = $rule['default']; - } - } - + */ + private function validateArray(&$input) { + $rules = $this->validateRules(); + foreach ((array) $rules as $rule) { + $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; + $arg = (array) $rule['args']; + array_unshift($arg, $_input); + if (call_user_func_array(array( + $this->getValidator(), + $rule['validator']), $arg) !== false) continue; + if ($rule['default'] === null) { + $this->_errors[$rule['field']] = $rule['message']; + continue; + } + $input[$rule['field']] = $rule['default']; + } + } + /** * 验证对象类型的输入 * 需要设置set和get方式 * * @param object $input 传入需要验证的数据 * - */ - private function validateObject(&$input) { - $rules = $this->validateRules(); - $methods = get_class_methods($input); - foreach ((array) $rules as $rule) { - $getMethod = 'get' . ucfirst($rule['field']); - $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; - $arg = (array) $rule['args']; - array_unshift($arg, $_input); - if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; - if ($rule['default'] === null) { - $this->_errors[$rule['field']] = $rule['message']; - continue; - } - $setMethod = 'set' . ucfirst($rule['field']); - in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); - } - } - + */ + private function validateObject(&$input) { + $rules = $this->validateRules(); + $methods = get_class_methods($input); + foreach ((array) $rules as $rule) { + $getMethod = 'get' . ucfirst($rule['field']); + $_input = in_array($getMethod, $methods) ? call_user_func(array( + $input, + $getMethod)) : ''; + $arg = (array) $rule['args']; + array_unshift($arg, $_input); + if (call_user_func_array(array( + $this->getValidator(), + $rule['validator']), $arg) !== false) continue; + if ($rule['default'] === null) { + $this->_errors[$rule['field']] = $rule['message']; + continue; + } + $setMethod = 'set' . ucfirst($rule['field']); + in_array($setMethod, $methods) && call_user_func_array(array( + $input, + $setMethod), array( + $rule['default'])); + } + } + /** * @param WindValidator $validator - */ - protected function setValidator($validator) { - $this->_validator = $validator; - } - + */ + protected function setValidator($validator) { + $this->_validator = $validator; + } + /** * 返回验证器 * @return WindValidator - */ - protected function getValidator() { - if ($this->_validator === null) { - $_className = Wind::import($this->_validatorClass); - Wind::import('WIND:core.factory.WindFactory'); - $this->_validator = WindFactory::createInstance($_className); - if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); - } - return $this->_validator; - } + */ + protected function getValidator() { + if ($this->_validator === null) { + $_className = Wind::import($this->_validatorClass); + Wind::import('WIND:core.factory.WindFactory'); + $this->_validator = WindFactory::createInstance($_className); + if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); + } + return $this->_validator; + } } \ No newline at end of file diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php index 9c9cedf2..0f414ea6 100644 --- a/wind/core/WindHelper.php +++ b/wind/core/WindHelper.php @@ -2,6 +2,7 @@ /** * wind core 基础帮助类 * 不建议被外部调用 + * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ @@ -9,7 +10,6 @@ */ class WindHelper { - /** * 解析ControllerPath * 返回解析后的controller信息,controller,module,app diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 800f65ad..df4ac025 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -1,128 +1,275 @@ - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2010 phpwind.com - * @license - */ - +Wind::import('COM:utility.WindUtility'); /** * 所有module的基础抽象类 - * 主要实现__get(), __set()等方法 - * 通过继承该类 + * 主要实现__get(), __set()等方法 * * @author Qiong Wu * @version $Id$ */ -abstract class WindModule { - - private $_classProxy = null; +class WindModule { + /** + * @var WindConfig + */ + private $_config = null; + /** + * 该对象的数组形态 + * + * @var array + */ + private $_array = array(); + /** + * 是否进行类型验证 + * + * @var boolean + */ + protected $_typeValidation = false; + /** + * 请求参数信息 + * + * @var array + */ + private $delayAttributes = array(); /** + * 设置属性值,该属性的访问类型不能为‘private’类型 + * * @param string $propertyName * @param string $value + * @return */ public function __set($propertyName, $value) { - if (!$this->validatePropertyName($propertyName, $value)) return; - $this->$propertyName = $value; + if (!$this->validatePropertyName($propertyName)) { + $_setter = 'set' . ucfirst($propertyName); + if (method_exists($this, $_setter)) + $this->$_setter($value); + else + Wind::log('[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, + WindLogger::LEVEL_DEBUG, 'wind.core'); + } else + $this->$propertyName = $value; } /** + * 返回输入的属性的值,如果该属性不存在或访问类型为‘private’类型,则返回null + * * @param string $propertyName + * @return value of the property or null */ public function __get($propertyName) { - if (!$this->validatePropertyName($propertyName)) return null; - return $propertyName; + if (!$this->validatePropertyName($propertyName)) { + $_getter = 'get' . ucfirst($propertyName); + if (method_exists($this, $_getter)) + return $this->$_getter(); + else + Wind::log('[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, + WindLogger::LEVEL_DEBUG, 'wind.core'); + } else + return $this->$propertyName; } /** - * 实现setter或者getter方法调用 + * 实现setter或者getter方法调用,并返回你调用方法的返回值 * + * @param string $methodName + * @param array $args + * @return the return of the method your call */ public function __call($methodName, $args) { - $_propertyName = ''; - $_perfix = substr($methodName, 0, 3); - if (in_array($_perfix, array('set', 'get'))) { - $_propertyName = trim(substr($methodName, 3), '_'); - $_propertyName = strtolower(substr($_propertyName, 0, 1)) . substr($_propertyName, 1); - if (!$_propertyName || !in_array($_propertyName, (array) $this->getWriteTableForGetterAndSetter())) return; - switch ($_perfix) { - case 'set': - $this->$_propertyName = $args[0]; - break; - case 'get': - return $this->$_propertyName; - break; - default: - break; + $_prefix = substr($methodName, 0, 4); + $_propertyName = substr($methodName, 4); + $_propertyName = WindUtility::lcfirst($_propertyName); + if ($_prefix == '_set') { + $this->$_propertyName = $args[0]; + } elseif ($_prefix == '_get') { + if (property_exists($this, $_propertyName) && $this->$_propertyName) { + return $this->$_propertyName; + } + if (isset($this->delayAttributes[$_propertyName])) { + $_instance = null; + $_property = $this->delayAttributes[$_propertyName]; + if (isset($_property[WindClassDefinition::REF])) { + $_ref = $_property[WindClassDefinition::REF]; + if ($this->getSystemFactory()->checkAlias($_ref)) + $_instance = $this->getSystemFactory()->getInstance($_ref); + else + $_instance = $this->getSystemFactory()->createInstance($_ref); + } + $this->$_propertyName = $_instance; + Wind::log("[core.WindMOdule.__call] create property $_propertyName fail.", WindLogger::LEVEL_DEBUG, + 'wind.core'); + + // unset($this->delayAttributes[$_propertyName]); } + Wind::log("[core.WindModule.__call] attribute is not exist. + (" . $methodName . ")", WindLogger::LEVEL_DEBUG, + 'wind.core'); + return $this->$_propertyName; } + throw new WindException('[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); } + /** + * 对象clone魔术方法 + */ public function __clone() { - foreach ($this->getCloneProperty() as $value) { + foreach ($this->writeTableCloneProperty() as $value) { + if (!is_object($this->$value) || !isset($this->$value)) { + Wind::log( + "[core.WindModule.__clone] unexcepted value type or the property + is not setted.(" . $value . ") need an object type in here. + ", WindLogger::LEVEL_DEBUG, 'wind.core'); + continue; + } $this->$value = clone $this->$value; } } /** - * Enter description here ... + * 返回该对象的数组类型 * - * @return multitype: + * @return array */ public function toArray() { - $class = new ReflectionClass(get_class($this)); - $properties = $class->getProperties(); - $vars = array(); - foreach ($properties as $property) { - $_propertyName = $property->name; - $vars[$_propertyName] = $this->$_propertyName; + if (empty($this->_array)) { + $reflection = new ReflectionClass(get_class($this)); + $properties = $reflection->getProperties(); + $_result = array(); + foreach ($properties as $property) { + $_propertyName = $property->name; + $_result[$_propertyName] = $this->$_propertyName; + } + $this->_array = $_result; } - return $vars; + return $this->_array; } /** - * @return the $_classProxy + * 验证白名单是否为空,或属性值是否存在于定义的白名单中 + * + * @param string $propertyName + * @return boolean */ - public function getClassProxy() { - return ($this->_classProxy instanceof WindClassProxy) ? $this->_classProxy : null; + protected function validatePropertyName($propertyName, $value = null) { + if (isset($this->delayAttributes[$propertyName])) { + Wind::log('[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', + WindLogger::LEVEL_DEBUG, 'wind.core'); + return true; + } + if (!($_writeTableProperties = $this->writeTableForProperty())) { + Wind::log( + "[core.WindModule.validatePropertyName] + writeTableForProperty is empty or your input is not exists. + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); + return false; + } + if (!array_key_exists($propertyName, $_writeTableProperties)) { + Wind::log( + "[core.WindModule.validatePropertyName] + writeTableForProperty is empty or your input is not exists. + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); + return false; + } + if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { + if ($value instanceof $_writeTableProperties[$propertyName]) return true; + Wind::log( + "[core.WindModule.validatePropertyName] + type of the property " . $propertyName . " is not defined. + ", WindLogger::LEVEL_DEBUG, 'wind.core'); + return false; + } + return true; } /** - * @param WindClassProxy $classProxy + * 根据配置名取得相应的配置 + * + * @param string $configName 键名 + * @param string $subConfigName 二级键名 + * @param array $default 默认值 + * @return string|array */ - public function setClassProxy($classProxy) { - $this->_classProxy = $classProxy->initClassProxy($this); + public function getConfig($configName = '', $subConfigName = '', $default = '') { + if ($this->_config === null) { + Wind::log('[core.WindModule.getConfig] config is not exist.', WindLogger::LEVEL_INFO, 'wind.core'); + return $default; + } + return $this->_config->getConfig($configName, $subConfigName, array(), $default); } /** - * 验证属性白名单 + * Config配置,如果配置信息已经存在,则会合并配置 + * + * @param string|array|windConfig $config */ - protected function validatePropertyName($propertyName, $value = null) { - $autoSetProperty = $this->getAutoSetProperty(); - if (empty($autoSetProperty)) return true; + public function setConfig($config) { + if (!$config) return; + if (is_string($config)) { + Wind::import('WIND:core.config.parser.WindConfigParser'); + $config = new WindConfig($config, new WindConfigParser(), get_class($this), WIND_CONFIG_CACHE); + } elseif (is_array($config)) + $config = new WindConfig($config); - if (!key_exists($propertyName, $autoSetProperty)) return false; - //TODO add check for value - return true; + if ($this->_config !== null) + $this->_config->setConfig($config->getConfig(), true); + else + $this->_config = $config; } /** - * Enter description here ... + * 设置自动实现Getter/Setter方法的属性名称 + * 当该方法返回值为空时,类属性的可访问性跟默认相同 + * + * @return array */ - protected function getAutoSetProperty() { - return array(); + protected function writeTableForProperty() { + return array('delayAttributes' => 'array'); } /** - * 设置自动实现Getter/Setter方法的属性名称 + * 通过重载该方法,可以实现对对象内部的对象同时进行clone + * 返回需要被clone的对象数组 + * + * @return array */ - protected function getWriteTableForGetterAndSetter() { + protected function writeTableCloneProperty() { return array(); } - protected function getCloneProperty() { - return array(); + /** + * @return WindSystemConfig + */ + protected function getSystemConfig() { + return Wind::getApp()->getWindSystemConfig(); + } + + /** + * @return WindFactory + */ + protected function getSystemFactory() { + return Wind::getApp()->getWindFactory(); + } + + /** + * @return WindHttpRequest + */ + protected function getRequest() { + return Wind::getApp()->getRequest(); + } + + /** + * @return WindHttpResponse + */ + protected function getResponse() { + return Wind::getApp()->getResponse(); + } + + /** + * @param array $delayAttributes + */ + public function setDelayAttributes($delayAttributes) { + $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } \ No newline at end of file diff --git a/wind/core/config/WindConfig.php b/wind/core/config/WindConfig.php index c9277245..403f8aad 100644 --- a/wind/core/config/WindConfig.php +++ b/wind/core/config/WindConfig.php @@ -1,27 +1,15 @@ 2010-12-21 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.WindModule'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ -class WindConfig extends WindModule { - +class WindConfig { /* 配置解析信息 */ protected $configParser = null; - protected $cacheName; - protected $append; - protected $config = array(); /** @@ -47,13 +35,11 @@ public function __construct($config, $configParser = null, $cacheName = '', $app public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { if (!$config) $config = $this->config; if ($configName === '') return $config; - $_config = $default; if (isset($config[$configName])) { $_config = $config[$configName]; } if ($subConfigName === '') return $_config; - $_subConfig = $default; if (is_array($_config) && isset($_config[$subConfigName])) { $_subConfig = $_config[$subConfigName]; @@ -147,5 +133,4 @@ public function setCacheName($cacheName) { public function setAppend($append) { $this->append = $append; } - } \ No newline at end of file diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index 0b878f47..ddd3528f 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -5,7 +5,6 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ - Wind::import('WIND:core.config.WindConfig'); /** * 框架配置对象windConfig类, @@ -15,40 +14,24 @@ * @package */ class WindSystemConfig extends WindConfig { - /* 通用配置 */ const CLASS_PATH = 'class'; - const PATH = 'path'; - const VALUE = 'value'; - /* import 外部配置文件包含 */ const IMPORTS = 'imports'; - const IMPORTS_RESOURCE = 'resource'; - const IMPORTS_IS_APPEND = 'is-append'; - /* app 相关配置 */ const WEB_APPS = 'web-apps'; - const WEB_APP_ROOT_PATH = 'root-path'; - const WEB_APP_FACTORY = 'factory'; - const WEB_APP_FACTORY_CLASS_DEFINITION = 'class-definition'; - const WEB_APP_FILTER = 'filters'; - const WEB_APP_ROUTER = 'router'; - const WEB_APP_MODULE = 'modules'; - const WEB_APP_TEMPLATE = 'template'; - protected $appName = ''; - protected $imports = array(); /** @@ -93,12 +76,10 @@ public function getAppClass() { /** * 返回应用路径信息 - * * @return string */ public function getRootPath($appName = '') { if ($appName === '') $appName = $this->appName; - $_tmp = $appName . '_RootPath'; if (!isset($this->$_tmp)) { $appConfig = $this->getConfig(self::WEB_APPS, $appName); @@ -106,8 +87,6 @@ public function getRootPath($appName = '') { $rootPath = $appConfig[self::WEB_APP_ROOT_PATH]; else $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); - - //TODO 绝对路径相对路径判断,相对于webroot,支持自定义路径 $this->$_tmp = $rootPath; } return $this->$_tmp; @@ -122,6 +101,16 @@ public function getFactory($name = '') { } /** + * 返回filterChain的类型 + * @return array + */ + public function getFilterClass() { + return $this->getFilters(self::CLASS_PATH); + } + + /** + * 返回配置定义中定义的过滤链列表 + * 如果定义$name则返回在filters定义标签内对应的属性值 * @param string $name * @return array|string */ @@ -130,6 +119,14 @@ public function getFilters($name = '') { return $this->getConfig(self::WEB_APP_FILTER, $name, $_config); } + /** + * 返回路由类型定义 + * @return string + */ + public function getRouterClass() { + return $this->getRouter(WIND_CONFIG_CLASS); + } + /** * @param string $name * @return array|string @@ -140,7 +137,27 @@ public function getRouter($name = '') { return $_router ? $_router : COMPONENT_ROUTER; } - /** + /** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * * @param string $name * @return array|string */ @@ -149,6 +166,57 @@ public function getModules($name = '') { return $this->getConfig(self::WEB_APP_MODULE, $name, $_config); } + /** + * 根据module名称返回module的视图处理类 + * @param string $name + * @param string $default + */ + public function getModuleViewClassByModuleName($name, $default = '') { + $module = $this->getModules($name); + return $this->getConfig('view', WIND_CONFIG_CLASS, $module, $default); + } + + /** + * 根据module名称返回module的视图配置信息 + * @param string $name + * @param string $default + */ + public function getModuleViewConfigByModuleName($name, $default = '') { + $module = $this->getModules($name); + return $this->getConfig('view', WIND_CONFIG_CONFIG, $module, $default); + } + + /** + * 根据module名称返回错误的处理句柄 + * @param string $name + * @param string $default + * @return string + */ + public function getModuleErrorHandlerByModuleName($name, $default = '') { + $module = $this->getModules($name); + return $this->getConfig('error-handler', WIND_CONFIG_CLASS, $module, $default); + } + + /** + * 返回指定moduleName的controller路径信息 + * @param string $name + * @return string + */ + public function getModuleControllerPathByModuleName($name, $default = '') { + $module = $this->getModules($name); + return $this->getConfig(WIND_CONFIG_CLASSPATH, '', $module, $default); + } + + /** + * 返回指定moduleName的controller后缀 + * @param string $name + * @return string + */ + public function getModuleControllerSuffixByModuleName($name, $default = '') { + $module = $this->getModules($name); + return $this->getConfig('controller-suffix', WIND_CONFIG_VALUE, $module, $default); + } + /** * @param string $name * @return array|string @@ -209,5 +277,4 @@ protected function parseImport($name) { } return $this->imports[$name]; } - } \ No newline at end of file diff --git a/wind/core/config/parser/WindConfigParser.php b/wind/core/config/parser/WindConfigParser.php index 32403d9d..55bd70cd 100644 --- a/wind/core/config/parser/WindConfigParser.php +++ b/wind/core/config/parser/WindConfigParser.php @@ -1,5 +1,4 @@ error = $error; } - } - ?> \ No newline at end of file diff --git a/wind/core/exception/WindException.php b/wind/core/exception/WindException.php index a6bc5201..afbd8103 100644 --- a/wind/core/exception/WindException.php +++ b/wind/core/exception/WindException.php @@ -1,11 +1,4 @@ 2010-11-3 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - /** * 异常处理机制 * @@ -15,30 +8,24 @@ * @package */ class WindException extends Exception { - + /* 系统错误 */ + const ERROR_SYSTEM_ERROR = '0'; /* 类错误 */ const ERROR_CLASS_NOT_EXIST = '100'; - const ERROR_CLASS_TYPE_ERROR = '101'; - const ERROR_CLASS_METHOD_NOT_EXIST = '102'; - const ERROR_OBJECT_NOT_EXIST = '103'; - /* 参数错误 */ const ERROR_PARAMETER_TYPE_ERROR = '110'; - /* 配置错误 */ const ERROR_CONFIG_ERROR = '120'; - /* 返回值类型错误 */ const ERROR_RETURN_TYPE_ERROR = '130'; - + private $innerException = null; /** * 异常构造函数 - * * @param $message 异常信息 * @param $code 异常代号 * @param $innerException 内部异常 @@ -83,6 +70,7 @@ public function getStackTrace() { * @return string 组装后的异常信息 */ public function buildMessage($message, $code) { + $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } @@ -94,15 +82,14 @@ public function buildMessage($message, $code) { * @return string 返回异常号对应的异常组装信息原型 */ protected function messageMapper($code) { - $messages = array(self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', + $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', + self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', - self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , or the method is not exist.', + self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); - return isset($messages[$code]) ? $messages[$code] : '$message'; } - } \ No newline at end of file diff --git a/wind/core/exception/WindSqlException.php b/wind/core/exception/WindSqlException.php deleted file mode 100644 index b4b39f59..00000000 --- a/wind/core/exception/WindSqlException.php +++ /dev/null @@ -1,119 +0,0 @@ - 2010-11-15 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:core.exception.WindException'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSqlException extends WindException { - //TODO change exception message like WindException. - const DB_CONN_EMPTY = 200; - - const DB_CONN_FORMAT = 201; - - const DB_CONN_NOT_EXIST = 202; - - const DB_CONN_EXIST = 203; - - const DB_CONNECT_NOT_EXIST = 204; - - const DB_QUERY_EMPTY = 210; - - const DB_QUERY_LINK_EMPTY = 211; - - const DB_QUERY_FIELD_EMPTY = 212; - - const DB_QUERY_FIELD_EXIST = 213; - - const DB_QUERY_FIELD_FORMAT = 214; - - const DB_QUERY_INSERT_DATA = 215; - - const DB_QUERY_UPDATE_DATA = 216; - - const DB_QUERY_CONDTTION_FORMAT = 217; - - const DB_QUERY_GROUP_MATCH = 218; - - const DB_QUERY_LOGIC_MATCH = 219; - - const DB_QUERY_FETCH_ERROR = 220; - - const DB_QUERY_TRAN_BEGIN = 221; - - const DB_QUERY_COMPARESS_ERROR = 222; - - const DB_QUERY_COMPARESS_EXIST = 223; - - const DB_QUERY_WHERE_ERROR = 224; - - const DB_QUERY_JOIN_TYPE_ERROR = 225; - - const DB_TABLE_EMPTY = 240; - - const DB_EMPTY = 241; - - const DB_DRIVER_NOT_EXIST = 242; - - const DB_DRIVER_EXIST = 243; - - const DB_BUILDER_NOT_EXIST = 250; - - const DB_BUILDER_EXIST = 251; - - const DB_DRIVER_BUILDER_NOT_MATCH = 252; - - const DB_ADAPTER_NOT_EXIST = 260; - - const DB_ADAPTER_EXIST = 261; - - /** - * 重定义异常类型 - * - * @see WindException::messageMapper() - * @param int $code 异常号 - * @return string 最终输出异常信息的原型 - */ - protected function messageMapper($code) { - $messages = array( - self::DB_CONN_EMPTY => 'Database configuration is empty. \'$message\' ', - self::DB_CONN_FORMAT => 'Database configuration format is incorrect. \'$message\' ', - self::DB_CONN_NOT_EXIST => '\'$message\' The identify of the database connection does not exist. ', - self::DB_CONN_EXIST => '\'$message\' The identify of the database connection is aleady exist.', - self::DB_CONNECT_NOT_EXIST => '\'$message\' The database connection does not exist.', - self::DB_QUERY_EMPTY => 'Query is empty. \'$message\'', - self::DB_QUERY_LINK_EMPTY => '\'$message\' Query link is not a validate resource.', - self::DB_QUERY_FIELD_EMPTY => '\'$message\' Query field is empty.', - self::DB_QUERY_FIELD_EXIST => '\'$message\' Query field is not exist.', - self::DB_QUERY_FIELD_FORMAT => 'Inside the field in the query not formatted correctly. \'$message\'', - self::DB_QUERY_INSERT_DATA => 'The new data is empty. \'$message\'', - self::DB_QUERY_UPDATE_DATA => 'The Updated data is empty. \'$message\'', - self::DB_QUERY_CONDTTION_FORMAT => 'The conditions of query are not right. \'$message\'', - self::DB_QUERY_GROUP_MATCH => '\'$message\' Query group does not match.', - self::DB_QUERY_LOGIC_MATCH => '\'$message\' Query logic does not match.', - self::DB_QUERY_FETCH_ERROR => 'The wrong way to obtain the result set. \'$message\'', - self::DB_QUERY_TRAN_BEGIN => 'Transaction has not started. \'$message\'', - self::DB_QUERY_COMPARESS_ERROR => 'Query comparison is incorrect conversion or assembly. \'$message\'', - self::DB_QUERY_COMPARESS_EXIST => 'Comparison does not exist query. \'$message\'', - self::DB_QUERY_WHERE_ERROR => 'Query where is Error. \'$message\'', - self::DB_QUERY_JOIN_TYPE_ERROR => 'The database is wrong type of join query. \'$message\'', - self::DB_TABLE_EMPTY => 'Table is empty. \'$message\'', - self::DB_EMPTY => 'Database is empty. \'$message\'', - self::DB_DRIVER_NOT_EXIST => 'The database driver does not exist. \'$message\'', - self::DB_DRIVER_EXIST => 'The database driver is aleady exist. \'$message\'', - self::DB_BUILDER_NOT_EXIST => 'The database builder does not exist. \'$message\'', - self::DB_BUILDER_EXIST => 'The database builder is aleady exist. \'$message\'', - self::DB_ADAPTER_NOT_EXIST => 'The database adapter does not exist. \'$message\'', - self::DB_ADAPTER_EXIST => 'The database adapter is aleady exist. \'$message\'', - self::DB_DRIVER_BUILDER_NOT_MATCH => '\'$message\' The database driver does not match with the builder. ', - ); - return isset($messages[$code]) ? $messages[$code] : '$message'; - } -} \ No newline at end of file diff --git a/wind/core/factory/IWindFactory.php b/wind/core/factory/IWindFactory.php index 14d4c508..5a208bca 100644 --- a/wind/core/factory/IWindFactory.php +++ b/wind/core/factory/IWindFactory.php @@ -1,11 +1,4 @@ 2010-12-30 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - /** * 类工厂接口定义 * the last known user to change this file in the repository <$LastChangedBy$> @@ -22,10 +15,19 @@ interface IWindFactory { * 该方法首先通过类的别名到类的配置文件中找到类的相关配置信息, * 加载类的路径并创建类的依赖 * - * @param string $classAlias + * @param string $classAlias + * @return instance */ public function getInstance($classAlias); + /** + * 根据类的别名返回一个类的实例变量的clone + * + * @param string $classAlias + * @return clone of instance + */ + public function getPrototype($classAlias); + /** * 根据类名称创建类对象 * 返回一个类类型的实例对象,通过此方法创建类实例,并不能自动获取类路径信息 @@ -35,5 +37,4 @@ public function getInstance($classAlias); * @return Object | 返回的类类型的实例对象 */ static public function createInstance($className, $args = array()); - } \ No newline at end of file diff --git a/wind/core/factory/WindClassDefinition.php b/wind/core/factory/WindClassDefinition.php index ceeeee3d..56b6444b 100644 --- a/wind/core/factory/WindClassDefinition.php +++ b/wind/core/factory/WindClassDefinition.php @@ -1,11 +1,4 @@ 2010-12-31 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:core.WindModule'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @@ -19,7 +12,7 @@ * @version $Id$ * @package */ -class WindClassDefinition extends WindModule { +class WindClassDefinition { /* 配置信息定义 */ const NAME = 'name'; const PATH = 'path'; @@ -30,60 +23,87 @@ class WindClassDefinition extends WindModule { const CONSTRUCTOR_ARG = 'constructor-arg'; const REF = 'ref'; const VALUE = 'value'; + const DELAY = 'delay'; + const PROXY = 'proxy'; + const CONFIG = 'config'; + const RESOURCE = 'resource'; /* 支持的类命名空间 */ const SCOPE_SINGLETON = 'singleton'; const SCOPE_PROTOTYPE = 'prototype'; const SCOPE_REQUEST = 'request'; + /** + * 类代理类型 + * + * @var string + */ + protected $proxyClass = 'WIND:core.factory.proxy.WindClassProxy'; + /** + * 配置信息 + * + * @var string|array + */ + protected $config; + /** + * 类代理信息 + * + * @var boolean|string + */ + protected $proxy; /** - * 类名称 + * 类名称 + * * @var string */ - protected $className = ''; + protected $className; /** - * 类别名 + * 类别名 + * * @var string */ - protected $alias = ''; + protected $alias; /** - * 类路径 + * 类路径 + * * @var string */ - protected $path = ''; + protected $path; /** - * 类的存储空间 + * 类的存储空间 + * * singleton/prototype/request/session * @var string */ - protected $scope = ''; + protected $scope; /** * 类自定义的初始化方法 + * * @var string */ - protected $factoryMethod = ''; + protected $factoryMethod; /** * 类设置属性之后的调用处理操作 + * * @var string */ - protected $initMethod = ''; + protected $initMethod; /** - * 构造参数定义 + * 构造参数定义 + * * @var array */ protected $constructArgs = array(); /** - * 类属性定义 + * 类属性定义 + * * @var array */ - protected $propertys = array(); + protected $properties = array(); /** - * 类定义 + * 类定义 + * * @var array */ protected $classDefinition; - /** - * @var prototype - */ - private $prototype = null; /** * @var instance */ @@ -108,99 +128,101 @@ public function __construct($classDefinition = array()) { * @return instance|Ambigous |NULL */ public function getInstance($factory, $args = array()) { - if (($instance = $this->executeFactoryMethod($args)) != null) return $instance; + if ($instance = $this->executeFactoryMethod($args)) return $instance; switch ($this->scope) { case 'prototype': return $this->createInstanceWithPrototype($factory, $args); - case 'request': - return $this->createInstanceWithRequest($factory, $args); - case 'application': - return $this->createInstanceWithApplication($factory, $args); default: return $this->createInstanceWithSingleton($factory, $args); } } /** + * 以原型方式创建类实例 * @param IWindFactory $factory * @param array $args * @return NULL|object */ - protected function createInstanceWithApplication($factory, $args) { - if (!isset($factory->application)) return null; - if (null === $factory->application->getAttribute($this->getAlias())) { - $factory->application->setAttribute($this->getAlias(), $this->createInstanceWithPrototype($factory, $args)); - } - return $factory->application->getAttribute($this->getAlias()); + protected function createInstanceWithPrototype($factory, $args) { + return $this->createInstance($factory, $args); } /** - * @param IWindFactory $factory + * @param WindFactory $factory * @param array $args * @return NULL|object */ - protected function createInstanceWithRequest($factory, $args) { - if (!isset($factory->request)) return null; - if (null === $factory->request->getAttribute($this->getAlias(), null)) { - $factory->request->setAttribute($this->getAlias(), $this->createInstanceWithPrototype($factory, $args)); - } - return $factory->request->getAttribute($this->getAlias()); + protected function createInstanceWithSingleton($factory, $args) { + $_instance = $this->createInstance($factory, $args); + $factory->setSingled($this->getAlias(), $_instance); + return $_instance; } /** - * @param IWindFactory $factory - * @param array $args - * @return NULL|object + * @modified xiaoxia.xu + * @param AbstractWindFactory $factory + * @param array $args */ - protected function createInstanceWithPrototype($factory, $args) { - if ($this->prototype === null) { - $instance = $this->createInstance($factory, $args); - $this->setProperties($this->getPropertys(), $factory, $instance); + protected function createInstance($factory, $args) { + $args = $this->buildConstructArgs($factory, $args); + $instance = $factory->createInstance($this->getClassName(), $args); + if ($instance instanceof WindModule) { + $this->buildConfig($instance, $factory); + $this->buildProperties($instance, $factory); $this->executeInitMethod($instance); - $this->setPrototype($instance); + $this->setHiddenProperty($instance, $factory); + $instance = $this->setProxyForClass($instance, $factory); } - return clone $this->prototype; + return $instance; } /** - * @param IWindFactory $factory - * @param array $args - * @return NULL|object - */ - protected function createInstanceWithSingleton($factory, $args) { - if (!isset($this->instance)) { - $this->instance = $this->createInstanceWithPrototype($factory, $args); + * 为类对象设置配置 + * + * @param WindModule $instance + * @param WindFactory $factory + * @return + */ + protected function buildConfig($instance, $factory) { + if (!$config = $this->getConfig()) return; + if (isset($config[self::RESOURCE])) { + $config = $config[self::RESOURCE]; } - return $this->instance; + $instance->setConfig($config); } /** + * 设置变量隐藏属性 * - * @modified xiaoxia.xu - * @param AbstractWindFactory $factory - * @param array $args - */ - protected function createInstance($factory, $args = array()) { - $instance = null; - if (empty($args)) { - $args = $this->setProperties($this->getConstructArgs(), $factory); - } - $instance = $factory->createInstance($this->getClassName(), $args); - return $instance; + * @param WindModule $instance + * @param WindFactory $factory + * @return + */ + protected function setHiddenProperty($instance, $factory) { + $instance->systemConfig = Wind::getApp()->getWindSystemConfig(); + $instance->request = Wind::getApp()->getRequest(); + $instance->response = Wind::getApp()->getResponse(); + $instance->systemFactory = $factory; } /** - * Enter description here ... - * @param instance - * @param proxy - */ - private function setPrototype($instance) { - if ($this->prototype === null) { - if (($instance instanceof WindModule) && (null !== ($proxy = $instance->getClassProxy()))) - $this->prototype = $proxy; - else - $this->prototype = $instance; - } + * 为类设置代理 + * + * @param WindModule $instance + * @param WindFactory $factory + * @return WindClassProxy + */ + protected function setProxyForClass($instance, $factory) { + if (!($proxy = $this->getProxy()) || $proxy === 'false' || $proxy === false) return $instance; + if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyClass; + $proxy = $factory->createInstance($proxy, array($instance)); + if ($proxy !== null) return $proxy; + Wind::log( + '[core.factory.WindClassDefinition.setProxyForClass] create proxy for ' . $this->getClassName() . ' fail.', + WindLogger::LEVEL_DEBUG, 'wind.core'); + throw new WindException( + '[core.factory.WindClassDefinition.setProxyForClass] create proxy for ' . $this->getClassName() . ' fail.', + WindException::ERROR_SYSTEM_ERROR); } /** @@ -208,60 +230,98 @@ private function setPrototype($instance) { * * @author xiaoxia.xu * @param object $instance + * @return */ private function executeInitMethod($instance) { - if (!($initMethod = $this->getInitMethod())) return; - if (!in_array($initMethod, get_class_methods($instance))) throw new WindException(get_class($instance) . '->' . $initMethod, WindException::ERROR_CLASS_METHOD_NOT_EXIST); - $instance->$initMethod(); + try { + if (!($initMethod = $this->getInitMethod())) return; + return call_user_func_array(array($instance, $initMethod), array()); + } catch (Exception $e) { + throw new WindException( + '[core.factory.WindClassDefinition.executeInitMethod] (' . $this->getClassName() . '->' . $initMethod . + '()) "' . $e->getMessage() . '"', WindException::ERROR_CLASS_METHOD_NOT_EXIST); + } + } + + /** + * 构造构造函数参数对象 + * + * @param WindFactory $factory + * @throws WindException + */ + protected function buildConstructArgs($factory, $args) { + if ($args) return $args; + $subDefinitions = $this->getConstructArgs(); + $_tmp = array(); + foreach ($subDefinitions as $key => $subDefinition) { + if (isset($subDefinition[self::VALUE])) { + $_tmp[$key] = $subDefinition[self::VALUE]; + } elseif (isset($subDefinition[self::REF])) + $_tmp[$key] = $factory->getInstance($subDefinition[self::REF]); + } + return $_tmp; } /** - * 将类实例的依赖注入到类实例中 - * @param array $subDefinitions | 类定义 - * @param AbstractWindFactory $factory | 抽象的类工厂 - * @param object $instance | 类实例 + * 将类实例的依赖注入到类实例中 + * + * @param WindModule $instance | 类实例 + * @param WindFactory $factory | 抽象的类工厂 */ - private function setProperties($subDefinitions, $factory, $instance = null) { - $_temp = array(); + protected function buildProperties($instance, $factory) { + if (!$subDefinitions = $this->getPropertys()) return; foreach ($subDefinitions as $key => $subDefinition) { - if (isset($subDefinition[self::REF])) - $_temp[$key] = $factory->getInstance($subDefinition[self::REF]); - elseif (isset($subDefinition[self::VALUE])) - $_temp[$key] = $subDefinition[self::VALUE]; - if ($instance !== null) { - call_user_func_array(array($instance, 'set' . ucfirst(trim($key, '_'))), array($_temp[$key])); + $_value = ''; + if (isset($subDefinition[self::VALUE])) $_value = $subDefinition[self::VALUE]; + if ($_value) { + $_setter = 'set' . ucfirst(trim($key, '_')); + call_user_func_array(array($instance, $_setter), array($_value)); } } - return $_temp; + $instance->setDelayAttributes($subDefinitions); } /** - * Enter description here ... + * 执行调用工厂方法 * * @param array $args * @throws WindException * @return NULL|mixed */ - private function executeFactoryMethod($args) { - if (!($factoryMethod = $this->getFactoryMethod())) return null; - if (!in_array($factoryMethod, get_class_methods($this->getClassName()))) throw new WindException($this->getClassName() . '->' . $factoryMethod, WindException::ERROR_CLASS_METHOD_NOT_EXIST); - return call_user_func_array(array($this->getClassName(), $factoryMethod), $args); + protected function executeFactoryMethod($args) { + try { + if (!($factoryMethod = $this->getFactoryMethod())) return null; + return call_user_func_array(array($this->getClassName(), $factoryMethod), $args); + } catch (Exception $e) { + throw new WindException( + '[core.factory.WindClassDefinition.executeFactoryMethod] (' . $this->getClassName() . '->' . + $factoryMethod . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); + } } /** * 初始化类定义 + * * @param array $classDefinition */ protected function init($classDefinition) { - if (empty($classDefinition)) return; - if (isset($classDefinition[self::NAME])) $this->setAlias($classDefinition[self::NAME]); - if (isset($classDefinition[self::PATH])) $this->setPath($classDefinition[self::PATH]); - if (isset($classDefinition[self::SCOPE])) $this->setScope($classDefinition[self::SCOPE]); - if (isset($classDefinition[self::FACTORY_METHOD])) $this->setFactoryMethod($classDefinition[self::FACTORY_METHOD]); - if (isset($classDefinition[self::INIT_METHOD])) $this->setInitMethod($classDefinition[self::INIT_METHOD]); - if (isset($classDefinition[self::PROPERTIES])) $this->setPropertys($classDefinition[self::PROPERTIES]); - if (isset($classDefinition[self::CONSTRUCTOR_ARG])) $this->setConstructArgs($classDefinition[self::CONSTRUCTOR_ARG]); - $this->setClassDefinition($classDefinition); + try { + if (empty($classDefinition)) return; + foreach ($classDefinition as $key => $value) { + if (strpos($key, '-') !== false) { + list($_s1, $_s2) = explode('-', $key); + $_s1 = ucfirst($_s1); + $_s2 = ucfirst($_s2); + $_setter = 'set' . $_s1 . $_s2; + } else + $_setter = 'set' . ucfirst($key); + call_user_func_array(array($this, $_setter), array($value)); + } + $this->setClassDefinition($classDefinition); + } catch (Exception $e) { + throw new WindException("[core.factory.WindClassDefinition.init]" . $e->getMessage(), + WindException::ERROR_SYSTEM_ERROR); + } } /** @@ -338,7 +398,7 @@ public function getConstructArgs() { * @return the $propertys */ public function getPropertys() { - return $this->propertys; + return $this->properties; } /** @@ -360,8 +420,9 @@ public function setConstructArgs($constructArgs) { * @param array $propertys the $propertys to set * @author Qiong Wu */ - public function setPropertys($propertys) { - if (is_array($propertys) && !empty($propertys)) $this->propertys += $propertys; + public function setProperties($properties) { + if (!is_array($properties)) return; + $this->properties = array_merge($this->properties, $properties); } /** @@ -411,4 +472,33 @@ public function setFactoryMethod($factoryMethod) { public function setInitMethod($initMethod) { $this->initMethod = $initMethod; } + + /** + * @return the $proxy + */ + public function getProxy() { + return $this->proxy; + } + + /** + * @param boolean $proxy + */ + public function setProxy($proxy) { + $this->proxy = $proxy; + } + + /** + * @return the $config + */ + public function getConfig() { + return $this->config; + } + + /** + * @param string $config + */ + public function setConfig($config) { + $this->config = $config; + } + } \ No newline at end of file diff --git a/wind/core/factory/WindComponentDefinition.php b/wind/core/factory/WindComponentDefinition.php deleted file mode 100644 index 463f532e..00000000 --- a/wind/core/factory/WindComponentDefinition.php +++ /dev/null @@ -1,144 +0,0 @@ - 2010-12-31 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:core.factory.WindClassDefinition'); -Wind::import('WIND:core.config.parser.WindConfigParser'); -Wind::import('WIND:core.config.WindConfig'); -/** - * 组件定义 - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindComponentDefinition extends WindClassDefinition { - /* 配置 */ - const CONFIG = 'config'; - const RESOURCE = 'resource'; - /* 是否支持隐藏变量 */ - const HIDDEN_PRO = 'hidden-pro'; - /* component 定义 */ - const PROXY = 'proxy'; - protected $proxyClass = 'WIND:core.factory.proxy.WindClassProxy'; - /** - * 类代理对象定义 - * - * @var string - */ - protected $proxy = ''; - protected $hiddenPro = ''; - /** - * @var array - */ - protected $config = array(); - - /* (non-PHPdoc) - * @see WindClassDefinition::createInstance() - */ - protected function createInstance($factory, $args = array()) { - $instance = parent::createInstance($factory, $args); - if (!($instance instanceof WindComponentModule)) return $instance; - $windConfig = null; - if (isset($this->config[self::RESOURCE]) && ($resource = $this->config[self::RESOURCE])) { - $configPath = Wind::getRealPath($resource); - $windConfig = new WindConfig($configPath, new WindConfigParser(), $this->getAlias(), WIND_CONFIG_CACHE); - } else { - $windConfig = new WindConfig($this->config); - } - $instance->setConfig($windConfig); - $this->setHiddenProperty($instance, $factory); - $this->setProxyForClass($instance, $factory); - return $instance; - } - - /** - * 设置组件对象的隐藏属性 - */ - protected function setHiddenProperty($instance, $factory) { - if ($this->getHiddenPro() === 'false') return; - if (isset($factory->request)) { - $instance->windSystemConfig = $factory->request->getAttribute(WindFrontController::WIND_CONFIG); - $instance->windFactory = $factory->request->getAttribute(WindFrontController::WIND_FACTORY); - $instance->request = $factory->request; - } - if (isset($factory->response)) $instance->response = $factory->response; - } - - /** - * 为类设置代理 - * - * @param WindModule $instance - * @param WindFactory $factory - */ - protected function setProxyForClass($instance, $factory) { - if (!($proxyPath = $this->getProxy()) || $proxyPath === 'false') return; - $proxyPath = ($proxyPath === 'true' || $proxyPath === true) ? $this->proxyClass : $this->getProxy(); - $proxyClass = Wind::import($proxyPath); - if (!class_exists($proxyClass)) return; - $proxyClass = $factory->createInstance($proxyClass); - if ($proxyClass instanceof WindClassProxy) $instance->setClassProxy($proxyClass); - } - - /* (non-PHPdoc) - * @see WindClassDefinition::init() - */ - protected function init($classDefinition) { - parent::init($classDefinition); - if (isset($classDefinition[self::CONFIG])) { - $this->config = $classDefinition[self::CONFIG]; - } - if (isset($classDefinition[self::PROXY])) { - $this->setProxy($classDefinition[self::PROXY]); - } - if (isset($classDefinition[self::HIDDEN_PRO])) { - $this->setHiddenPro($classDefinition[self::HIDDEN_PRO]); - } - } - - /** - * @return the $proxy - */ - public function getProxy() { - return $this->proxy; - } - - /** - * @param string $proxy - */ - public function setProxy($proxy) { - $this->proxy = $proxy; - } - - /** - * @return the $hiddenPro - */ - public function getHiddenPro() { - return $this->hiddenPro; - } - - /** - * @param field_type $hiddenPro - */ - public function setHiddenPro($hiddenPro) { - $this->hiddenPro = $hiddenPro; - } - - /** - * @return the $config - */ - public function getConfig() { - return $this->config; - } - - /** - * @param array $config - */ - public function setConfig($config) { - $this->config = $config; - } -} \ No newline at end of file diff --git a/wind/core/factory/WindComponentFactory.php b/wind/core/factory/WindComponentFactory.php deleted file mode 100644 index 9f6e722b..00000000 --- a/wind/core/factory/WindComponentFactory.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindComponentFactory extends WindFactory { - - protected $classDefinitionType = 'WIND:core.factory.WindComponentDefinition'; - -} - -?> \ No newline at end of file diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 043b2d3d..41e8360c 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -1,40 +1,40 @@ 2010-11-29 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.factory.IWindFactory'); /** * Wind容器基类,创建类对象(分为两种模式,一种是普通模式,一种为单利模式) - * * 职责: * 类创建 - * 统一类接口访问 + * 统一类接口访问 + * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ class WindFactory implements IWindFactory { - + /** + * 类定义类型,默认为WindClassDefinition + * + * @var string + */ protected $classDefinitionType = 'WIND:core.factory.WindClassDefinition'; - - protected $_classDefinitions = array(); - + /** + * 类定义集合 + * + * @var array + */ protected $classDefinitions = array(); - - protected $classAlias = array(); - - protected $cache = ''; + + /** + * 类实例集合 + * + * @var array + */ + protected $instances = array(); /** * 初始化抽象工厂类 * 可以通过两种方式初始化该工厂 * 1. 直接传递一个解析好的类配置信息 - * * @param string $configFile */ public function __construct($classDefinitions = array()) { @@ -45,39 +45,48 @@ public function __construct($classDefinitions = array()) { * @see AbstractWindFactory::getInstance() */ public function getInstance($alias) { - $classDefinition = $this->getClassDefinitionByAlias($alias); - if (!($classDefinition instanceof WindClassDefinition)) { - return null; - } - /*@var $classDefinition WindClassDefinition */ + if (isset($this->instances[$alias])) return $this->instances[$alias]; + if (!$classDefinition = $this->getClassDefinitionByAlias($alias)) return null; $args = func_get_args(); unset($args[0]); return $classDefinition->getInstance($this, $args); } + /* (non-PHPdoc) + * @see IWindFactory::getPrototype() + */ + public function getPrototype($alias) { + $instance = $this->getInstance($alias); + if ($instance === null) return null; + return clone $instance; + } + /* (non-PHPdoc) * @see AbstractWindFactory::createInstance() */ static public function createInstance($className, $args = array()) { - if (!$className) return null; - if (strpos($className, ':') !== false) $className = Wind::import($className); - if (!$className || !class_exists($className)) { + try { + if (!$className) return null; + if (strpos($className, ':') !== false) $className = Wind::import($className); + $reflection = new ReflectionClass($className); + if ($reflection->isAbstract() || $reflection->isInterface()) return null; + + Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_INFO, + 'core.factory'); + return call_user_func_array(array($reflection, 'newInstance'), (array) $args); + } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } - $reflection = new ReflectionClass($className); - if ($reflection->isAbstract() || $reflection->isInterface()) return null; - return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } /** - * Enter description here ... - * * @param string $classAlias * @return boolean */ - public function isSingled($classAlias) { - $classDefinition = $this->getClassDefinitionByAlias($classAlias); - return isset($classDefinition[self::CLASS_SINGLE]) && $classDefinition[self::CLASS_SINGLE] === 'false'; + public function setSingled($classAlias, $instance) { + Wind::log('[core.factory.WindFactory.createInstance] create singled instance:' . $classAlias, + WindLogger::LEVEL_INFO, 'core.factory'); + $this->instances[$classAlias] = $instance; } /** @@ -86,28 +95,25 @@ public function isSingled($classAlias) { * @param string $classAlias * @return WindClassDefinition */ - public function getClassDefinitionByAlias($classAlias) { - if (!isset($this->classAlias[$classAlias]) && isset($this->_classDefinitions[$classAlias])) { - $definition = $this->_classDefinitions[$classAlias]; - $classDefinition = self::createInstance($this->classDefinitionType, array($definition)); - $classDefinition->setAlias($classAlias); - $this->addClassDefinitions($classDefinition); - return $classDefinition; - } - return $this->classDefinitions[$this->classAlias[$classAlias]]; + protected function getClassDefinitionByAlias($classAlias) { + if (!($definition = $this->classDefinitions[$classAlias])) return null; + if ($definition instanceof WindClassDefinition) return $definition; + $classDefinition = self::createInstance($this->classDefinitionType, array($definition)); + $classDefinition->setAlias($classAlias); + $this->addClassDefinitions($classDefinition); + return $classDefinition; } /** - * Enter description here ... + * 动态添加类定义对象 * * @param WindClassDefinition|array $classDefinition + * @return */ public function addClassDefinitions($classDefinition) { if ($classDefinition instanceof WindClassDefinition) { - $className = $classDefinition->getClassName(); $alias = $classDefinition->getAlias(); - $this->classDefinitions[$className] = $classDefinition; - $this->classAlias[$alias] = $className; + $this->classDefinitions[$alias] = $classDefinition; } elseif (is_array($classDefinition)) { foreach ($classDefinition as $value) $this->addClassDefinitions($value); @@ -115,27 +121,28 @@ public function addClassDefinitions($classDefinition) { } /** - * Enter description here ... + * 类定义检查,检查类型以是否已经存在 * - * @param array $classDefinitions - * @throws WindException + * @param array $definition + * @return boolean */ - protected function loadClassDefinitions($classDefinitions) { - if (!is_array($classDefinitions)) { - throw new WindException($classDefinitions, WindException::ERROR_PARAMETER_TYPE_ERROR); - } - $this->_classDefinitions = $classDefinitions; + public function checkAlias($alias) { + return isset($this->classDefinitions[$alias]); } /** - * 类定义检查 + * 加载类定义信息 * - * @param array $definition - * @return string + * @param array $classDefinitions + * @throws WindException + * @return */ - protected function checkClassDefinition($definition) { - //TODO check class definition - return true; + protected function loadClassDefinitions($classDefinitions) { + if (is_array($classDefinitions)) + $this->classDefinitions = $classDefinitions; + else + throw new WindException('[core.factory.WindFactory.loadClassDefinitions]', + WindException::ERROR_PARAMETER_TYPE_ERROR); } } \ No newline at end of file diff --git a/wind/core/factory/proxy/IWindClassProxy.php b/wind/core/factory/proxy/IWindClassProxy.php index 9e362fa1..1ab6ceef 100644 --- a/wind/core/factory/proxy/IWindClassProxy.php +++ b/wind/core/factory/proxy/IWindClassProxy.php @@ -1,17 +1,12 @@ * @author Qiong Wu * @version $Id$ * @package */ interface IWindClassProxy { - const EVENT_TYPE_METHOD = 'method'; - /** * Enter description here ... * @@ -19,7 +14,6 @@ interface IWindClassProxy { * @deprecated */ const EVENT_TYPE_SETTER = 'setter'; - /** * Enter description here ... * @@ -47,7 +41,5 @@ public function _getInstance(); * @param string $type */ public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD); - } - ?> \ No newline at end of file diff --git a/wind/core/factory/proxy/WindClassProxy.php b/wind/core/factory/proxy/WindClassProxy.php index 3295f4b3..df5dce07 100644 --- a/wind/core/factory/proxy/WindClassProxy.php +++ b/wind/core/factory/proxy/WindClassProxy.php @@ -1,33 +1,23 @@ * @author Qiong Wu * @version $Id$ * @package */ class WindClassProxy implements IWindClassProxy { - + private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; protected $_attributes = array(); - protected $_className = ''; - protected $_classPath = ''; - protected $_reflection = null; - protected $_instance = null; - protected $_listener = array(); - private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; - /** - * Enter description here ... - * * @param string|object $targetObj */ public function __construct($targetObj = null, $args = array()) { @@ -38,29 +28,16 @@ public function __construct($targetObj = null, $args = array()) { * @see IWindClassProxy::registerAspect() */ public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { - //TODO add Logger if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { - throw new WindException('incorrect registerType ' . $type); + throw new WindException( + '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, + WindException::ERROR_PARAMETER_TYPE_ERROR); } - if (!isset($this->_listener[$type])) $this->_listener[$type] = array(); - if (!isset($this->_listener[$type][$event])) $this->_listener[$type][$event] = array(); + !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } /** - * Enter description here ... - * - * @param string $propertyName - * @param $value - */ - public function _setProperty($propertyName, $value) { - $this->_getInstance()->$propertyName = $value; - return true; - } - - /** - * Enter description here ... - * * @param string $propertyName * @param $value * @throws WindException @@ -71,10 +48,8 @@ public function __set($propertyName, $value) { if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } - $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); - $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); @@ -82,17 +57,6 @@ public function __set($propertyName, $value) { } /** - * Enter description here ... - * - * @param string $propertyName - */ - public function _getProperty($propertyName) { - return $this->_getInstance()->$propertyName; - } - - /** - * Enter description here ... - * * @param unknown_type $propertyName * @deprecated */ @@ -101,10 +65,8 @@ public function __get($propertyName) { if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } - $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); - $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); @@ -112,8 +74,6 @@ public function __get($propertyName) { } /** - * Enter description here ... - * * @param string $methodName * @param array $args * @throws WindException @@ -121,7 +81,6 @@ public function __get($propertyName) { public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); - $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); @@ -135,28 +94,38 @@ public function __call($methodName, $args) { * @param array $args * @throws WindException */ - public function initClassProxy($targetObject, $args = array()) { - if ($targetObject === null) return null; - if (is_object($targetObject)) { - $this->_setClassName(get_class($targetObject)); - $this->_instance = $targetObject; - } elseif (is_string($targetObject) && !empty($targetObject)) { - if (!class_exists($targetObject)) throw new WindException($targetObject, WindException::ERROR_CLASS_NOT_EXIST); - $this->_setClassName($targetObject); - } - if ($this->_reflection === null) { + protected function initClassProxy($targetObject, $args = array()) { + try { + if (is_object($targetObject)) { + $this->_setClassName(get_class($targetObject)); + $this->_instance = $targetObject; + } elseif (is_string($targetObject) && !empty($targetObject)) { + $_className = Wind::import($targetObject); + $this->_setClassName($_className); + } else + throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); + + $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); + foreach ($types as $type) { + $this->_listener[$type] = array(); + } $reflection = new ReflectionClass($this->_className); - if ($reflection->isAbstract() || $reflection->isInterface()) return; + if ($reflection->isAbstract() || $reflection->isInterface()) { + throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); + } $this->_reflection = $reflection; - } - if ($this->_instance === null) { + if ($this->_instance !== null) return; $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); + } catch (Exception $e) { + Wind::log( + '[core.factory.proxy.WindClassProxy.initClassProxy] Initialization proxy failed.' . $e->getMessage(), + WindLogger::LEVEL_DEBUG, 'wind.core'); } - return $this; } /** - * Enter description here ... + * @param string $event + * @return */ private function _getInterceptorChain($event = '') { $interceptorChain = WindFactory::createInstance($this->_interceptorChain); @@ -170,7 +139,10 @@ private function _getInterceptorChain($event = '') { } /** - * Enter description here ... + * 根据监听器类型,返回对象的监听器对象 + * + * @param string $type + * @param string $subType */ private function _getListenerByType($type, $subType) { $listener = array(); @@ -194,18 +166,19 @@ public function _getReflection() { if ($this->_reflection instanceof ReflectionClass) return $this->_reflection; else - throw new WindException(get_class($this) . '->_reflection, ' . gettype($this->_reflection), WindException::ERROR_CLASS_TYPE_ERROR); + throw new WindException(get_class($this) . '->_reflection, ' . gettype($this->_reflection), + WindException::ERROR_CLASS_TYPE_ERROR); } /** - * @return the $_className + * @return string */ public function _getClassName() { return $this->_className; } /** - * @return the $_classPath + * @return string */ public function _getClassPath() { return $this->_classPath; @@ -213,6 +186,7 @@ public function _getClassPath() { /** * @param string $className + * @return */ public function _setClassName($className) { $this->_className = $className; @@ -220,6 +194,7 @@ public function _setClassName($className) { /** * @param string $classPath + * @return */ public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); @@ -227,10 +202,26 @@ public function _setClassPath($classPath) { } /** - * Enter description here ... + * @param string $propertyName + * @param $value + */ + public function _setProperty($propertyName, $value) { + $this->_getInstance()->$propertyName = $value; + return true; + } + + /** + * @param string $propertyName + */ + public function _getProperty($propertyName) { + return $this->_getInstance()->$propertyName; + } + + /** + * 根据别名返回属性定义,别名为空时返回整个属性定义列表 * - * @param unknown_type $alias - * @return multitype:|Ambigous + * @param string $alias + * @return object | array */ public function _getAttribute($alias = '') { if ($alias === '') @@ -240,10 +231,10 @@ public function _getAttribute($alias = '') { } /** - * Enter description here ... + * 设置属性对象,设置的属性可以在listener中被访问到 * - * @param unknown_type $alias - * @param unknown_type $object + * @param string|array $alias + * @param object $object */ public function _setAttribute($alias, $object = null) { if (is_array($alias)) @@ -251,7 +242,5 @@ public function _setAttribute($alias, $object = null) { elseif (is_string($alias)) $this->_attributes[$alias] = $object; } - } - ?> \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptor.php b/wind/core/filter/WindHandlerInterceptor.php index 8eb3c200..c6ca0890 100644 --- a/wind/core/filter/WindHandlerInterceptor.php +++ b/wind/core/filter/WindHandlerInterceptor.php @@ -1,30 +1,23 @@ * @author Qiong Wu * @version $Id$ * @package */ -class WindHandlerInterceptor { - +class WindHandlerInterceptor extends WindModule { protected $result = null; + protected $interceptorChain = null; /** * Enter description here ... */ - public function preHandle() { - - } + public function preHandle() {} /** * Enter description here ... */ - public function postHandle() { - - } + public function postHandle() {} /** * Enter description here ... @@ -46,18 +39,12 @@ public function handle() { } /** + * 设置过滤链对象 + * * @param WindHandlerInterceptorChain $interceptorChain */ public function setHandlerInterceptorChain($interceptorChain) { - if ($interceptorChain instanceof WindComponentModule) { - $attributes = $interceptorChain->getAttribute(); - foreach ($attributes as $key => $value) { - $this->$key = $value; - } - } $this->interceptorChain = $interceptorChain; } - } - ?> \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptorChain.php b/wind/core/filter/WindHandlerInterceptorChain.php index f16e85dc..55ec188d 100644 --- a/wind/core/filter/WindHandlerInterceptorChain.php +++ b/wind/core/filter/WindHandlerInterceptorChain.php @@ -1,26 +1,22 @@ * @author Qiong Wu * @version $Id$ * @package */ -class WindHandlerInterceptorChain extends WindComponentModule { - +class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); - protected $_callBack = null; - protected $_args = array(); - private $_state = true; /** - * Enter description here ... + * 设置回调方法 + * + * @param string|array $callBack + * @param array $args + * @return */ public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; @@ -28,20 +24,22 @@ public function setCallBack($callBack, $args = array()) { } /** - * Enter description here ... + * 执行callback方法 * * @throws WindException * @return void|mixed */ public function execute() { if ($this->_callBack === null) return null; - if (is_string($this->_callBack) && !function_exists($this->_callBack)) throw new WindException($this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); - + if (is_string($this->_callBack) && !function_exists($this->_callBack)) { + throw new WindException('[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, + WindException::ERROR_FUNCTION_NOT_EXIST); + } return call_user_func_array($this->_callBack, (array) $this->_args); } /** - * Enter description here ... + * 返回处理句柄 * * @return WindHandlerInterceptor */ @@ -51,19 +49,22 @@ public function getHandler() { $this->_state = false; } if (count($this->_interceptors) <= 0) return null; - $handler = array_shift($this->_interceptors); if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } + Wind::log( + '[core.filter.WindHandlerInterceptorChain.getHandler] the type of Interceptor ' . gettype($handler) . + ' is not supported.', WindLogger::LEVEL_DEBUG, 'wind.core'); return $this->getHandler(); } /** - * Enter description here ... + * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 * * @param $interceptors + * @return */ public function addInterceptors($interceptors) { if (is_array($interceptors)) @@ -71,7 +72,5 @@ public function addInterceptors($interceptors) { else $this->_interceptors[] = $interceptors; } - } - ?> \ No newline at end of file diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php index 8bc91af0..3c690685 100644 --- a/wind/core/request/WindHttpRequest.php +++ b/wind/core/request/WindHttpRequest.php @@ -1,11 +1,4 @@ 2010-11-7 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:core.request.IWindRequest'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu @@ -74,41 +67,55 @@ public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes($data); } - public function setAttribute($name, $value) { - $this->_attribute[$name] = $value; - } - - /** - * 根据名称获得服务器和执行环境信息 - * @param string|null $name - */ - public function getAttribute($name, $value = '') { - if (isset($this->_attribute[$name])) - return $this->_attribute[$name]; - else if (isset($_GET[$name])) - return $_GET[$name]; - else if (isset($_POST[$name])) - return $_POST[$name]; - else if (isset($_COOKIE[$name])) - return $_COOKIE[$name]; - else if (isset($_REQUEST[$name])) - return $_REQUEST[$name]; - else if (isset($_ENV[$name])) - return $_ENV[$name]; - else if (isset($_SERVER[$name])) - return $_SERVER[$name]; + /** + * 设置属性数据 + * + * @param string|array|object $data + * @param string $key + * @return + */ + public function setAttribute($data, $key = '') { + if ($key) { + $this->_attribute[$key] = $data; + return; + } + if (is_object($data)) $data = get_object_vars($data); + if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); + } + + /** + * 根据名称获得服务器和执行环境信息 + * + * @param string|null $name + * @return string|object|array| + */ + public function getAttribute($key, $defaultValue = '') { + if (isset($this->_attribute[$key])) + return $this->_attribute[$key]; + else if (isset($_GET[$key])) + return $_GET[$key]; + else if (isset($_POST[$key])) + return $_POST[$key]; + else if (isset($_COOKIE[$key])) + return $_COOKIE[$key]; + else if (isset($_REQUEST[$key])) + return $_REQUEST[$key]; + else if (isset($_ENV[$key])) + return $_ENV[$key]; + else if (isset($_SERVER[$key])) + return $_SERVER[$key]; else - return $value; + return $defaultValue; } /** * 返回$_GET,$_POST的值,未设置则返回default * @param string $name | attribute name */ - public function getRequest($name = null, $defaultValue = null) { - if (!$name) return array_merge($_POST, $_GET); - if (isset($_GET[$name])) return $_GET[$name]; - if (isset($_POST[$name])) return $_POST[$name]; + public function getRequest($key = null, $defaultValue = null) { + if (!$key) return array_merge($_POST, $_GET); + if (isset($_GET[$key])) return $_GET[$key]; + if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } @@ -522,8 +529,10 @@ private function _getClientIp() { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); - if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { - $this->_clientIp = long2ip($ip); + if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || + (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || + (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { + $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); @@ -551,7 +560,8 @@ private function initRequestUri() { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; - if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); + if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace( + '/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; @@ -570,64 +580,68 @@ private function initRequestUri() { * @return */ private function _initScriptUrl() { - if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); + if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException( + __CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; - } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { - $this->_scriptUrl = $_scriptName; - } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { - $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; - } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { - $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); - } else - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); - } + } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && + basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { + $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; + } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && + ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && + strpos($_scriptName, $_documentRoot) === 0) { + $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } - /** - * 获得主机信息,包含协议信息,主机名,访问端口信息 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_hostInfo = http://www.phpwind.net/ - * $this->_hostInfo = http://www.phpwind.net:80/ - * $this->_hostInfo = https://www.phpwind.net:443/ - * - * @throws WindException - * @return - */ - private function _initHostInfo() { - $http = $this->isSecure() ? 'https' : 'http'; - if (($httpHost = $this->getServer('HTTP_HOST')) != null) - $this->_hostInfo = $http . '://' . $httpHost; - elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { - $this->_hostInfo = $http . '://' . $httpHost; - if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; - } else - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); - } + /** + * 获得主机信息,包含协议信息,主机名,访问端口信息 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_hostInfo = http://www.phpwind.net/ + * $this->_hostInfo = http://www.phpwind.net:80/ + * $this->_hostInfo = https://www.phpwind.net:443/ + * + * @throws WindException + * @return + */ + private function _initHostInfo() { + $http = $this->isSecure() ? 'https' : 'http'; + if (($httpHost = $this->getServer('HTTP_HOST')) != null) + $this->_hostInfo = $http . '://' . $httpHost; + elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { + $this->_hostInfo = $http . '://' . $httpHost; + if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } - /** - * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 - * - * @throws WindException - * @return - */ - private function _initPathInfo() { - $requestUri = urldecode($this->getRequestUri()); - $scriptUrl = $this->getScriptUrl(); - $baseUrl = $this->getBaseUrl(); - if (strpos($requestUri, $scriptUrl) === 0) - $pathInfo = substr($requestUri, strlen($scriptUrl)); - elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) - $pathInfo = substr($requestUri, strlen($baseUrl)); - elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) - $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); - else - throw new WindException(''); - if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); - $this->_pathInfo = trim($pathInfo, '/'); - } -} \ No newline at end of file + /** + * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 + * + * @throws WindException + * @return + */ + private function _initPathInfo() { + $requestUri = urldecode($this->getRequestUri()); + $scriptUrl = $this->getScriptUrl(); + $baseUrl = $this->getBaseUrl(); + if (strpos($requestUri, $scriptUrl) === 0) + $pathInfo = substr($requestUri, strlen($scriptUrl)); + elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) + $pathInfo = substr($requestUri, strlen($baseUrl)); + elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) + $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); + else + throw new WindException(''); + if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); + $this->_pathInfo = trim($pathInfo, '/'); + } + } \ No newline at end of file diff --git a/wind/core/response/WindHttpResponse.php b/wind/core/response/WindHttpResponse.php index e45105bb..6c587509 100644 --- a/wind/core/response/WindHttpResponse.php +++ b/wind/core/response/WindHttpResponse.php @@ -20,86 +20,88 @@ * @package */ class WindHttpResponse implements IWindResponse { - + private $_body = array(); - + + private $_bodyIndex = array(); + private $_headers = array(); - + private $_isRedirect = false; - + private $_status = ''; - + private $_isAjax = false; - + private $_data = array(); - + /* * Server status codes; see RFC 2068. * Status code (100) indicating the client can continue. */ const SC_CONTINUE = 100; - + /** * Status code (101) indicating the server is switching protocols * according to Upgrade header. */ const SC_SWITCHING_PROTOCOLS = 101; - + /** * Status code (200) indicating the request succeeded normally. */ const SC_OK = 200; - + /** * Status code (201) indicating the request succeeded and created * a new resource on the server. */ const SC_CREATED = 201; - + /** * Status code (202) indicating that a request was accepted for * processing, but was not completed. */ const SC_ACCEPTED = 202; - + /** * Status code (203) indicating that the meta information presented * by the client did not originate from the server. */ const SC_NON_AUTHORITATIVE_INFORMATION = 203; - + /** * Status code (204) indicating that the request succeeded but that * there was no new information to return. */ const SC_NO_CONTENT = 204; - + /** * Status code (205) indicating that the agent SHOULD reset * the document view which caused the request to be sent. */ const SC_RESET_CONTENT = 205; - + /** * Status code (206) indicating that the server has fulfilled * the partial GET request for the resource. */ const SC_PARTIAL_CONTENT = 206; - + /** * Status code (300) indicating that the requested resource * corresponds to any one of a set of representations, each with * its own specific location. */ const SC_MULTIPLE_CHOICES = 300; - + /** * Status code (301) indicating that the resource has permanently * moved to a new location, and that future references should use a * new URI with their requests. */ const SC_MOVED_PERMANENTLY = 301; - + /** * Status code (302) indicating that the resource has temporarily * moved to another location, but that future references should @@ -109,7 +111,7 @@ class WindHttpResponse implements IWindResponse { * SC_FOUND is now the preferred definition. */ const SC_MOVED_TEMPORARILY = 302; - + /** * Status code (302) indicating that the resource reside * temporarily under a different URI. Since the redirection might @@ -118,26 +120,26 @@ class WindHttpResponse implements IWindResponse { * status code (302), it is recommended to use this variable. */ const SC_FOUND = 302; - + /** * Status code (303) indicating that the response to the request * can be found under a different URI. */ const SC_SEE_OTHER = 303; - + /** * Status code (304) indicating that a conditional GET operation * found that the resource was available and not modified. */ const SC_NOT_MODIFIED = 304; - + /** * Status code (305) indicating that the requested resource * MUST be accessed through the proxy given by the * Location field. */ const SC_USE_PROXY = 305; - + /** * Status code (307) indicating that the requested resource * resides temporarily under a different URI. The temporary URI @@ -145,43 +147,43 @@ class WindHttpResponse implements IWindResponse { * field in the response. */ const SC_TEMPORARY_REDIRECT = 307; - + /** * Status code (400) indicating the request sent by the client was * syntactically incorrect. */ const SC_BAD_REQUEST = 400; - + /** * Status code (401) indicating that the request requires HTTP * authentication. */ const SC_UNAUTHORIZED = 401; - + /** * Status code (402) reserved for future use. */ const SC_PAYMENT_REQUIRED = 402; - + /** * Status code (403) indicating the server understood the request * but refused to fulfill it. */ const SC_FORBIDDEN = 403; - + /** * Status code (404) indicating that the requested resource is not * available. */ const SC_NOT_FOUND = 404; - + /** * Status code (405) indicating that the method specified in the * Request-Line is not allowed for the resource * identified by the Request-URI. */ const SC_METHOD_NOT_ALLOWED = 405; - + /** * Status code (406) indicating that the resource identified by the * request is only capable of generating response entities which have @@ -189,111 +191,111 @@ class WindHttpResponse implements IWindResponse { * headers sent in the request. */ const SC_NOT_ACCEPTABLE = 406; - + /** * Status code (407) indicating that the client MUST first * authenticate itself with the proxy. */ const SC_PROXY_AUTHENTICATION_REQUIRED = 407; - + /** * Status code (408) indicating that the client did not produce a * request within the time that the server was prepared to wait. */ const SC_REQUEST_TIMEOUT = 408; - + /** * Status code (409) indicating that the request could not be * completed due to a conflict with the current state of the * resource. */ const SC_CONFLICT = 409; - + /** * Status code (410) indicating that the resource is no longer * available at the server and no forwarding address is known. * This condition SHOULD be considered permanent. */ const SC_GONE = 410; - + /** * Status code (411) indicating that the request cannot be handled * without a defined Content-Length. */ const SC_LENGTH_REQUIRED = 411; - + /** * Status code (412) indicating that the precondition given in one * or more of the request-header fields evaluated to false when it * was tested on the server. */ const SC_PRECONDITION_FAILED = 412; - + /** * Status code (413) indicating that the server is refusing to process * the request because the request entity is larger than the server is * willing or able to process. */ const SC_REQUEST_ENTITY_TOO_LARGE = 413; - + /** * Status code (414) indicating that the server is refusing to service * the request because the Request-URI is longer * than the server is willing to interpret. */ const SC_REQUEST_URI_TOO_LONG = 414; - + /** * Status code (415) indicating that the server is refusing to service * the request because the entity of the request is in a format not * supported by the requested resource for the requested method. */ const SC_UNSUPPORTED_MEDIA_TYPE = 415; - + /** * Status code (416) indicating that the server cannot serve the * requested byte range. */ const SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; - + /** * Status code (417) indicating that the server could not meet the * expectation given in the Expect request header. */ const SC_EXPECTATION_FAILED = 417; - + /** * Status code (500) indicating an error inside the HTTP server * which prevented it from fulfilling the request. */ const SC_INTERNAL_SERVER_ERROR = 500; - + /** * Status code (501) indicating the HTTP server does not support * the functionality needed to fulfill the request. */ const SC_NOT_IMPLEMENTED = 501; - + /** * Status code (502) indicating that the HTTP server received an * invalid response from a server it consulted when acting as a * proxy or gateway. */ const SC_BAD_GATEWAY = 502; - + /** * Status code (503) indicating that the HTTP server is * temporarily overloaded, and unable to handle the request. */ const SC_SERVICE_UNAVAILABLE = 503; - + /** * Status code (504) indicating that the server did not receive * a timely response from the upstream server while acting as * a gateway or proxy. */ const SC_GATEWAY_TIMEOUT = 504; - + /** * Status code (505) indicating that the server does not support * or refuses to support the HTTP protocol version that was used @@ -347,9 +349,10 @@ public function setStatus($status, $message = '') { * @param string $name */ public function setBody($content, $name = null) { - if (!is_string($content) || trim($content) == '') return; - if ($name == null || !is_string($name)) $name = 'default'; - $this->_body[$name] = (string) $content; + if (!$content) return; + !$name && $name = 'default'; + array_unshift($this->_bodyIndex, $name); + $this->_body[$name] = $content; } /** @@ -412,8 +415,8 @@ public function sendHeaders() { */ public function sendBody() { /*if ($this->_isAjax) echo "_body as $content) - echo $content; + foreach ($this->_bodyIndex as $key) + echo $this->_body[$key]; /*if ($this->_isAjax) echo "]]>";*/ } @@ -441,7 +444,8 @@ public function getBody($name = false) { */ public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); - if ($throw && $sended) throw new WindException(__CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); + if ($throw && $sended) throw new WindException( + __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } @@ -498,9 +502,9 @@ public function setIsAjax($_isAjax) { } /** - * @return the $_data + * @return array */ - public function getData($key1, $key2 = '') { + public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; @@ -509,8 +513,7 @@ public function getData($key1, $key2 = '') { /** * @param $data */ - public function setData($data, $key) { - if ($key === '') return; + public function setData($data, $key = '') { if ($key) { $this->_data[$key] = $data; return; diff --git a/wind/core/router/AbstractWindRouter.php b/wind/core/router/AbstractWindRouter.php index ec824980..d393c896 100644 --- a/wind/core/router/AbstractWindRouter.php +++ b/wind/core/router/AbstractWindRouter.php @@ -1,12 +1,4 @@ 2010-11-3 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.WindComponentModule'); /** * 路由解析器接口 * 职责: 路由解析, 返回路由对象 @@ -17,118 +9,165 @@ * @version $Id$ * @package */ -abstract class AbstractWindRouter extends WindComponentModule { - - protected $action = 'run'; - - protected $controller = 'index'; - - protected $module = 'default'; - - protected $modulePath = ''; - - protected $appName = ''; - - protected $reParse = true; - - protected $defaultControllerSuffix = 'Controller'; - - protected $defaultControllerPath = 'controller'; - +abstract class AbstractWindRouter extends WindModule { + const DEFAULT_ERROR_HANDLER = 'WIND:core.web.WindErrorHandler'; + const CONTROLLER_DEFAULT_PATH = 'controller'; + const CONTROLLER_DEFAULT_SUFFIX = 'Controller'; /** - * Enter description here ... + * 默认的处理方法‘run’ + * + * @var string */ - abstract public function parse(); + private $action = 'run'; + /** + * 默认的控制器‘index’ + * + * @var string + */ + private $controller = 'index'; + /** + * 默认的系统应用模块名为‘default’ + * + * @var string + */ + private $module = 'default'; + /** + * 系统应用模块寻址路径 + * + * @var string + */ + protected $modulePath = ''; + + private $reParse = true; /** - * Enter description here ... + * 该方法定义了路由解析策略 + * @return string | actionHandler */ - abstract public function getHandler(); + abstract public function parse(); /** - * Enter description here ... + * 构建Url并返回 + * @return string */ abstract public function buildUrl(); /** - * Enter description here ... + * 通过调用该方法返回,解析请求参数,并返回路由结果 + * + * @return */ public function doParse() { + $_moduleName = $this->getModule(); + if (!strcasecmp($this->getController(), WIND_M_ERROR)) { + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log( + '[core.roter.AbstractWindRouter.doParse] action hander: default error action :' . + self::DEFAULT_ERROR_HANDLER, WindLogger::LEVEL_DEBUG, 'wind.core'); + } + return $this->getSystemConfig()->getModuleErrorHandlerByModuleName($_moduleName, + self::DEFAULT_ERROR_HANDLER); + } if ($this->reParse) { $this->parse(); $this->reParse = false; + Wind::log('[core.router.AbstractWindRouter.doParse] parse the request.', WindLogger::LEVEL_DEBUG, + 'wind.core'); + } + $_suffix = $this->getSystemConfig()->getModuleControllerSuffixByModuleName($_moduleName, + self::CONTROLLER_DEFAULT_SUFFIX); + if ($this->modulePath) + $_path = $this->modulePath; + else { + $_path = $this->getSystemConfig()->getModuleControllerPathByModuleName($_moduleName, + self::CONTROLLER_DEFAULT_PATH); + } + $_path .= '.' . ucfirst($this->controller) . $_suffix; + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log('[core.router.AbstractWindRouter.doParse] action handler: ' . $_path, WindLogger::LEVEL_DEBUG, + 'wind.core'); } $this->destroy(); + return $_path; } /** - * 重新进行解析 + * @return */ - public function reParse() { - $this->reParse = true; + protected function destroy() { + $this->modulePath = ''; + } + + /** + * 设置module信息, 支持格式: + * 'moduleName'; + * 'namespace:modulePath' + * + * @param string $module + * @return + */ + public function setModule($module) { + if (false !== ($pos = strpos($module, ':'))) { + $this->modulePath = $module; + } else { + $this->module = $module; + $this->modulePath = ''; + } } /** - * 获得业务操作 + * 获得业务操作 + * + * @return string */ public function getAction() { return $this->action; } /** - * 获得业务对象 + * 获得业务对象 + * + * @return string */ public function getController() { return $this->controller; } /** - * 返回一组应用入口 + * 返回一组应用入口 + * + * @return string */ public function getModule() { return $this->module; } /** + * 设置action信息 + * * @param string $action + * @return */ public function setAction($action) { $this->action = $action; } /** + * 设置controller信息 + * * @param string $controller + * @return */ public function setController($controller) { $this->controller = $controller; } /** - * @param string $module - */ - public function setModule($module) { - if (false !== $pos = strpos($module, ':')) { - $this->appName = substr($module, 0, $pos); - $this->modulePath = substr($module, $pos + 1); - if (false === strpos($this->modulePath, '.')) { - $this->module = $this->modulePath; - $this->modulePath = ''; - } - } elseif (false !== strpos($module, '.')) { - $this->modulePath = $module; - } else { - $this->module = $module; - $this->modulePath = ''; - $this->appName = ''; - } - } - - /** - * 销毁缓存 + * @param boolean $reParse + * @return */ - protected function destroy() { - $this->modulePath = ''; - $this->appName = ''; + public function reParse() { + $this->reParse = true; } } \ No newline at end of file diff --git a/wind/core/router/WindUrlBasedRouter.php b/wind/core/router/WindUrlBasedRouter.php index 44cd4c12..2256706d 100644 --- a/wind/core/router/WindUrlBasedRouter.php +++ b/wind/core/router/WindUrlBasedRouter.php @@ -1,12 +1,4 @@ 2010-11-3 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.router.AbstractWindRouter'); /** * 基于URL的路由解析器. * 该解析器通过访问一个Http请求的Request对象来获得URL的参数信息 @@ -20,53 +12,24 @@ * @package */ class WindUrlBasedRouter extends AbstractWindRouter { - /* url 路由参数规则 */ const URL_PARAM = 'url-param'; - const DEFAULT_VALUE = 'default-value'; - - /* url 后缀名参数规则 */ + /* 后缀名参数规则 */ const CONTROLLER_SUFFIX = 'controller-suffix'; - const ACTION_SUFFIX = 'action-suffix'; - + /* 路由信息 */ const URL_RULE_MODULE = 'module'; - const URL_RULE_CONTROLLER = 'controller'; - const URL_RULE_ACTION = 'action'; /* (non-PHPdoc) * @see AbstractWindRouter::parse() */ public function parse() { - $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->request, $this->module)); - $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->request, $this->controller)); - $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->request, $this->action)); - } - - /* (non-PHPdoc) - * @see AbstractWindRouter::getHandler() - */ - public function getHandler() { - $moduleConfig = $this->windSystemConfig->getModules($this->getModule()); - $_controllerPath = $this->windSystemConfig->getConfig(WIND_CONFIG_CLASSPATH, '', $moduleConfig, $this->defaultControllerPath); - $_suffix = $this->windSystemConfig->getConfig(self::CONTROLLER_SUFFIX, WIND_CONFIG_VALUE, $moduleConfig, $this->defaultControllerSuffix); - $_path = $this->modulePath ? $this->modulePath : $_controllerPath; - $_path .= '.' . ucfirst($this->controller) . $_suffix; - if (strpos($_path, ':') === false) $_path = strtoupper($this->windSystemConfig->getAppName()) . ':' . $_path; - - //add log - if (IS_DEBUG) { - /* @var $logger WindLogger */ - //TODO 调试信息的输出 - Wind::log('do getHandler of ' . __CLASS__, WindLogger::LEVEL_DEBUG, 'wind.debug'); - // $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); - // $logger->debug('do getHandler of ' . __CLASS__); - } - - return $_path; + $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->getModule())); + $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->getController())); + $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->getAction())); } /* (non-PHPdoc) @@ -83,20 +46,17 @@ public function buildUrl() { } /** - * Enter description here ... + * 返回路由的配置信息 + * * @param urlParam - * @param request * @param defaultValue * @return string */ - private function getUrlParamValue($type, $request = null, $defaultValue = '') { + private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, self::URL_PARAM)) { - if (is_null($request)) return $_param; - $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE); - $defaultValue = $_defaultValue ? $_defaultValue : $defaultValue; - return $request->getAttribute($_param, $defaultValue); + $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE, $defaultValue); + return $this->getRequest()->getRequest($_param, $defaultValue); } return $defaultValue; } - } \ No newline at end of file diff --git a/wind/core/viewer/WindView.php b/wind/core/viewer/WindView.php deleted file mode 100644 index e5994267..00000000 --- a/wind/core/viewer/WindView.php +++ /dev/null @@ -1,226 +0,0 @@ - 2010-11-9 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.WindComponentModule'); -/** - * 处理视图请求的准备工作,并将视图请求提交给某一个具体的视图解析器 - * 如果视图请求是一个重定向请求,或者是请求另一个操作 - * 则返回一个forward对象 - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindView extends WindComponentModule { - - const TEMPLATE_DIR = 'template-dir'; - - const TEMPLATE_EXT = 'template-ext'; - - const IS_CACHE = 'is-cache'; - - const CACHE_DIR = 'cache-dir'; - - const COMPILE_DIR = 'compile-dir'; - - const SHARE_VAR = 'share-var'; - - protected $templatePath = ''; - - protected $templateExt = ''; - - protected $templateName = ''; - - protected $isCache = ''; - - protected $compileDir = ''; - - protected $cacheDir = ''; - - protected $shareVar = ''; - - /** - * 视图解析引擎 - * - * @var WindViewerResolver - */ - protected $viewResolver = null; - - /** - * 布局文件 - * - * @var string - */ - protected $layout = ''; - - /** - * 设置布局对象 - * @param WindLayout|string $layout - */ - public function setLayout($layout) { - if ($layout instanceof WindLayout) - $this->layout = $layout->getLayoutFile(); - else - $this->layout = $layout; - - } - - /** - * 模板路径解析 - * 根据模板的逻辑名称,返回模板的绝对路径信息 - * - * @param string $templateName - * @param string $templateExt - * @return string | false - */ - public function getViewTemplate($template = '', $ext = '') { - $path = $this->getTemplatePath(); - return $this->parseFilePath($template, $ext, $path); - } - - /** - * 模板编译路径解析 - * 根据模板的逻辑名称,返回模板的绝对路径信息 - * - * @param string $templateName - * @param string $templateExt - * @return string | false - */ - public function getCompileFile($template = '', $ext = '') { - $path = $this->getCompileDir(); - return $this->parseFilePath($template, $ext, $path); - } - - /** - * 模板缓存路径路径解析 - * 根据模板的逻辑名称,返回模板的绝对路径信息 - * - * @param string $templateName - * @param string $templateExt - * @return string | false - */ - public function getCacheFile($template = '', $ext = '') { - $path = $this->getCacheDir(); - return $this->parseFilePath($template, $ext, $path); - } - - /** - * @return WindViewerResolver - */ - public function getViewResolver() { - if ($this->viewResolver !== null) { - if ($this->getIsCache() === 'true') { - Wind::import('WIND:core.viewer.listener.WindViewCacheListener'); - $this->viewResolver->setClassProxy(new WindClassProxy()); - $this->viewResolver = $this->viewResolver->getClassProxy(); - $this->viewResolver->registerEventListener('windFetch', new WindViewCacheListener($this)); - } - $this->viewResolver->setWindView($this); - return $this->viewResolver; - } else { - throw new WindException('getViewResolver()', WindException::ERROR_RETURN_TYPE_ERROR); - } - } - - /** - * @param $fileName - * @param $fileExt - * @param $path - */ - private function parseFilePath($fileName, $fileExt, $path) { - if (!$fileName) $fileName = $this->getTemplateName(); - if (!$fileExt) $fileExt = $this->getTemplateExt(); - if (!$fileName) return ''; - if (strrpos($path, ':') === false) $path = $this->windSystemConfig->getAppName() . ':' . $path; - if (!($dir = Wind::getRealPath($path, true)) || !is_dir($dir)) { - throw new WindException('The file folder \'' . $dir . '\' is not exist.'); - } - return Wind::getRealPath($path . '.' . $fileName . '.' . $fileExt); - } - - /** - * @return string $templatePath - */ - public function getTemplatePath() { - //TODO change templatePath to templateDir - if ($this->templatePath === '') { - $this->templatePath = $this->getDefaultValue(self::TEMPLATE_DIR); - } - return $this->templatePath; - } - - /** - * @return string $templateExt - */ - public function getTemplateExt() { - if ($this->templateExt === '') { - $this->templateExt = $this->getDefaultValue(self::TEMPLATE_EXT); - } - return $this->templateExt; - } - - /** - * @return boolean $isCache - */ - public function getIsCache() { - if ($this->isCache === '') { - $this->isCache = $this->getDefaultValue(self::IS_CACHE); - } - return $this->isCache; - } - - /** - * @return string $compileDir - */ - public function getCompileDir() { - if ($this->compileDir === '') { - $this->compileDir = $this->getDefaultValue(self::COMPILE_DIR); - } - return $this->compileDir; - } - - /** - * @return string $cacheDir - */ - public function getCacheDir() { - if ($this->cacheDir === '') $this->cacheDir = $this->getDefaultValue(self::CACHE_DIR); - return $this->cacheDir; - } - - /** - * @return boolean $shareVar - */ - public function getShareVar() { - if ($this->shareVar === '') $this->shareVar = $this->getDefaultValue(self::SHARE_VAR); - return $this->shareVar; - } - - /** - * @param string $type - */ - private function getDefaultValue($type) { - return $this->getConfig($type, WindSystemConfig::VALUE); - } - - /* (non-PHPdoc) - * @see WindModule::getWriteTableForGetterAndSetter() - */ - protected function getWriteTableForGetterAndSetter() { - return array('templatePath', 'templateExt', 'templateName', 'isCache', 'compileDir', 'cacheDir', 'viewResolver', - 'layout'); - } - - /* (non-PHPdoc) - * @see WindModule::getCloneProperty() - */ - protected function getCloneProperty() { - return array('viewResolver'); - } - -} \ No newline at end of file diff --git a/wind/core/viewer/WindViewerResolver.php b/wind/core/viewer/WindViewerResolver.php deleted file mode 100644 index 054b05c1..00000000 --- a/wind/core/viewer/WindViewerResolver.php +++ /dev/null @@ -1,139 +0,0 @@ - 2010-11-15 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.viewer.IWindViewerResolver'); -Wind::import('WIND:core.WindComponentModule'); -/** - * 默认视图引擎 - * 基于URL的视图引擎,视图名和模板名称保持一致 - * - * 该视图类接收一个modelAndView对象,通过解析该对象获得一个逻辑视图名称 - * 并将该逻辑视图名称,映射到具体的视图资源。 - * - * 布局解析,模板解析,编译缓存,模板缓存 - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindViewerResolver extends WindComponentModule implements IWindViewerResolver { - - /** - * 模板信息 - * @var WindView - */ - protected $windView = null; - - /** - * @var WindUrlHelper - */ - protected $urlHelper = null; - - /** - * 立即输出模板内容 - * - * @param string $template - */ - public function displayWindFetch($template = '') { - echo $this->windFetch($template); - } - - /* (non-PHPdoc) - * @see IWindViewerResolver::windFetch() - */ - public function windFetch($template = '') { - if (!$template && null !== $layout = $this->getWindView()->getLayout()) { - $template = $layout; - } - ob_start(); - $this->render($template); - return ob_get_clean(); - } - - /** - * 设置模板变量信息 - * - * @param object|array|string $vars - * @param string $key - */ - public function windAssign($vars, $key = '') { - if ($key === '') $key = $this->getWindView()->getTemplateName(); - $this->response->setData($vars, $key); - } - - /** - * 编译模板并返回编译后模板名称 - * @param string $template - * @param string $suffix - * @param boolean $output - * @return string - */ - public function compile($template, $suffix = '', $output = false) { - $templateFile = $this->getWindView()->getViewTemplate($template, $suffix); - if (!file_exists($templateFile)) { - throw new WindViewException($templateFile, WindViewException::VIEW_NOT_EXIST); - } - if (!$this->getWindView()->getCompileDir()) return $templateFile; - $compileFile = $this->getWindView()->getCompileFile($template, 'tpl'); - $_windTemplate = $this->windFactory->getInstance(COMPONENT_TEMPLATE); - if ($_windTemplate) { - $_output = $_windTemplate->compile($templateFile, $compileFile, $this); - } - if ($output === false) return $compileFile; - if ($_output !== null) return array($compileFile, $_output); - if ($fp = @fopen($compileFile, 'r')) { - while (!feof($fp)) - $_output .= fgets($fp, 4096); - fclose($fp); - } else - throw new WindViewException('Unable to open the template file \'' . $compileFile . '\'.'); - - return array($compileFile, $_output); - } - - /** - * 加载视图模板文件 - * @param template - */ - protected function render($template) { - $_tmp = $this->compile($template); - //extract template vars - @extract((array) $this->response->getData($this->windView->getTemplateName()), EXTR_REFS); - if (!include $_tmp) { - throw new WindViewException($_tmp, WindViewException::VIEW_NOT_EXIST); - } - } - - /** - * 当前模板内容 - * @param string $template - */ - private function getContent($template = '') { - if (!$template) $template = $this->getWindView()->getTemplateName(); - if ($template) $this->displayWindFetch($template); - } - - /** - * @return WindView $windView - */ - public function getWindView() { - if ($this->windView !== null) - return $this->windView; - else - throw new WindException('WindView', WindException::ERROR_RETURN_TYPE_ERROR); - } - - /* (non-PHPdoc) - * @see WindModule::getWriteTableForGetterAndSetter() - */ - protected function getWriteTableForGetterAndSetter() { - return array('windView', 'windTemplate', 'urlHelper', 'templateVars'); - } - -} \ No newline at end of file diff --git a/wind/core/viewer/compiler/WindTemplateCompilerAction.php b/wind/core/viewer/compiler/WindTemplateCompilerAction.php deleted file mode 100644 index cec0934a..00000000 --- a/wind/core/viewer/compiler/WindTemplateCompilerAction.php +++ /dev/null @@ -1,53 +0,0 @@ - 2010-11-2 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2010 phpwind.com - * @license - */ - -Wind::import('WIND:core.viewer.AbstractWindTemplateCompiler'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindTemplateCompilerAction extends AbstractWindTemplateCompiler { - - protected $action = ''; - - protected $controller = ''; - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - $_content = 'getScript() . ' ?>' . "\r\n"; - return $_content; - } - - /** - * @return string - */ - public function getScript() { - $_tmp = ''; - $_tmp .= '$_tpl_forward = $this->windFactory->getInstance(COMPONENT_FORWARD);'. - '$_tpl_forward->forwardAnotherAction(\''.$this->action.'\', \''.$this->controller.'\');'. - '$_tpl_appName = $this->windSystemConfig->getAppClass();'. - '$_tpl_app = $this->windFactory->getInstance($_tpl_appName);'. - '$_tpl_app->getDispatcher()->setDisplay(true);'. - '$_tpl_app->doDispatch($_tpl_forward);'. - 'list($viewName, $tplVars) = $_tpl_app->getDispatcher()->getAttribute("viewCache");'. - '$this->windAssign($tplVars, $viewName);'; - return $_tmp; - } - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::getProperties() - */ - public function getProperties() { - return array('action', 'controller'); - } - -} \ No newline at end of file diff --git a/wind/core/web/IWindApplication.php b/wind/core/web/IWindApplication.php index cd1c4b42..aa44406d 100644 --- a/wind/core/web/IWindApplication.php +++ b/wind/core/web/IWindApplication.php @@ -1,8 +1,5 @@ * @author Qiong Wu * @version $Id$ @@ -12,6 +9,8 @@ interface IWindApplication { /** * 请求处理 + * @param IWindHttpRequest $request + * @param IWindHttpResponse $response */ public function processRequest(); @@ -21,7 +20,5 @@ public function processRequest(); * @param WindForward $forward */ public function doDispatch($forward); - } - ?> \ No newline at end of file diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php deleted file mode 100644 index 222efbf1..00000000 --- a/wind/core/web/WindController.php +++ /dev/null @@ -1,62 +0,0 @@ - 2010-11-8 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.web.WindAction'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class WindController extends WindAction { - - protected $validatorClass = 'WIND:component.utility.WindValidator'; - - /* (non-PHPdoc) - * @see WindAction::resolvedActionMethod() - */ - protected function resolvedActionMethod($handlerAdapter) { - $action = $handlerAdapter->getAction(); - if ($action !== 'run') $action = $this->resolvedActionName($action); - try { - $method = new ReflectionMethod($this, $action); - } catch (Exception $exception) { - throw new WindActionException('The action method ' . $action . ' is protected or not exist.'); - } - if ($action !== 'doAction' && !$method->isAbstract() && $method->isPublic()) - call_user_func_array(array($this, $action), array()); - else - throw new WindException(); - } - - /** - * 根据请求的Action值返回Action的真正方法名 - * 可以通过覆盖该方法来改变Action的命名规则 - * @param string $action - * @return string - */ - protected function resolvedActionName($action) { - return $action . 'Action'; - } - - /** - * 实现表单验证规则 - * @param string $type - */ - public function validatorFormRule($type) { - return array(); - } - - /** - * @return the $validatorClass - */ - public function getValidatorClass() { - return $this->validatorClass; - } - -} \ No newline at end of file diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php index 90fe8469..91396495 100644 --- a/wind/core/web/WindDispatcher.php +++ b/wind/core/web/WindDispatcher.php @@ -1,126 +1,176 @@ 2010-12-15 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.WindComponentModule'); +Wind::import('COM:viewer.exception.WindViewException'); /** - * 请求分发 - * + * 职责描述:负责请求的分发 + * 分发类型: + * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ -class WindDispatcher extends WindComponentModule { - - protected $oldRouter = null; - +class WindDispatcher extends WindModule { + /** + * 将上一次请求信息缓存在这个变量中 + * + * @var array + */ + protected $processCache = array(); + /** + * @var WindUrlHelper + */ + protected $urlHelper = null; + + /** + * @var boolean + */ protected $display = false; /** - * 请求分发处理 - * @param WindForward $forward + * 请求分发处理 + * + * @param WindWebApplication $app + * @param WindForward $forward + * @param WindUrlBasedRouter $router + * @return */ - public function dispatch($forward) { - $this->oldRouter = clone $this->windFactory->getInstance(COMPONENT_ROUTER); + public function dispatch($app, $forward, $router) { + $this->checkProcess($router, false); if ($forward->getIsRedirect()) - $this->dispatchWithRedirect($forward); + $this->dispatchWithRedirect($app, $forward, $router); elseif ($forward->getIsReAction()) - $this->dispatchWithAction($forward); + $this->dispatchWithAction($app, $forward, $router); else - $this->render($forward); + $this->render($app, $forward, $router); $this->destroy(); } /** * 请求分发一个重定向请求 - * @param WindForward $forward + * + * @param WindWebApplication $app + * @param WindForward $forward + * @param WindUrlBasedRouter $router + * @return */ - protected function dispatchWithRedirect($forward) { + protected function dispatchWithRedirect($app, $forward, $router) { $_url = $forward->getUrl(); - //TODO check $_url 在urlHelper中添加url检测方法,检查是否是一个正确的Url形式,包括包含不包含域名等 - $urlHelper = $this->windFactory->getInstance(COMPONENT_URLHELPER); if (!$_url && $forward->getIsReAction()) { - /* @var $urlHelper WindUrlHelper */ - $_url = $urlHelper->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); - } - $_url = $urlHelper->checkUrl($_url); - $_router = $this->windFactory->getInstance(COMPONENT_ROUTER); - $_router->reParse(); - if ($forward->getIsReAction() && !$this->checkProcess($_router)) { - throw new WindException('Duplicate request ' . $_router->getAction() . '_' . $_router->getController() . '.' . $_router->getModule()); - } - $this->response->sendRedirect($_url); + $_url = $this->getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), + $forward->getArgs()); + $router->reParse(); + if (!$this->checkProcess($router)) { + throw new WindException('[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request ', + WindException::ERROR_SYSTEM_ERROR); + } + } else + $_url = $this->getUrlHelper()->checkUrl($_url); + $this->getResponse()->sendRedirect($_url); } /** - * 请求分发一个操作请求 - * @param WindForward $forward + * 请求分发一个操作请求 + * + * @param WindWebApplication $app + * @param WindForward $forward + * @param WindUrlBasedRouter $router + * @return */ - protected function dispatchWithAction($forward) { - $_a = $forward->getAction(); + protected function dispatchWithAction($app, $forward, $router) { + //TODO 是否需要缓存上次请求的变量信息 + $this->getRequest()->setAttribute($forward->getVars(), + $router->getAction() . '_' . $router->getController()); + $this->setDisplay($forward->getDisplay()); list($_c, $_m) = WindHelper::resolveController($forward->getController()); - - /* @var $_router WindUrlBasedRouter */ - $_router = $this->windFactory->getInstance(COMPONENT_ROUTER); - $_a && $_router->setAction($_a); - $_c && $_router->setController($_c); - $_m && $_router->setModule($_m); - if (!$this->checkProcess($_router)) { - throw new WindException('Duplicate request ' . $_router->getAction() . '_' . $_router->getController() . '.' . $_router->getModule()); + $_a = $forward->getAction(); + $_a && $router->setAction($_a); + $_c && $router->setController($_c); + $_m && $router->setModule($_m); + if (!$this->checkProcess($router)) { + throw new WindException('[core.web.WindDispatcher.dispatchWithAction] Duplicate request ', + WindException::ERROR_SYSTEM_ERROR); } - - $appName = $this->windSystemConfig->getAppClass(); - $application = $this->windFactory->getInstance($appName); - $application->processRequest(); - } - - /** - * 检查请求是否是重复请求 - * @param AbstractWindRouter $router - * @param string $action - * @param string $controller - */ - protected function checkProcess($router) { - if ($router->getAction() !== $this->oldRouter->getAction()) return true; - if ($router->getController() !== $this->oldRouter->getController()) return true; - if ($router->getModule() !== $this->oldRouter->getModule()) return true; - return false; + $app->processRequest(); } /** * 进行视图渲染 + * + * @param WindWebApplication $app * @param WindForward $forward + * @param WindUrlBasedRouter $router + * @return */ - protected function render($forward) { - if ($forward && null !== ($windView = $forward->getWindView())) { - if ($windView->getTemplateName() === '') return; - $viewResolver = $windView->getViewResolver(); - $this->response->setData($forward->getVars(), $windView->getTemplateName()); - if ($this->display === false) - $this->response->setBody($viewResolver->windFetch(), $windView->getTemplateName()); + protected function render($app, $forward, $router) { + try { + if ($windViewClass = $forward->getWindView()) + $view = $this->getSystemFactory()->createInstance($windViewClass); + elseif ($windViewClass = $this->getSystemConfig()->getModuleViewClassByModuleName($router->getModule())) + $view = $this->getSystemFactory()->getInstance($windViewClass); else - $viewResolver->displayWindFetch(); - } else - throw new WindException('unable to create the object with forward.'); + $view = $this->getSystemFactory()->getInstance(COMPONENT_VIEW); + $view->setConfig($this->getSystemConfig()->getModuleViewConfigByModuleName($router->getModule())); + $view->render($forward, $router, $this->getDisplay()); + } catch (Exception $e) { + throw new WindViewException('[core.web.WindDispatcher.render] view render fail.' . $e->getMessage()); + } } - /* (non-PHPdoc) - * @see WindModule::getWriteTableForGetterAndSetter() + /** + * 检查请求是否是重复请求 + * + * @param WindUrlBasedRouter $router + * @param boolean $check + * @return boolean */ - public function getWriteTableForGetterAndSetter() { - return array('display'); + protected function checkProcess($router, $check = true) { + if ($check === false) { + $this->processCache['action'] = $router->getAction(); + $this->processCache['controller'] = $router->getController(); + $this->processCache['module'] = $router->getModule(); + } elseif ($router->getAction() === $this->processCache['action'] && + $router->getController() === $this->processCache['controller'] && + $router->getModule() === $this->processCache['module']) + return false; + return true; } /** * 注销当前dispatcher状态 + * + * @return */ protected function destroy() { - $this->display = false; - $this->oldRouter = null; + $this->processCache = array(); + $this->setDisplay(false); + } + + /** + * @return boolean + */ + public function getDisplay() { + return $this->display; + } + + /** + * @param boolean $display + */ + public function setDisplay($display) { + $this->display = $display; + } + + /** + * @return WindUrlHelper + */ + public function getUrlHelper() { + return $this->_getUrlHelper(); } + + /** + * @param WindUrlHelper $urlHelper + */ + public function setUrlHelper($urlHelper) { + $this->urlHelper = $urlHelper; + } + } diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php index 2e01a67e..bab45cde 100644 --- a/wind/core/web/WindErrorHandler.php +++ b/wind/core/web/WindErrorHandler.php @@ -1,5 +1,4 @@ * @author Qiong Wu @@ -49,7 +48,7 @@ final public function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { $errfile = $this->getFile($errfile); $_tmp = "$errstr ($errfile:$errline)\r\nStack trace:\r\n"; - $_trace = debug_backtrace(false); + $_trace = debug_backtrace(); foreach ($_trace as $key => $value) { if (!isset($value['file'])) continue; if (!isset($value['line'])) $value['line'] = 0; @@ -64,11 +63,11 @@ final public function errorHandle($errno, $errstr, $errfile, $errline) { } else echo "

" . $this->errnoMap($errno) . " $errstr

"; Wind::log($this->errnoMap($errno) . $errstr, $_tmp); + exit(); } } /** - * Enter description here ... * @param $string $errno */ private function errnoMap($errno) { @@ -124,20 +123,21 @@ private function errnoMap($errno) { * 异常处理句柄 */ final public function exceptionHandle($exception) { - $_tmp = $exception->getMessage() . ' (' . $this->getFile($exception->getFile()) . ':' . $exception->getLine() . ')'; - if (IS_DEBUG > WindLogger::LEVEL_DEBUG) { - echo '

' . get_class($exception) . '

'; - echo "

$_tmp

"; - echo '
' . $exception->getTraceAsString() . '
'; - } else { - echo '

' . get_class($exception) . '

'; - echo '

' . $exception->getMessage() . '

'; + $_tmp = $exception->getMessage() . ' (' . $this->getFile($exception->getFile()) . ':' . $exception->getLine() . + ')'; + if (IS_DEBUG) { + echo '

' . get_class($exception) . '

'; + echo "

$_tmp

"; + echo '
' . $exception->getTraceAsString() . '
'; + } else { + echo '

' . get_class($exception) . '

'; + echo '

' . $exception->getMessage() . '

'; + } + Wind::log("$_tmp:" . $exception->getTraceAsString()); + exit(); } - Wind::log("$_tmp:" . $exception->getTraceAsString()); - exit(); - } - private function getFile($filePath) { - return $filePath; - } -} \ No newline at end of file + private function getFile($filePath) { + return $filePath; + } + } \ No newline at end of file diff --git a/wind/core/web/WindErrorMessage.php b/wind/core/web/WindErrorMessage.php index 11cc527e..926fd216 100644 --- a/wind/core/web/WindErrorMessage.php +++ b/wind/core/web/WindErrorMessage.php @@ -1,12 +1,11 @@ * @author Qiong Wu * @version $Id$ * @package */ -class WindErrorMessage implements IWindErrorMessage { +class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction = 'run'; /** @@ -27,6 +26,7 @@ public function __construct($message = '', $errorAction = '', $errorController = * @see IWindErrorMessage::sendError() */ public function sendError() { + if (empty($this->error)) return; throw new WindActionException($this); } diff --git a/wind/core/web/WindFormController.php b/wind/core/web/WindFormController.php deleted file mode 100644 index dc3d03e4..00000000 --- a/wind/core/web/WindFormController.php +++ /dev/null @@ -1,56 +0,0 @@ - 2010-11-8 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.base.WindAction'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindFormController extends WindAction { - - protected $formClass = ''; - - /* (non-PHPdoc) - * @see WindAction::resolvedActionMethod() - */ - protected function resolvedActionMethod($handlerAdapter) { - $action = $handlerAdapter->getAction(); - if ($action !== 'run') $action = $this->resolvedActionName($action); - try { - $method = new ReflectionMethod($this, $action); - } catch (Exception $exception) { - throw new WindActionException('The action method ' . $action . ' is protected or not exist.'); - } - if ($action !== 'doAction' && !$method->isAbstract() && $method->isPublic()) - call_user_func_array(array($this, $action), array()); - else - throw new WindException(); - } - - /** - * 根据请求的Action值返回Action的真正方法名 - * 可以通过覆盖该方法来改变Action的命名规则 - * @param string $action - * @return string - */ - protected function resolvedActionName($action) { - return $action . 'Action'; - } - - /** - * 返回form的类 - * @return the $formClass - */ - public function getFormClass() { - return $this->formClass; - } -} - -?> \ No newline at end of file diff --git a/wind/core/web/WindForward.php b/wind/core/web/WindForward.php index 07335ee7..65294291 100644 --- a/wind/core/web/WindForward.php +++ b/wind/core/web/WindForward.php @@ -1,12 +1,4 @@ 2010-11-22 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.WindComponentModule'); /** * 操作转发类,将操作句柄转发给下一个操作或者转发给一个视图处理 * the last known user to change this file in the repository <$LastChangedBy$> @@ -14,65 +6,81 @@ * @version $Id$ * @package */ -class WindForward extends WindComponentModule { - +class WindForward extends WindModule { /** - * 模板视图信息 + * 定义视图处理器 * - * @var WindView + * @var string */ - private $windView = null; - + private $windView; /** - * 模板变量信息 + * 模板名称 + * + * @var strig + */ + private $templateName; + /** + * 模板路径 * + * @var string + */ + private $templatePath; + /** + * 模板扩展名 + * + * @var string + */ + private $templateExt; + /** + * 模板布局 + * + * @var string + */ + private $layout; + /** + * 模板变量信息 + * * @var array */ private $vars = array(); - /** * 是否为Action请求 - * + * * @var boolean */ private $isReAction = false; - /** * 是否是重定向请求 - * + * * @var boolean */ private $isRedirect = false; - /** * 跳转链接 - * + * * @var string */ - private $url = ''; - - private $action = ''; - - private $controller = ''; - - private $args = ''; + private $url; + private $action; + private $controller; + private $args; + private $display = false; /** * 将请求重定向到另外一个Action操作 - * * @param string $action | $action 操作 * @param string $controller | controller 路径 , controller 为空是则指向当前的控制器 * @param array $args | 参数 * @param boolean $isRedirect | 是否重定向 * - * @return null + * @return */ - public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = '') { + public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); - $isRedirect !== '' && $this->setIsRedirect($isRedirect); + $this->setIsRedirect($isRedirect); } /** @@ -90,23 +98,6 @@ public function setVars($vars, $key = '') { return; } - /** - * @return WindView $windView - */ - public function getWindView() { - if ($this->windView === null) { - $module = $this->windFactory->getInstance(COMPONENT_ROUTER)->getModule(); - $moduleConfig = $this->windSystemConfig->getModules($module); - $view = $this->windSystemConfig->getConfig('view', WindSystemConfig::CLASS_PATH, (array) $moduleConfig); - if (!$view) $view = COMPONENT_VIEW; - - $this->windView = $this->windFactory->getInstance($view); - $_viewConfig = $this->windView->getConfig('view', WIND_CONFIG_CONFIG, $moduleConfig); - if ($_viewConfig) $this->windView->updateConfig($_viewConfig, true); - } - return $this->windView; - } - /** * @return the $isRedirect */ @@ -198,4 +189,88 @@ public function setArgs($args) { $this->args = $args; } + /** + * @return the $templateName + */ + public function getTemplateName() { + return $this->templateName; + } + + /** + * @return the $templatePath + */ + public function getTemplatePath() { + return $this->templatePath; + } + + /** + * @return the $templateExt + */ + public function getTemplateExt() { + return $this->templateExt; + } + + /** + * @return the $layout + */ + public function getLayout() { + return $this->layout; + } + + /** + * @param strig $templateName + */ + public function setTemplateName($templateName) { + $this->templateName = $templateName; + } + + /** + * @param string $templatePath + */ + public function setTemplatePath($templatePath) { + $this->templatePath = $templatePath; + } + + /** + * @param string $templateExt + */ + public function setTemplateExt($templateExt) { + $this->templateExt = $templateExt; + } + + /** + * @param string $layout + */ + public function setLayout($layout) { + $this->layout = $layout; + } + + /** + * @return string + */ + public function getWindView() { + return $this->windView; + } + + /** + * @param string $windView + */ + public function setWindView($windView) { + $this->windView = $windView; + } + + /** + * @return the $display + */ + public function getDisplay() { + return $this->display; + } + + /** + * @param field_type $display + */ + public function setDisplay($display) { + $this->display = $display; + } + } \ No newline at end of file diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 7a8ced70..c38c8e5b 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -1,153 +1,166 @@ 2010-10-27 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2010 phpwind.com - * @license - */ -Wind::import('WIND:core.AbstractWindServer'); /** * 抽象的前端控制器接口,通过集成该接口可以实现以下职责 - * * 职责定义: * 接受客户请求 * 处理请求 * 向客户端发送响应 - * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ -class WindFrontController extends AbstractWindServer { - const WIND_CONFIG = 'WIND:core.config.WindSystemConfig'; - const WIND_FACTORY = 'WIND:core.factory.WindComponentFactory'; - const COMPONENTS_CONFIG = 'WIND:components_config.php'; +class WindFrontController { + /** + * 全局配置对象类型定义,建议WindSystemConfig配置类作为全局配置容器 + */ + const WIND_SYSTEM_CONFIG = 'WIND:core.config.WindSystemConfig'; + /** + * 全局工厂类型定义,建议WindComponentFactory工厂类作为全局工厂 + */ + const WIND_SYSTEM_FACTORY = 'WIND:core.factory.WindFactory'; + /** + * 框架系统配置信息资源地址,只接受php格式配置 + */ + const WIND_COMPONENT_CONFIG_RESOURCE = 'WIND:components_config.php'; + /** + * @var WindHttpRequest + */ + private $request; + /** + * @var WindHttpResponse + */ + private $response; /** * @var WindSystemConfig */ protected $windSystemConfig = null; + /** + * @var WindFactory + */ protected $windFactory = null; - protected $windErrorHandler = null; /** * @param WindConfig $windConfig * @param WindFactory $windFactory */ - public function __construct($appName, $config = array()) { - parent::__construct(); - $this->initWindConfig($appName, $config); - $this->initWindFactory(); + public function __construct($appName, $config = '') { + try { + $this->request = new WindHttpRequest(); + $this->response = $this->request->getResponse(); + $this->initWindConfig($appName, $config); + $this->initWindFactory(); + } catch (Exception $exception) { + throw new Exception('System failed to initialize.' . $exception->getMessage()); + } } /** - * 初始化类工厂 + * 执行操作 + * @throws Exception */ - protected function initWindFactory() { - $configPath = Wind::getRealPath(self::COMPONENTS_CONFIG); - $classesDefinitions = $this->getWindConfig()->getConfigParser()->parse($configPath, 'components', WIND_CONFIG_CACHE); - $factoryClass = Wind::import(self::WIND_FACTORY); - if (!class_exists($factoryClass)) { - throw new WindException($factoryClass, WindException::ERROR_CLASS_NOT_EXIST); + public function run() { + $this->beforeProcess(); + $appName = $this->windSystemConfig->getAppClass(); + /* @var $application WindModule */ + $application = $this->windFactory->getInstance($appName); + if ($application === null) { + throw new WindException($appName . '[core.web.WindFrontController.process]', + WindException::ERROR_CLASS_NOT_EXIST); } - $this->windFactory = new $factoryClass($classesDefinitions); + $routerAlias = $this->windSystemConfig->getRouterClass(); + $application->setDelayAttributes(array('handlerAdapter' => array('ref' => $routerAlias))); + + if (null !== ($filterChain = $this->getFilterChain())) { + $filterChain->setCallBack(array($application, 'processRequest'), array()); + $filterChain->getHandler()->handle($this->request, $this->response); + } else + $application->processRequest($this->request, $this->response); + $this->afterProcess(); } /** - * @param string $appName - * @param string $config + * @return WindFilterChain */ - protected function initWindConfig($appName, $config) { - Wind::import('WIND:core.config.parser.WindConfigParser'); - Wind::import('WIND:core.config.WindSystemConfig'); - $configParser = new WindConfigParser(); - $this->windSystemConfig = new WindSystemConfig($config, $configParser, ($appName ? $appName : 'default')); - Wind::register($this->getWindConfig()->getRootPath(), $this->getWindConfig()->getAppName()); - //TODO register all apps + protected function getFilterChain() { + $filterChainPath = $this->windSystemConfig->getFilterClass(); + $filters = $this->windSystemConfig->getFilters(); + if (empty($filters) || empty($filterChainPath)) return null; + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log( + "[core.WindFrontController.getFilterChain] an filter chain defined.(" . $filterChainPath . "," . + count($filters) . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); + } + return $this->windFactory->createInstance($filterChainPath, array($filters)); } - /* (non-PHPdoc) - * @see wind/core/base/WindServer#process() - */ - protected function process(WindHttpRequest $request, WindHttpResponse $response) { - $this->getWindFactory()->request = $request; - $this->getWindFactory()->response = $response; - $request->setAttribute(self::WIND_CONFIG, $this->windSystemConfig); - $request->setAttribute(self::WIND_FACTORY, $this->windFactory); - $appName = $this->getWindConfig()->getAppClass(); - $application = $this->getWindFactory()->getInstance($appName); - if (null === $application) { - throw new WindException('application', WindException::ERROR_CLASS_NOT_EXIST); + /** + * 初始全局工厂类 + * @return + */ + protected function initWindFactory() { + $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); + $factoryClass = Wind::import(self::WIND_SYSTEM_FACTORY); + $this->windFactory = new $factoryClass(@include ($configPath)); + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log('[core.web.WindFrontController.initWindFactory] system factory:' . self::WIND_SYSTEM_FACTORY, + WindLogger::LEVEL_DEBUG, 'wind.core'); } - $this->getWindFactory()->application = $application; - if (null !== $filterChain = $this->getFilterChain()) { - $filterChain->setCallBack(array($application, 'processRequest'), array()); - $filterChain->getHandler()->handle($request, $response); - } else - $application->processRequest(); } /** - * @return WindFilterChain + * 初始化系统配置 + * @param string $appName + * @param string $config */ - private function getFilterChain() { - $filterChainPath = $this->getWindConfig()->getFilters(WindSystemConfig::CLASS_PATH); - return $this->getWindFactory()->createInstance($filterChainPath, array($this->getWindConfig()->getFilters())); + protected function initWindConfig($appName, $config) { + !$appName && $appName = 'default'; + $this->windSystemConfig = new WindSystemConfig($config, new WindConfigParser(), $appName); + Wind::register($this->windSystemConfig->getRootPath(), $this->windSystemConfig->getAppName(), true); + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log( + '[core.web.WindFrontController.initWindConfig] rootPath:' . $this->windSystemConfig->getRootPath() . + ' appName:' . $this->windSystemConfig->getAppName(), WindLogger::LEVEL_DEBUG, 'wind.core'); + } } /* (non-PHPdoc) * @see AbstractWindServer::beforeProcess() */ - protected function beforeProcess(WindHttpRequest $request, WindHttpResponse $response) { - Wind::import('WIND:core.web.WindErrorHandler'); - set_error_handler(array(new WindErrorHandler(), 'errorHandle'), error_reporting()); - set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); - } + protected function beforeProcess() {} /* (non-PHPdoc) * @see AbstractWindServer::afterProcess() */ - protected function afterProcess(WindHttpRequest $request, WindHttpResponse $response) { - Wind::getLogger()->flush(); - restore_error_handler(); - restore_exception_handler(); + protected function afterProcess() { + $this->response->sendResponse(); } /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @throws Exception + * @return WindsystemConfig */ - protected function doPost(WindHttpRequest $request, WindHttpResponse $response) { - $this->process($request, $response); + public function getWindSystemConfig() { + return $this->windSystemConfig; } /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @throws Exception + * @return WindComponentFactory */ - protected function doGet(WindHttpRequest $request, WindHttpResponse $response) { - $this->process($request, $response); + public function getWindFactory() { + return $this->windFactory; } /** - * @return WindSystemConfig $windConfig + * @return WindHttpRequest */ - public function getWindConfig() { - if ($this->windSystemConfig instanceof WindConfig) - return $this->windSystemConfig; - else - throw new WindException(get_class($this) . '->windSystemConfig', WindException::ERROR_CLASS_TYPE_ERROR); + public function getRequest() { + return $this->request; } /** - * @return WindFactory $windFactory + * @return WindHttpResponse */ - public function getWindFactory() { - if ($this->windFactory instanceof WindFactory) - return $this->windFactory; - else - throw new WindException(get_class($this) . '->windFactory', WindException::ERROR_CLASS_TYPE_ERROR); + public function getResponse() { + return $this->response; } } \ No newline at end of file diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php index fe6de0af..15671f8c 100644 --- a/wind/core/web/WindUrlHelper.php +++ b/wind/core/web/WindUrlHelper.php @@ -1,37 +1,19 @@ 2010-10-27 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2010 phpwind.com - * @license - */ - -/** - * Enter description here ... - * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ -class WindUrlHelper extends WindComponentModule { - +class WindUrlHelper extends WindModule { const URL_PATTERN = 'url-pattern'; - const ROUTE_SUFFIX = 'route-suffix'; - const ROUTE_PARAM = 'route-param'; - const REWRITE = false; - const ROUTE_SEPARATOR = '_'; - protected $routeSuffix = ''; - protected $routeParam = ''; - protected $urlPattern = ''; - protected $windRouter = null; public function isRewrite() { @@ -229,7 +211,7 @@ private function buildRewriteURL($params, $routerInfo) { $separator = $this->getSeparator(); if (empty($params)) return $separator[1] . $routerInfo; $url = ''; - foreach ((array)$params as $key => $value) { + foreach ((array) $params as $key => $value) { $url .= $this->buildKey($key, $value, $separator[0], $separator[1]) . $separator[1]; } return $separator[1] . $url . $routerInfo; @@ -351,7 +333,5 @@ public function getWindRouter() { public function setWindRouter($windRouter) { $this->windRouter = $windRouter; } - } - ?> \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index ecaf8c99..ad93b167 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -1,56 +1,40 @@ 2010-11-7 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.WindComponentModule'); -Wind::import('WIND:core.web.IWindApplication'); -Wind::import('WIND:core.factory.WindComponentDefinition'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ -class WindWebApplication extends WindComponentModule implements IWindApplication { - - const ERROR_HANDLER = 'error-handler'; - +class WindWebApplication extends WindModule implements IWindApplication { + /** + * @var WindDispatcher + */ protected $dispatcher = null; - - protected $errorHandle = 'WIND:core.web.WindErrorHandler'; + /** + * @var WindUrlBasedRouter + */ + protected $handlerAdapter = null; /* (non-PHPdoc) * @see IWindApplication::processRequest() */ public function processRequest() { try { - //add log - if (IS_DEBUG) { - /* @var $logger WindLogger */ - //TODO 调试信息输出调用Wind::log - Wind::log('do processRequest of ' . get_class($this), WindLogger::LEVEL_DEBUG, 'wind.debug'); -// $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); -// $logger->debug('do processRequest of ' . get_class($this)); + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log('[core.web.WindWebApplication.processRequest]', WindLogger::LEVEL_DEBUG, 'wind.core'); } - $handler = $this->getHandler(); - $forward = call_user_func_array(array($handler, 'doAction'), array($this->getHandlerAdapter())); - if ($forward === null) { - throw new WindException('doAction', WindException::ERROR_RETURN_TYPE_ERROR); - } + call_user_func_array(array($handler, 'preAction'), array($this->handlerAdapter)); + $forward = call_user_func_array(array($handler, 'doAction'), array($this->handlerAdapter)); + call_user_func_array(array($handler, 'postAction'), array($this->handlerAdapter)); $this->doDispatch($forward); } catch (WindActionException $actionException) { $this->sendErrorMessage($actionException); - } catch (WindDbException $dbException) { $this->sendErrorMessage($dbException->getMessage()); - } catch (WindViewException $viewException) { - + //TODO + throw new Exception($viewException->getMessage()); } } @@ -58,16 +42,12 @@ public function processRequest() { * @see IWindApplication::doDispatch() */ public function doDispatch($forward) { - //add log - if (IS_DEBUG) { - /* @var $logger WindLogger */ - //TODO 调试信息 - Wind::log('do doDispatch of ' . get_class($this), WindLogger::LEVEL_DEBUG, 'wind.debug'); -// $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); -// $logger->info('do doDispatch of ' . get_class($this)); + if ($forward === null) { + Wind::log('[core.web.WindWebApplication.doDispatch] Forward is null, dispatch abort.', + WindLogger::LEVEL_DEBUG, 'wind.core'); + return; } - - $this->dispatcher->dispatch($forward); + $this->getDispatcher()->dispatch($this, $forward, $this->handlerAdapter); } /** @@ -76,110 +56,52 @@ public function doDispatch($forward) { * @param WindHttpRequest $request */ protected function getHandler() { - $handlerAdapter = $this->getHandlerAdapter(); - $handlerAdapter->doParse(); - - //add log - if (IS_DEBUG) { - /* @var $logger WindLogger */ - //TODO 调试信息输出调用Wind::log - Wind::log('router result: Action:' . $handlerAdapter->getAction() . ' Controller:' . $handlerAdapter->getController() . ' Module:' . $handlerAdapter->getModule(), WindLogger::LEVEL_DEBUG, 'wind.debug'); -// $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); -// $logger->debug('router result: Action:' . $handlerAdapter->getAction() . ' Controller:' . $handlerAdapter->getController() . ' Module:' . $handlerAdapter->getModule()); + $handler = $this->getHandlerAdapter()->doParse(); + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log('[core.web.WindWebApplication.getHandler] router result:' . $handler, WindLogger::LEVEL_DEBUG, + 'wind.core'); } - - if (!strcasecmp($handlerAdapter->getController(), WIND_M_ERROR)) { - $moduleConfig = $this->windSystemConfig->getModules($this->getModule()); - $handler = $this->windSystemConfig->getConfig(self::ERROR_HANDLER, WIND_CONFIG_CLASS, $moduleConfig, $this->errorHandle); - } else - $handler = $handlerAdapter->getHandler(); - - $definition = new WindComponentDefinition(); - $definition->setPath($handler); - $definition->setScope(WindComponentDefinition::SCOPE_PROTOTYPE); - $definition->setProxy('true'); - $definition->setAlias($handler); - $definition->setPropertys(array('errorMessage' => array('ref' => COMPONENT_ERRORMESSAGE), - 'forward' => array('ref' => COMPONENT_FORWARD), 'urlHelper' => array('ref' => COMPONENT_URLHELPER))); - - $this->windFactory->addClassDefinitions($definition); - $actionHandler = $this->windFactory->getInstance($handler); - $actionHandler->beforeAction($handlerAdapter); - - //TODO 添加过滤链 - if ($actionHandler->_getInstance() instanceof WindFormController) { - if ($formClassPath = $actionHandler->getFormClass()) { - Wind::import('WIND:core.web.listener.WindFormListener'); - $actionHandler->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $actionHandler->getErrorMessage())); - } - } elseif ($actionHandler->_getInstance() instanceof WindController) { - if ($rules = (array) $actionHandler->validatorFormRule($handlerAdapter->getAction())) { - if (!isset($rules['errorMessage'])) { - $rules['errorMessage'] = $actionHandler->getErrorMessage(); - } - Wind::import('WIND:core.web.listener.WindValidateListener'); - $actionHandler->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $actionHandler->getValidatorClass())); - } - } - - //add log - if (IS_DEBUG) { - /* @var $logger WindLogger */ - //TODO 调试信息输出调用Wind::log - Wind::log('ActionHandler: ', WindLogger::LEVEL_DEBUG, 'wind.debug'); -// $logger = $this->windFactory->getInstance(COMPONENT_LOGGER); -// $logger->debug('ActionHandler: ' . $handler); + if (!$this->getSystemFactory()->checkAlias($handler)) { + $definition = new WindClassDefinition(); + $definition->setPath($handler); + $definition->setScope(WindClassDefinition::SCOPE_SINGLETON); + $definition->setAlias($handler); + $definition->setProxy('true'); + $definition->setProperties( + array('errorMessage' => array('ref' => COMPONENT_ERRORMESSAGE), + 'forward' => array('ref' => COMPONENT_FORWARD), 'urlHelper' => array('ref' => COMPONENT_URLHELPER))); + $this->getSystemFactory()->addClassDefinitions($definition); } - - return $actionHandler; + return $this->getSystemFactory()->getInstance($handler); } /** - * 错误请求 + * 异常处理请求 + * * @param WindActionException|string actionException + * @return */ protected function sendErrorMessage($actionException) { - $forward = $this->windFactory->getInstance(COMPONENT_FORWARD); $_tmp = is_object($actionException) ? $actionException->getError() : $actionException; - if (is_string($_tmp)) { - Wind::import('WIND:core.web.WindErrorMessage'); - $_tmp = new WindErrorMessage($_tmp); - } + if (is_string($_tmp)) $_tmp = new WindErrorMessage($_tmp); + $forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD); $forward->forwardAnotherAction($_tmp->getErrorAction(), $_tmp->getErrorController()); - $this->request->setAttribute('error', $_tmp->getError()); + $this->getRequest()->setAttribute('error', $_tmp->getError()); $this->doDispatch($forward); } /** - * @param request - * @return AbstractWindRouter + * @return WindUrlBasedRouter */ protected function getHandlerAdapter() { - $routerAlias = $this->windSystemConfig->getRouter(WIND_CONFIG_CLASS); - if (null === $this->getAttribute($routerAlias)) { - /* @var $router AbstractWindRouter */ - $router = $this->windFactory->getInstance($routerAlias); - if (!$router instanceof AbstractWindRouter) { - throw new WindException(get_class($this) . '::getHandlerAdapter()', WindException::ERROR_RETURN_TYPE_ERROR); - } - } - return $this->getAttribute($routerAlias); + return $this->_getHandlerAdapter(); } /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @param string $message - */ - protected function noActionHandlerFound($message) { - $this->response->sendError(WindHttpResponse::SC_NOT_FOUND, $message); - } - - /* (non-PHPdoc) - * @see WindModule::getWriteTableForGetterAndSetter() + * @return WindDispatcher */ - public function getWriteTableForGetterAndSetter() { - return array('dispatcher'); + protected function getDispatcher() { + return $this->_getDispatcher(); } } \ No newline at end of file diff --git a/wind/core/web/controller/IWindController.php b/wind/core/web/controller/IWindController.php new file mode 100644 index 00000000..d0e4cef3 --- /dev/null +++ b/wind/core/web/controller/IWindController.php @@ -0,0 +1,31 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindController { + + /** + * 处理请求并返回Forward对象 + * @param WindUrlBasedRouter $handlerAdapter + * @return WindForward + */ + public function doAction($handlerAdapter); + + /** + * Action预处理方法 + * @param WindUrlBasedRouter $handlerAdapter + * @return + */ + public function preAction($handlerAdapter); + + /** + * Action后处理方法 + * @param WindUrlBasedRouter $handlerAdapter + * @return + */ + public function postAction($handlerAdapter); +} +?> \ No newline at end of file diff --git a/wind/core/web/controller/WindController.php b/wind/core/web/controller/WindController.php new file mode 100644 index 00000000..dadf53bb --- /dev/null +++ b/wind/core/web/controller/WindController.php @@ -0,0 +1,105 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindController extends WindSimpleController { + /** + * 验证类 + * + * @var string + */ + protected $validatorClass = 'WIND:component.utility.WindValidator'; + /** + * 表单类 + * + * @var string + */ + protected $formClass = ''; + + /* (non-PHPdoc) + * @see WindSimpleController::run() + */ + public function run() {} + + /* (non-PHPdoc) + * @see WindSimpleController::preAction() + */ + final public function preAction($handlerAdapter) { + parent::preAction($handlerAdapter); + if ($formClassPath = $this->getFormClass()) { + $this->registerEventListener('doAction', + new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); + } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { + if (!isset($rules['errorMessage'])) { + $rules['errorMessage'] = $this->getErrorMessage(); + } + $this->registerEventListener('doAction', + new WindValidateListener($this->request, $rules, $this->getValidatorClass())); + } + } + + /* (non-PHPdoc) + * @see WindAction::setDefaultTemplateName() + */ + protected function setDefaultTemplateName($handlerAdapter) { + $_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); + $this->setTemplate($_temp); + } + + /* (non-PHPdoc) + * @see WindAction::resolvedActionMethod() + */ + protected function resolvedActionMethod($handlerAdapter) { + $action = $handlerAdapter->getAction(); + if ($action !== 'run') $action = $this->resolvedActionName($action); + try { + if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); + $method = new ReflectionMethod($this, $action); + if ($method->isAbstract() || !$method->isPublic()) throw new WindException( + '[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); + return $action; + } catch (Exception $exception) { + throw new WindException( + '[core.web.WindController.resolvedActionMethod] action method:' . $action . ' exception message:' . + $exception->getMessage()); + } + } + + /** + * 根据请求的Action值返回Action的真正方法名 + * 可以通过覆盖该方法来改变Action的命名规则 + * @param string $action + * @return string + */ + protected function resolvedActionName($action) { + return $action . 'Action'; + } + + /** + * 实现表单验证规则 + * @param string $type + */ + protected function validatorFormRule($type) { + return array(); + } + + /** + * 返回form的类 + * @return string + */ + protected function getFormClass() { + return $this->formClass; + } + + /** + * 返回数据验证类 + * @return string + */ + protected function getValidatorClass() { + return $this->validatorClass; + } +} \ No newline at end of file diff --git a/wind/core/web/WindAction.php b/wind/core/web/controller/WindSimpleController.php similarity index 63% rename from wind/core/web/WindAction.php rename to wind/core/web/controller/WindSimpleController.php index 355abc05..179099e9 100644 --- a/wind/core/web/WindAction.php +++ b/wind/core/web/controller/WindSimpleController.php @@ -1,18 +1,15 @@ 2010-11-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license +/** + * 简单应用控制器 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package */ -Wind::import('WIND:core.WindComponentModule'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class WindAction extends WindComponentModule { +abstract class WindSimpleController extends WindModule implements IWindController { + /** + * @var WindForward + */ protected $forward = null; /** * @var WindUrlHelper @@ -26,34 +23,47 @@ abstract class WindAction extends WindComponentModule { /** * 默认的操作处理方法 */ - public function run() {} + abstract public function run(); /** - * Action操作预处理方法,返回boolean型值 - * @param AbstractWindRouter $handlerAdapter - * @return boolean + * @param WindUrlBasedRouter $handlerAdapter + * @deprecated */ - public function beforeAction($handlerAdapter) {} + protected function beforeAction($handlerAdapter) {} /** - * Action操作后处理方法,在执行完Action后执行 - * @param AbstractWindRouter $handlerAdapter - * @return null + * @param WindUrlBasedRouter $handlerAdapter + * @deprecated */ - public function afterAction($handlerAdapter) {} + protected function afterAction($handlerAdapter) {} - /** - * 根据路由信息重定向执行方法 - * - * @param AbstractWindRouter $handlerAdapter + /* (non-PHPdoc) + * @see IWindController::preAction() + */ + public function preAction($handlerAdapter) { + $this->urlHelper = null; + $this->errorMessage = null; + $this->forward = null; + } + + /* (non-PHPdoc) + * @see IWindController::postAction() + */ + public function postAction($handlerAdapter) {} + + /* (non-PHPdoc) + * @see IWindController::doAction() */ public function doAction($handlerAdapter) { + $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); - $this->resolvedActionMethod($handlerAdapter); + $method = $this->resolvedActionMethod($handlerAdapter); + Wind::log('[core.web.controller.WindSimpleController.doAction] resolved action method:' . $method, + WindLogger::LEVEL_INFO, 'wind.core'); + call_user_func_array(array($this, $method), array()); + $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); - if ($this->getErrorMessage()->getError()) $this->getErrorMessage()->sendError(); - if ($this->request->getIsAjaxRequest()) $this->setLayout(''); - return $this->getForward(); + return $this->forward; } /** @@ -63,13 +73,17 @@ public function doAction($handlerAdapter) { * @param string $controller * @param array $args * @param boolean $isRedirect + * @return */ protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } /** - * 请求重定向到另外一个Url + * 重定向一个请求到另外的URL + * + * @param string $url + * @return */ protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); @@ -77,26 +91,27 @@ protected function forwardRedirect($url) { } /* 数据处理 */ - /** + /** * 设置模板数据 - * - * @param string|array|object $data - * @param string $key + * + * @param string|array|object $data + * @param string $key + * @return */ protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } - /** - * 获得输入数据 - * 如果输入了回调方法则返回数组: - * 第一个值:value + /** + * 获得输入数据 + * 如果输入了回调方法则返回数组: + * 第一个值:value * 第二个值:验证结果 - * - * @param string $name input name - * @param string $type input type (GET POST COOKIE) - * @param string $callback | validation for input - * @return array | string + * + * @param string $name input name + * @param string $type input type (GET POST COOKIE) + * @param string $callback | validation for input + * @return array | string */ protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) @@ -106,44 +121,54 @@ protected function getInput($name, $type = '', $callback = null) { } /* 模板处理 */ - /** + /** * 设置页面模板 - * @param string $template + * + * @param string $template + * @return */ protected function setTemplate($template) { - $this->getForward()->getWindView()->setTemplateName($template); + $this->getForward()->setTemplateName($template); } /** * 设置模板路径 + * * @param string $templatePath + * @return */ protected function setTemplatePath($templatePath) { - $this->getForward()->getWindView()->setTemplatePath($templatePath); + $this->getForward()->setTemplatePath($templatePath); } /** - * 设置模板扩展名称 + * 设置模板文件的扩展名 + * * @param string $templateExt + * @return */ protected function setTemplateExt($templateExt) { - $this->getForward()->getWindView()->setTemplateExt($templateExt); + $this->getForward()->setTemplateExt($templateExt); } - /** + /** * 设置页面布局 - * 可以是一个布局对象或者一个布局文件 + * 可以是一个布局对象或者一个布局文件 + * * @param WindLayout|string $layout + * @return */ protected function setLayout($layout) { - $this->getForward()->getWindView()->setLayout($layout); + $this->getForward()->setLayout($layout); } /* 错误处理 */ /** * 添加错误信息 + * * @param string $message * @param string $key + * @return */ protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); @@ -151,10 +176,12 @@ protected function addMessage($message, $key = '') { /** * 发送一个错误 + * * @param string $message * @param string $key * @param string $errorAction * @param string $errorController + * @return */ protected function showMessage($message = '', $key = '', $errorAction = '', $errorController = '') { $this->addMessage($message, $key); @@ -163,63 +190,26 @@ protected function showMessage($message = '', $key = '', $errorAction = '', $err $this->getErrorMessage()->sendError(); } - /** - * 返回一个错误处理对象 - * @return WindErrorMessage $errorMessage - */ - public function getErrorMessage() { - if ($this->errorMessage === null) { - throw new WindException(__CLASS__ . '::getError(), Actually get a null', WindException::ERROR_RETURN_TYPE_ERROR); - } - return $this->errorMessage; - } - - /** - * 返回UrlHelper对象 - * - * @return WindUrlHelper - */ - protected function getUrlHelper() { - if ($this->urlHelper === null) { - throw new WindException('urlHelper', WindException::ERROR_CLASS_NOT_EXIST); - } - return $this->urlHelper; - } - - /** - * @return WindForward - */ - protected function getForward() { - if ($this->forward === null) { - throw new WindException('windForward', WindException::ERROR_CLASS_NOT_EXIST); - } - return $this->forward; - } - /** * 设置默认的模板名称 - * * @param WindUrlBasedRouter $handlerAdapter + * @return */ - protected function setDefaultTemplateName($handlerAdapter) { - $_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); - $this->setTemplate($_temp); - } + protected function setDefaultTemplateName($handlerAdapter) {} /** - * 获得Action处理方法 - * - * @param AbstractWindRouter $handlerAdapter + * 定义了一种解析策略,使其通过解析请求信息来获得调用的方法。 + * @param WindUrlBasedRouter $handlerAdapter + * @return */ protected function resolvedActionMethod($handlerAdapter) { - call_user_func_array(array($this, 'run'), array()); + return 'run'; } /** - * Enter description here ... - * - * @param unknown_type $name - * @param unknown_type $type + * @param string $name + * @param string $type + * @param array $callback * @return Ambigous */ private function getInputWithString($name, $type = '', $callback = array()) { @@ -244,9 +234,7 @@ private function getInputWithString($name, $type = '', $callback = array()) { } /** - * Enter description here ... - * - * @param string $name + * @param array $name * @param string $type * @return array */ @@ -258,10 +246,26 @@ private function getInputWithArray($name, $type = '') { return $result; } - /* (non-PHPdoc) - * @see WindModule::getWriteTableForGetterAndSetter() + /** + * @return WindForward */ - protected function getWriteTableForGetterAndSetter() { - return array('forward', 'urlHelper', 'errorMessage'); + protected function getForward() { + return $this->_getForward(); } -} \ No newline at end of file + + /** + * @return WindUrlHelper + */ + protected function getUrlHelper() { + return $this->_getUrlHelper(); + } + + /** + * @return WindErrorMessage + */ + protected function getErrorMessage() { + return $this->_getErrorMessage(); + } + +} +?> \ No newline at end of file From cdced44f461a0e272c101baa44cbf7f9a21c8da2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 06:52:42 +0000 Subject: [PATCH 0104/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2162 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/wind_basic.php | 1 + 1 file changed, 1 insertion(+) create mode 100644 wind/wind_basic.php diff --git a/wind/wind_basic.php b/wind/wind_basic.php new file mode 100644 index 00000000..b4ed2e91 --- /dev/null +++ b/wind/wind_basic.php @@ -0,0 +1 @@ +buildCacheFilePath($append) : $this->buildCacheFilePath($alias)); if ($alias) { $config = $this->getCacheContent($cacheFileName); if (isset($config[$alias]) && !$this->needCompiled()) { return $config[$alias]; } } if (!($configPath = trim($configPath))) throw new WindException('Please input the file path!'); $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); if (!$alias) return $result; $config[$alias] = $result; $this->saveConfigFile($cacheFileName, $config); return $result; } private function getCacheContent($file) { $content = array(); if (is_file($file)) $content = include ($file); return is_array($content) ? $content : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('init config parser error.'); break; } } private function doParser($configFile, $type) { if (!$configFile) return array(); if (!is_file($configFile)) throw new WindException('The file <' . $configFile . '> is not exists'); if ($type == 'PHP') { $config = include ($configFile); return (isset($config['wind'])) ? $config['wind'] : $config; } if (!isset($this->configParsers[$type])) { $this->configParsers[$type] = $this->createParser($type); } return $this->configParsers[$type]->parse($configFile); } private function needCompiled() { if (IS_DEBUG && is_dir(COMPILE_PATH)) return true; return false; } private function getConfigFormat($configPath) { if ($configPath === '') return self::CONFIG_XML; $format = strtoupper(trim(strrchr($configPath, '.'), '.')); if (!in_array($format, $this->getConfigFormatList())) { throw new WindException("The format of the config file doesn't sopported yet!"); } return $format; } private function saveConfigFile($filename, $data) { if (!$filename || !$data || !is_dir(COMPILE_PATH)) return false; Wind::import('COM:utility.WindFile'); return WindFile::savePhpData($filename, $data); } private function buildCacheFilePath($fileName) { return rtrim(COMPILE_PATH, '/') . D_S . strtolower($fileName) . '.php'; } private function getConfigFormatList() { return array( self::CONFIG_XML, self::CONFIG_PHP, self::CONFIG_INI, self::CONFIG_PROPERTIES); } public function __destruct() { $this->configParser = array(); } } class WindConfig { protected $configParser = null; protected $cacheName; protected $append; protected $config = array(); public function __construct($config, $configParser = null, $cacheName = '', $append = false) { $this->setConfigParser($configParser); $this->setCacheName($cacheName); $this->setAppend($append); $this->initConfig($config); } public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { if (!$config) $config = $this->config; if ($configName === '') return $config; $_config = $default; if (isset($config[$configName])) { $_config = $config[$configName]; } if ($subConfigName === '') return $_config; $_subConfig = $default; if (is_array($_config) && isset($_config[$subConfigName])) { $_subConfig = $_config[$subConfigName]; } return $_subConfig; } protected function initConfig($config) { if (!$config) return; if (!is_array($config)) { $config = $this->parseConfig($config, $this->getCacheName(), $this->getAppend()); } $this->setConfig($config); } protected function parseConfig($config, $cacheName, $append) { if ($this->getConfigParser() === null) { throw new WindException('configParser is null.'); } return $this->getConfigParser()->parse($config, $cacheName, $append); } public function setConfig($config, $merage = false) { if (!is_array($config)) throw new WindException('config error.'); if ($merage) $this->config = array_merge($this->config, $config); else $this->config = $config; } public function getConfigParser() { return $this->configParser; } public function setConfigParser($configParser) { if ($this->configParser || $configParser == null) return; $this->configParser = $configParser; } public function getCacheName() { return $this->cacheName; } public function getAppend() { return $this->append; } public function setCacheName($cacheName) { $this->cacheName = $cacheName; } public function setAppend($append) { $this->append = $append; } } Wind::import('WIND:core.config.WindConfig'); class WindSystemConfig extends WindConfig { const CLASS_PATH = 'class'; const PATH = 'path'; const VALUE = 'value'; const IMPORTS = 'imports'; const IMPORTS_RESOURCE = 'resource'; const IMPORTS_IS_APPEND = 'is-append'; const WEB_APPS = 'web-apps'; const WEB_APP_ROOT_PATH = 'root-path'; const WEB_APP_FACTORY = 'factory'; const WEB_APP_FACTORY_CLASS_DEFINITION = 'class-definition'; const WEB_APP_FILTER = 'filters'; const WEB_APP_ROUTER = 'router'; const WEB_APP_MODULE = 'modules'; const WEB_APP_TEMPLATE = 'template'; protected $appName = ''; protected $imports = array(); public function __construct($config, $configParser, $appName) { $cacheName = $appName . '_config'; $this->appName = $appName; parent::__construct($config, $configParser, $cacheName); } public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { $imports = parent::getConfig(self::IMPORTS); if (key_exists($configName, (array) $imports)) { return $this->parseImport($configName); } return parent::getConfig($configName, $subConfigName, $config, $default); } public function getAppName() { return $this->appName; } public function getAppClass() { $_config = $this->getConfig(self::WEB_APPS, $this->appName); $_tmp = $this->getConfig(self::CLASS_PATH, '', $_config); return $_tmp ? $_tmp : COMPONENT_WEBAPP; } public function getRootPath($appName = '') { if ($appName === '') $appName = $this->appName; $_tmp = $appName . '_RootPath'; if (!isset($this->$_tmp)) { $appConfig = $this->getConfig(self::WEB_APPS, $appName); if (isset($appConfig[self::WEB_APP_ROOT_PATH]) && !empty($appConfig[self::WEB_APP_ROOT_PATH])) $rootPath = $appConfig[self::WEB_APP_ROOT_PATH]; else $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); $this->$_tmp = $rootPath; } return $this->$_tmp; } public function getFactory($name = '') { $_config = $this->getConfig(self::WEB_APPS, $this->appName); return $this->getConfig(self::WEB_APP_FACTORY, $name, $_config); } public function getFilterClass() { return $this->getFilters(self::CLASS_PATH); } public function getFilters($name = '') { $_config = $this->getConfig(self::WEB_APPS, $this->appName); return $this->getConfig(self::WEB_APP_FILTER, $name, $_config); } public function getRouterClass() { return $this->getRouter(WIND_CONFIG_CLASS); } public function getRouter($name = '') { $_config = $this->getConfig(self::WEB_APPS, $this->appName); $_router = $this->getConfig(self::WEB_APP_ROUTER, $name, $_config); return $_router ? $_router : COMPONENT_ROUTER; } public function getModules($name = '') { $_config = $this->getConfig(self::WEB_APPS, $this->appName); return $this->getConfig(self::WEB_APP_MODULE, $name, $_config); } public function getModuleViewClassByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig('view', WIND_CONFIG_CLASS, $module, $default); } public function getModuleViewConfigByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig('view', WIND_CONFIG_CONFIG, $module, $default); } public function getModuleErrorHandlerByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig('error-handler', WIND_CONFIG_CLASS, $module, $default); } public function getModuleControllerPathByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig(WIND_CONFIG_CLASSPATH, '', $module, $default); } public function getModuleControllerSuffixByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig('controller-suffix', WIND_CONFIG_VALUE, $module, $default); } public function getTemplate($name = '') { return $this->getConfig(self::TEMPLATE, $name); } public function getViewerResolvers($name = '') { return $this->getConfig(self::VIEWER_RESOLVERS, $name); } public function getApplications($name = '') { return $this->getConfig(self::APPLICATIONS, $name); } public function getErrorMessage($name = '') { return $this->getConfig(self::ERROR, $name); } protected function parseImport($name) { if (!isset($this->imports[$name])) { $imports = $this->getConfig(self::IMPORTS); if (!isset($imports[$name])) return array(); $import = $imports[$name]; $config = array(); if (is_array($import) && !empty($import)) { $configPath = Wind::getRealPath($import[self::IMPORTS_RESOURCE]); if (!isset($import[self::IMPORTS_IS_APPEND]) || $import[self::IMPORTS_IS_APPEND] === 'true') { $append = $this->cacheName; } elseif ($import[self::IMPORTS_IS_APPEND] === 'false' || $import[self::IMPORTS_IS_APPEND] === '') { $append = false; } else { $append = $import[self::IMPORTS_IS_APPEND]; } $cacheName = $append ? $name : $this->appName . '_' . $name . '_config'; $config = $this->parseConfig($configPath, $cacheName, $append); } $this->imports[$name] = $config; } return $this->imports[$name]; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } Wind::import('WIND:core.exception.WindException'); class WindActionException extends WindException { private $error; public function __construct($error) { $this->setError($error); parent::__construct(''); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } Wind::import('WIND:core.exception.WindException'); class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } interface IWindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; public function _getReflection(); public function _getInstance(); public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD); } class WindClassProxy implements IWindClassProxy { private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObj = null, $args = array()) { $this->initClassProxy($targetObj, $args); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } protected function initClassProxy($targetObject, $args = array()) { try { if (is_object($targetObject)) { $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; } elseif (is_string($targetObject) && !empty($targetObject)) { $_className = Wind::import($targetObject); $this->_setClassName($_className); } else throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) { $this->_listener[$type] = array(); } $reflection = new ReflectionClass($this->_className); if ($reflection->isAbstract() || $reflection->isInterface()) { throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); } $this->_reflection = $reflection; if ($this->_instance !== null) return; $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); } catch (Exception $e) { Wind::log( '[core.factory.proxy.WindClassProxy.initClassProxy] Initialization proxy failed.' . $e->getMessage(), WindLogger::LEVEL_DEBUG, 'wind.core'); } } private function _getInterceptorChain($event = '') { $interceptorChain = WindFactory::createInstance($this->_interceptorChain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $interceptorChain->setAttribute($this->_getAttribute()); $interceptorChain->setAttribute('instance', $this->_getInstance()); $interceptorChain->setAttribute('event', array($this->_getClassName(), $event)); return $interceptorChain; } else throw new WindException('unable to create interceptorChain.'); } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getReflection() { if ($this->_reflection instanceof ReflectionClass) return $this->_reflection; else throw new WindException(get_class($this) . '->_reflection, ' . gettype($this->_reflection), WindException::ERROR_CLASS_TYPE_ERROR); } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; return true; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } public function _getAttribute($alias = '') { if ($alias === '') return $this->_attributes; else return isset($this->_attributes[$alias]) ? $this->_attributes[$alias] : null; } public function _setAttribute($alias, $object = null) { if (is_array($alias)) $this->_attributes += $alias; elseif (is_string($alias)) $this->_attributes[$alias] = $object; } } class WindClassDefinition { const NAME = 'name'; const PATH = 'path'; const FACTORY_METHOD = 'factory-method'; const INIT_METHOD = 'init-method'; const SCOPE = 'scope'; const PROPERTIES = 'properties'; const CONSTRUCTOR_ARG = 'constructor-arg'; const REF = 'ref'; const VALUE = 'value'; const DELAY = 'delay'; const PROXY = 'proxy'; const CONFIG = 'config'; const RESOURCE = 'resource'; const SCOPE_SINGLETON = 'singleton'; const SCOPE_PROTOTYPE = 'prototype'; const SCOPE_REQUEST = 'request'; protected $proxyClass = 'WIND:core.factory.proxy.WindClassProxy'; protected $config; protected $proxy; protected $className; protected $alias; protected $path; protected $scope; protected $factoryMethod; protected $initMethod; protected $constructArgs = array(); protected $properties = array(); protected $classDefinition; private $instance = null; public function __construct($classDefinition = array()) { $this->init($classDefinition); } public function getInstance($factory, $args = array()) { if ($instance = $this->executeFactoryMethod($args)) return $instance; switch ($this->scope) { case 'prototype': return $this->createInstanceWithPrototype($factory, $args); default: return $this->createInstanceWithSingleton($factory, $args); } } protected function createInstanceWithPrototype($factory, $args) { return $this->createInstance($factory, $args); } protected function createInstanceWithSingleton($factory, $args) { $_instance = $this->createInstance($factory, $args); $factory->setSingled($this->getAlias(), $_instance); return $_instance; } protected function createInstance($factory, $args) { $args = $this->buildConstructArgs($factory, $args); $instance = $factory->createInstance($this->getClassName(), $args); if ($instance instanceof WindModule) { $this->buildConfig($instance, $factory); $this->buildProperties($instance, $factory); $this->executeInitMethod($instance); $this->setHiddenProperty($instance, $factory); $instance = $this->setProxyForClass($instance, $factory); } return $instance; } protected function buildConfig($instance, $factory) { if (!$config = $this->getConfig()) return; if (isset($config[self::RESOURCE])) { $config = $config[self::RESOURCE]; } $instance->setConfig($config); } protected function setHiddenProperty($instance, $factory) { $instance->systemConfig = Wind::getApp()->getWindSystemConfig(); $instance->request = Wind::getApp()->getRequest(); $instance->response = Wind::getApp()->getResponse(); $instance->systemFactory = $factory; } protected function setProxyForClass($instance, $factory) { if (!($proxy = $this->getProxy()) || $proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyClass; $proxy = $factory->createInstance($proxy, array($instance)); if ($proxy !== null) return $proxy; Wind::log( '[core.factory.WindClassDefinition.setProxyForClass] create proxy for ' . $this->getClassName() . ' fail.', WindLogger::LEVEL_DEBUG, 'wind.core'); throw new WindException( '[core.factory.WindClassDefinition.setProxyForClass] create proxy for ' . $this->getClassName() . ' fail.', WindException::ERROR_SYSTEM_ERROR); } private function executeInitMethod($instance) { try { if (!($initMethod = $this->getInitMethod())) return; return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindClassDefinition.executeInitMethod] (' . $this->getClassName() . '->' . $initMethod . '()) "' . $e->getMessage() . '"', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function buildConstructArgs($factory, $args) { if ($args) return $args; $subDefinitions = $this->getConstructArgs(); $_tmp = array(); foreach ($subDefinitions as $key => $subDefinition) { if (isset($subDefinition[self::VALUE])) { $_tmp[$key] = $subDefinition[self::VALUE]; } elseif (isset($subDefinition[self::REF])) $_tmp[$key] = $factory->getInstance($subDefinition[self::REF]); } return $_tmp; } protected function buildProperties($instance, $factory) { if (!$subDefinitions = $this->getPropertys()) return; foreach ($subDefinitions as $key => $subDefinition) { $_value = ''; if (isset($subDefinition[self::VALUE])) $_value = $subDefinition[self::VALUE]; if ($_value) { $_setter = 'set' . ucfirst(trim($key, '_')); call_user_func_array(array($instance, $_setter), array($_value)); } } $instance->setDelayAttributes($subDefinitions); } protected function executeFactoryMethod($args) { try { if (!($factoryMethod = $this->getFactoryMethod())) return null; return call_user_func_array(array($this->getClassName(), $factoryMethod), $args); } catch (Exception $e) { throw new WindException( '[core.factory.WindClassDefinition.executeFactoryMethod] (' . $this->getClassName() . '->' . $factoryMethod . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function init($classDefinition) { try { if (empty($classDefinition)) return; foreach ($classDefinition as $key => $value) { if (strpos($key, '-') !== false) { list($_s1, $_s2) = explode('-', $key); $_s1 = ucfirst($_s1); $_s2 = ucfirst($_s2); $_setter = 'set' . $_s1 . $_s2; } else $_setter = 'set' . ucfirst($key); call_user_func_array(array($this, $_setter), array($value)); } $this->setClassDefinition($classDefinition); } catch (Exception $e) { throw new WindException("[core.factory.WindClassDefinition.init]" . $e->getMessage(), WindException::ERROR_SYSTEM_ERROR); } } public function getClassName() { if (!$this->className) { $this->className = Wind::import($this->getPath()); } return $this->className; } public function getAlias() { return $this->alias; } public function getPath() { return $this->path; } public function getScope() { return $this->scope; } public function setClassName($className) { $this->className = $className; } public function setAlias($alias) { $this->alias = $alias; } public function setPath($path) { $this->path = $path; } public function setScope($scope) { $this->scope = strtolower($scope); } public function getConstructArgs() { return $this->constructArgs; } public function getPropertys() { return $this->properties; } public function getClassDefinition() { return $this->classDefinition; } public function setConstructArgs($constructArgs) { if (is_array($constructArgs) && !empty($constructArgs)) $this->constructArgs += $constructArgs; } public function setProperties($properties) { if (!is_array($properties)) return; $this->properties = array_merge($this->properties, $properties); } public function setClassDefinition($classDefinition) { $this->classDefinition = $classDefinition; } public function getFactoryMethod() { return $this->factoryMethod; } public function getInitMethod() { return $this->initMethod; } public function setFactoryMethod($factoryMethod) { $this->factoryMethod = $factoryMethod; } public function setInitMethod($initMethod) { $this->initMethod = $initMethod; } public function getProxy() { return $this->proxy; } public function setProxy($proxy) { $this->proxy = $proxy; } public function getConfig() { return $this->config; } public function setConfig($config) { $this->config = $config; } } class WindFactory implements IWindFactory { protected $classDefinitionType = 'WIND:core.factory.WindClassDefinition'; protected $classDefinitions = array(); protected $instances = array(); public function __construct($classDefinitions = array()) { $this->loadClassDefinitions($classDefinitions); } public function getInstance($alias) { if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!$classDefinition = $this->getClassDefinitionByAlias($alias)) return null; $args = func_get_args(); unset($args[0]); return $classDefinition->getInstance($this, $args); } public function getPrototype($alias) { $instance = $this->getInstance($alias); if ($instance === null) return null; return clone $instance; } static public function createInstance($className, $args = array()) { try { if (!$className) return null; if (strpos($className, ':') !== false) $className = Wind::import($className); $reflection = new ReflectionClass($className); if ($reflection->isAbstract() || $reflection->isInterface()) return null; Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_INFO, 'core.factory'); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function setSingled($classAlias, $instance) { Wind::log('[core.factory.WindFactory.createInstance] create singled instance:' . $classAlias, WindLogger::LEVEL_INFO, 'core.factory'); $this->instances[$classAlias] = $instance; } protected function getClassDefinitionByAlias($classAlias) { if (!($definition = $this->classDefinitions[$classAlias])) return null; if ($definition instanceof WindClassDefinition) return $definition; $classDefinition = self::createInstance($this->classDefinitionType, array($definition)); $classDefinition->setAlias($classAlias); $this->addClassDefinitions($classDefinition); return $classDefinition; } public function addClassDefinitions($classDefinition) { if ($classDefinition instanceof WindClassDefinition) { $alias = $classDefinition->getAlias(); $this->classDefinitions[$alias] = $classDefinition; } elseif (is_array($classDefinition)) { foreach ($classDefinition as $value) $this->addClassDefinitions($value); } } public function checkAlias($alias) { return isset($this->classDefinitions[$alias]); } protected function loadClassDefinitions($classDefinitions) { if (is_array($classDefinitions)) $this->classDefinitions = $classDefinitions; else throw new WindException('[core.factory.WindFactory.loadClassDefinitions]', WindException::ERROR_PARAMETER_TYPE_ERROR); } } Wind::import('COM:utility.WindUtility'); class WindModule { private $_config = null; private $_array = array(); protected $_typeValidation = false; private $delayAttributes = array(); public function __set($propertyName, $value) { if (!$this->validatePropertyName($propertyName)) { $_setter = 'set' . ucfirst($propertyName); if (method_exists($this, $_setter)) $this->$_setter($value); else Wind::log('[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } else $this->$propertyName = $value; } public function __get($propertyName) { if (!$this->validatePropertyName($propertyName)) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); else Wind::log('[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } else return $this->$propertyName; } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_set') { $this->$_propertyName = $args[0]; } elseif ($_prefix == '_get') { if (property_exists($this, $_propertyName) && $this->$_propertyName) { return $this->$_propertyName; } if (isset($this->delayAttributes[$_propertyName])) { $_instance = null; $_property = $this->delayAttributes[$_propertyName]; if (isset($_property[WindClassDefinition::REF])) { $_ref = $_property[WindClassDefinition::REF]; if ($this->getSystemFactory()->checkAlias($_ref)) $_instance = $this->getSystemFactory()->getInstance($_ref); else $_instance = $this->getSystemFactory()->createInstance($_ref); } $this->$_propertyName = $_instance; Wind::log("[core.WindMOdule.__call] create property $_propertyName fail.", WindLogger::LEVEL_DEBUG, 'wind.core'); } Wind::log("[core.WindModule.__call] attribute is not exist. (" . $methodName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return $this->$_propertyName; } throw new WindException('[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) { Wind::log( "[core.WindModule.__clone] unexcepted value type or the property is not setted.(" . $value . ") need an object type in here. ", WindLogger::LEVEL_DEBUG, 'wind.core'); continue; } $this->$value = clone $this->$value; } } public function toArray() { if (empty($this->_array)) { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } $this->_array = $_result; } return $this->_array; } protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { Wind::log('[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } if (!($_writeTableProperties = $this->writeTableForProperty())) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { if ($value instanceof $_writeTableProperties[$propertyName]) return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. ", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } return true; } public function getConfig($configName = '', $subConfigName = '', $default = '') { if ($this->_config === null) { Wind::log('[core.WindModule.getConfig] config is not exist.', WindLogger::LEVEL_INFO, 'wind.core'); return $default; } return $this->_config->getConfig($configName, $subConfigName, array(), $default); } public function setConfig($config) { if (!$config) return; if (is_string($config)) { Wind::import('WIND:core.config.parser.WindConfigParser'); $config = new WindConfig($config, new WindConfigParser(), get_class($this), WIND_CONFIG_CACHE); } elseif (is_array($config)) $config = new WindConfig($config); if ($this->_config !== null) $this->_config->setConfig($config->getConfig(), true); else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemConfig() { return Wind::getApp()->getWindSystemConfig(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('WIND:core.filter.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); private $_state = true; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException('[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if ($this->_state) { $this->addInterceptors(new WindHandlerInterceptor()); $this->_state = false; } if (count($this->_interceptors) <= 0) return null; $handler = array_shift($this->_interceptors); if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } Wind::log( '[core.filter.WindHandlerInterceptorChain.getHandler] the type of Interceptor ' . gettype($handler) . ' is not supported.', WindLogger::LEVEL_DEBUG, 'wind.core'); return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } } Wind::import('WIND:core.filter.WindHandlerInterceptorChain'); class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes($data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse() { if ($this->_response === null) { Wind::import('WIND:core.response.WindHttpResponse'); $this->_response = new WindHttpResponse(); if ($this->getIsAjaxRequest()) { $this->_response->addHeader('Content-type', 'text/xml;charset=utf-8'); $this->_response->setIsAjax(true); } else $this->_response->addHeader('Content-type', 'text/html;charset=utf-8'); } return $this->_response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace( '/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException( __CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(''); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('WIND:core.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_isAjax = false; private $_data = array(); const SC_CONTINUE = 100; const SC_SWITCHING_PROTOCOLS = 101; const SC_OK = 200; const SC_CREATED = 201; const SC_ACCEPTED = 202; const SC_NON_AUTHORITATIVE_INFORMATION = 203; const SC_NO_CONTENT = 204; const SC_RESET_CONTENT = 205; const SC_PARTIAL_CONTENT = 206; const SC_MULTIPLE_CHOICES = 300; const SC_MOVED_PERMANENTLY = 301; const SC_MOVED_TEMPORARILY = 302; const SC_FOUND = 302; const SC_SEE_OTHER = 303; const SC_NOT_MODIFIED = 304; const SC_USE_PROXY = 305; const SC_TEMPORARY_REDIRECT = 307; const SC_BAD_REQUEST = 400; const SC_UNAUTHORIZED = 401; const SC_PAYMENT_REQUIRED = 402; const SC_FORBIDDEN = 403; const SC_NOT_FOUND = 404; const SC_METHOD_NOT_ALLOWED = 405; const SC_NOT_ACCEPTABLE = 406; const SC_PROXY_AUTHENTICATION_REQUIRED = 407; const SC_REQUEST_TIMEOUT = 408; const SC_CONFLICT = 409; const SC_GONE = 410; const SC_LENGTH_REQUIRED = 411; const SC_PRECONDITION_FAILED = 412; const SC_REQUEST_ENTITY_TOO_LARGE = 413; const SC_REQUEST_URI_TOO_LONG = 414; const SC_UNSUPPORTED_MEDIA_TYPE = 415; const SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const SC_EXPECTATION_FAILED = 417; const SC_INTERNAL_SERVER_ERROR = 500; const SC_NOT_IMPLEMENTED = 501; const SC_BAD_GATEWAY = 502; const SC_SERVICE_UNAVAILABLE = 503; const SC_GATEWAY_TIMEOUT = 504; const SC_HTTP_VERSION_NOT_SUPPORTED = 505; public function setHeader($name, $value, $replace = false) { if (trim($name) == '' || trim($value) == '') return; $name = $this->_normalizeHeader($name); foreach ($this->_headers as $key => $one) { ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); } } public function addHeader($name, $value, $replace = false) { if (trim($name) == '' || trim($value) == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function setStatus($status, $message = '') { if (!is_int($status) || $status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_unshift($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::SC_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message); $this->setStatus($status); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } header('HTTP/1.1 ' . $this->_status); } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { if (trim($name) == '') return ''; $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getIsAjax() { return $this->_isAjax; } public function setIsAjax($_isAjax) { $this->_isAjax = $_isAjax; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '') { if ($key) { $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_data += $data; } } abstract class AbstractWindRouter extends WindModule { const DEFAULT_ERROR_HANDLER = 'WIND:core.web.WindErrorHandler'; const CONTROLLER_DEFAULT_PATH = 'controller'; const CONTROLLER_DEFAULT_SUFFIX = 'Controller'; private $action = 'run'; private $controller = 'index'; private $module = 'default'; protected $modulePath = ''; private $reParse = true; abstract public function parse(); abstract public function buildUrl(); public function doParse() { $_moduleName = $this->getModule(); if (!strcasecmp($this->getController(), WIND_M_ERROR)) { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( '[core.roter.AbstractWindRouter.doParse] action hander: default error action :' . self::DEFAULT_ERROR_HANDLER, WindLogger::LEVEL_DEBUG, 'wind.core'); } return $this->getSystemConfig()->getModuleErrorHandlerByModuleName($_moduleName, self::DEFAULT_ERROR_HANDLER); } if ($this->reParse) { $this->parse(); $this->reParse = false; Wind::log('[core.router.AbstractWindRouter.doParse] parse the request.', WindLogger::LEVEL_DEBUG, 'wind.core'); } $_suffix = $this->getSystemConfig()->getModuleControllerSuffixByModuleName($_moduleName, self::CONTROLLER_DEFAULT_SUFFIX); if ($this->modulePath) $_path = $this->modulePath; else { $_path = $this->getSystemConfig()->getModuleControllerPathByModuleName($_moduleName, self::CONTROLLER_DEFAULT_PATH); } $_path .= '.' . ucfirst($this->controller) . $_suffix; if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.router.AbstractWindRouter.doParse] action handler: ' . $_path, WindLogger::LEVEL_DEBUG, 'wind.core'); } $this->destroy(); return $_path; } protected function destroy() { $this->modulePath = ''; } public function setModule($module) { if (false !== ($pos = strpos($module, ':'))) { $this->modulePath = $module; } else { $this->module = $module; $this->modulePath = ''; } } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getModule() { return $this->module; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function reParse() { $this->reParse = true; } } class WindUrlBasedRouter extends AbstractWindRouter { const URL_PARAM = 'url-param'; const DEFAULT_VALUE = 'default-value'; const CONTROLLER_SUFFIX = 'controller-suffix'; const ACTION_SUFFIX = 'action-suffix'; const URL_RULE_MODULE = 'module'; const URL_RULE_CONTROLLER = 'controller'; const URL_RULE_ACTION = 'action'; public function parse() { $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->getModule())); $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->getController())); $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->getAction())); } public function buildUrl() { $module = $this->getUrlParamValue(self::URL_RULE_MODULE); $controller = $this->getUrlParamValue(self::URL_RULE_CONTROLLER); $action = $this->getUrlParamValue(self::URL_RULE_ACTION); $url = '?' . $module . '=' . $this->getModule(); $url .= '&' . $controller . '=' . $this->getController(); $url .= '&' . $action . '=' . $this->getAction(); return $url; } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, self::URL_PARAM)) { $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE, $defaultValue); return $this->getRequest()->getRequest($_param, $defaultValue); } return $defaultValue; } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $urlHelper = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); Wind::log('[core.web.controller.WindSimpleController.doAction] resolved action method:' . $method, WindLogger::LEVEL_INFO, 'wind.core'); call_user_func_array(array($this, $method), array()); $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '', $errorController = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->setErrorController($errorController); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getUrlHelper() { return $this->_getUrlHelper(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; public function run() {} final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } } protected function setDefaultTemplateName($handlerAdapter) { $_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); $this->setTemplate($_temp); } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); try { if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) throw new WindException( '[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); return $action; } catch (Exception $exception) { throw new WindException( '[core.web.WindController.resolvedActionMethod] action method:' . $action . ' exception message:' . $exception->getMessage()); } } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('WIND:core.filter.WindFilter'); class WindLoggerFilter extends WindFilter { public function preHandle($request = null, $response = null) { if (!IS_DEBUG) return; $this->initWindLogger($request); $this->logger->info('-------------------------------request start!!!!--------------------------------'); } public function postHandle($request = null, $response = null) { if (!IS_DEBUG) return; $this->logger->info('---------------------------------request end!!!!---------------------------------'); if ($this->logger instanceof WindLogger) $this->logger->flush(); } private function initWindLogger($request) { $windFactory = $request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $windFactory->getInstance(COMPONENT_LOGGER); } } Wind::import('WIND:core.filter.WindFilter'); class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { $windFactory = $request->getAttribute(WindFrontController::WIND_FACTORY); $this->urlHelper = $windFactory->getInstance(COMPONENT_URLHELPER); $this->urlHelper->parseUrl(); } public function postHandle($request = null, $response = null) { } } interface IWindApplication { public function processRequest(); public function doDispatch($forward); } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } Wind::import('WIND:core.filter.WindHandlerInterceptor'); class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException('the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet($_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('WIND:core.filter.WindHandlerInterceptor'); Wind::import('WIND:component.log.WindLogger'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim($trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('WIND:core.filter.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost($key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError(($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); Wind::import('WIND:core.factory.WindFactory'); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $urlHelper = null; protected $display = false; public function dispatch($app, $forward, $router) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($app, $forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($app, $forward, $router); else $this->render($app, $forward, $router); $this->destroy(); } protected function dispatchWithRedirect($app, $forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindException('[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request ', WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($app, $forward, $router) { $this->getRequest()->setAttribute($forward->getVars(), $router->getAction() . '_' . $router->getController()); $this->setDisplay($forward->getDisplay()); list($_c, $_m) = WindHelper::resolveController($forward->getController()); $_a = $forward->getAction(); $_a && $router->setAction($_a); $_c && $router->setController($_c); $_m && $router->setModule($_m); if (!$this->checkProcess($router)) { throw new WindException('[core.web.WindDispatcher.dispatchWithAction] Duplicate request ', WindException::ERROR_SYSTEM_ERROR); } $app->processRequest(); } protected function render($app, $forward, $router) { try { if ($windViewClass = $forward->getWindView()) $view = $this->getSystemFactory()->createInstance($windViewClass); elseif ($windViewClass = $this->getSystemConfig()->getModuleViewClassByModuleName($router->getModule())) $view = $this->getSystemFactory()->getInstance($windViewClass); else $view = $this->getSystemFactory()->getInstance(COMPONENT_VIEW); $view->setConfig($this->getSystemConfig()->getModuleViewConfigByModuleName($router->getModule())); $view->render($forward, $router, $this->getDisplay()); } catch (Exception $e) { throw new WindViewException('[core.web.WindDispatcher.render] view render fail.' . $e->getMessage()); } } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === $this->processCache['action'] && $router->getController() === $this->processCache['controller'] && $router->getModule() === $this->processCache['module']) return false; return true; } protected function destroy() { $this->processCache = array(); $this->setDisplay(false); } public function getDisplay() { return $this->display; } public function setDisplay($display) { $this->display = $display; } public function getUrlHelper() { return $this->_getUrlHelper(); } public function setUrlHelper($urlHelper) { $this->urlHelper = $urlHelper; } } class WindErrorHandler extends WindController { protected $error = array(); protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->request->getUrlReferer(); else $this->urlReferer = $this->request->getBaseUrl(); return true; } public function run() { $_tmp = "User Message:\r\n"; $i = 0; foreach ($this->error as $key => $value) { $i++; $_tmp .= "#$i " . $value . "\r\n"; } echo "

User Message: (" . count($this->error) . ")

"; echo "

" . nl2br($_tmp) . "

"; echo "Click to go back."; Wind::log('User Error:', $_tmp); exit(); } final public function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { $errfile = $this->getFile($errfile); $_tmp = "$errstr ($errfile:$errline)\r\nStack trace:\r\n"; $_trace = debug_backtrace(); foreach ($_trace as $key => $value) { if (!isset($value['file'])) continue; if (!isset($value['line'])) $value['line'] = 0; if (!isset($value['function'])) continue; $_tmp .= "#$key {$value['file']}({$value['line']}): "; if (isset($value['object']) && is_object($value['object'])) $_tmp .= get_class($value['object']) . '->'; $_tmp .= "{$value['function']}()\r\n"; } if (IS_DEBUG) { echo "

" . $this->errnoMap($errno) . " $errstr

"; echo "

" . nl2br($_tmp) . "

"; } else echo "

" . $this->errnoMap($errno) . " $errstr

"; Wind::log($this->errnoMap($errno) . $errstr, $_tmp); exit(); } } private function errnoMap($errno) { $_tmp = ''; switch ($errno) { case E_ERROR: $_tmp = "Error"; break; case E_WARNING: $_tmp = "Warning"; break; case E_PARSE: $_tmp = "Parse Error"; break; case E_NOTICE: $_tmp = "Notice"; break; case E_CORE_ERROR: $_tmp = "Core Error"; break; case E_CORE_WARNING: $_tmp = "Core Warning"; break; case E_COMPILE_ERROR: $_tmp = "Compile Error"; break; case E_COMPILE_WARNING: $_tmp = "Compile Warning"; break; case E_USER_ERROR: $_tmp = "User Error"; break; case E_USER_WARNING: $_tmp = "User Warning"; break; case E_USER_NOTICE: $_tmp = "User Notice"; break; case E_STRICT: $_tmp = "Strict Notice"; break; case E_RECOVERABLE_ERROR: $_tmp = "Recoverable Error"; break; default: $_tmp = "Unknown error ($errno)"; break; } return $_tmp; } final public function exceptionHandle($exception) { $_tmp = $exception->getMessage() . ' (' . $this->getFile($exception->getFile()) . ':' . $exception->getLine() . ')'; if (IS_DEBUG) { echo '

' . get_class($exception) . '

'; echo "

$_tmp

"; echo '
' . $exception->getTraceAsString() . '
'; } else { echo '

' . get_class($exception) . '

'; echo '

' . $exception->getMessage() . '

'; } Wind::log("$_tmp:" . $exception->getTraceAsString()); exit(); } private function getFile($filePath) { return $filePath; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction = 'run'; private $errorController = WIND_M_ERROR; public function __construct($message = '', $errorAction = '', $errorController = '') { $this->addError($message); $this->setErrorAction($errorAction); $this->setErrorController($errorController); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; else return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if (!$error) return; if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function getErrorController() { return $this->errorController; } public function setErrorAction($errorAction) { if ($errorAction) $this->errorAction = $errorAction; } public function setErrorController($errorController) { if ($errorController) $this->errorController = $errorController; } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath; private $templateExt; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; private $display = false; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } public function getDisplay() { return $this->display; } public function setDisplay($display) { $this->display = $display; } } class WindFrontController { const WIND_SYSTEM_CONFIG = 'WIND:core.config.WindSystemConfig'; const WIND_SYSTEM_FACTORY = 'WIND:core.factory.WindFactory'; const WIND_COMPONENT_CONFIG_RESOURCE = 'WIND:components_config.php'; private $request; private $response; protected $windSystemConfig = null; protected $windFactory = null; public function __construct($appName, $config = '') { try { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(); $this->initWindConfig($appName, $config); $this->initWindFactory(); } catch (Exception $exception) { throw new Exception('System failed to initialize.' . $exception->getMessage()); } } public function run() { $this->beforeProcess(); $appName = $this->windSystemConfig->getAppClass(); $application = $this->windFactory->getInstance($appName); if ($application === null) { throw new WindException($appName . '[core.web.WindFrontController.process]', WindException::ERROR_CLASS_NOT_EXIST); } $routerAlias = $this->windSystemConfig->getRouterClass(); $application->setDelayAttributes(array('handlerAdapter' => array('ref' => $routerAlias))); if (null !== ($filterChain = $this->getFilterChain())) { $filterChain->setCallBack(array($application, 'processRequest'), array()); $filterChain->getHandler()->handle($this->request, $this->response); } else $application->processRequest($this->request, $this->response); $this->afterProcess(); } protected function getFilterChain() { $filterChainPath = $this->windSystemConfig->getFilterClass(); $filters = $this->windSystemConfig->getFilters(); if (empty($filters) || empty($filterChainPath)) return null; if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( "[core.WindFrontController.getFilterChain] an filter chain defined.(" . $filterChainPath . "," . count($filters) . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); } return $this->windFactory->createInstance($filterChainPath, array($filters)); } protected function initWindFactory() { $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); $factoryClass = Wind::import(self::WIND_SYSTEM_FACTORY); $this->windFactory = new $factoryClass(@include ($configPath)); if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.web.WindFrontController.initWindFactory] system factory:' . self::WIND_SYSTEM_FACTORY, WindLogger::LEVEL_DEBUG, 'wind.core'); } } protected function initWindConfig($appName, $config) { !$appName && $appName = 'default'; $this->windSystemConfig = new WindSystemConfig($config, new WindConfigParser(), $appName); Wind::register($this->windSystemConfig->getRootPath(), $this->windSystemConfig->getAppName(), true); if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( '[core.web.WindFrontController.initWindConfig] rootPath:' . $this->windSystemConfig->getRootPath() . ' appName:' . $this->windSystemConfig->getAppName(), WindLogger::LEVEL_DEBUG, 'wind.core'); } } protected function beforeProcess() {} protected function afterProcess() { $this->response->sendResponse(); } public function getWindSystemConfig() { return $this->windSystemConfig; } public function getWindFactory() { return $this->windFactory; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } } class WindUrlHelper extends WindModule { const URL_PATTERN = 'url-pattern'; const ROUTE_SUFFIX = 'route-suffix'; const ROUTE_PARAM = 'route-param'; const REWRITE = false; const ROUTE_SEPARATOR = '_'; protected $routeSuffix = ''; protected $routeParam = ''; protected $urlPattern = ''; protected $windRouter = null; public function isRewrite() { return self::REWRITE; } public function parseUrl() { if ((($uri = $this->request->getServer('QUERY_STRING')) == '') || !$this->isRewrite()) return; if (($pattern = $this->getUrlPattern()) == '') return; $seperator = isset($pattern[1]) ? $pattern[1] : $pattern[0]; $uri = explode($seperator, $uri); if (strcasecmp($pattern, "=&") != 0) $params = $this->parseUrlToParams($uri, $seperator, $pattern[0]); $_GET = array_merge($_GET, $params); $this->matchRouter(array_pop($uri)); } public function createUrl($action, $controller, $params = array()) { $action && $this->getWindRouter()->setAction($action); list($_c, $_m) = WindHelper::resolveController($controller); $_c && $this->getWindRouter()->setController($_c); $_m && $this->getWindRouter()->setModule($_m); $url = $this->getWindRouter()->buildUrl(); $server = $this->getUrlServer(); if ($this->isRewrite()) { $server = substr($server, 0, strrpos($server, '/')); $url = $server . $this->buildRewriteURL($params, $url); } else { $url = $server . $url . '&' . $this->buildUrl($params); } return $url; } private function getUrlServer($hasPath = true) { list($protocol, ) = explode('/', $this->request->getProtocol()); $protocol = strtolower($protocol) . '://' . $this->request->getServer('SERVER_NAME'); ($hasPath) && $protocol .= $this->request->getServer('PHP_SELF'); return $protocol; } private function matchRouter($mca) { if (strrpos($mca, '.' . $this->getRouteSuffix()) === false) return; $mca = trim(rtrim($mca, '.' . $this->getRouteSuffix())); if ($mca == '') return; $mca = explode(self::ROUTE_SEPARATOR, $mca); $m = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_MODULE); $c = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_CONTROLLER); $a = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_ACTION); if (count($mca) == 1) { $_GET[$c] = $mca[0]; } elseif (count($mca) == 2) { $_GET[$c] = $mca[0]; $_GET[$a] = $mca[1]; } else { ($mca[0]) && $_GET[$m] = $mca[0]; ($mca[1]) && $_GET[$c] = $mca[1]; ($mca[2]) && $_GET[$a] = $mca[2]; } return; } private function parseUrlToParams($url, $seprator = '', $keyAsValue = '=') { $params = array(); if ($seprator == $keyAsValue) { $n = count($url); for ($i = 0; $i < $n / 2; $i++) { $k = 2 * $i; $v = $k + 1; if (isset($url[$v])) { $this->parseKey($params, $url[$k], $url[$v]); } } return $params; } foreach ((array) $url as $key => $value) { if (strpos($value, $keyAsValue) === false) continue; list($key, $value) = explode($keyAsValue, $value); $this->parseKey($params, $key, $value); } return $params; } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } private function getUrlParamConfig($type) { $_config = $this->getWindRouter()->getConfig(WindUrlBasedRouter::URL_RULE); if ($_param = $this->getConfig($type, WindUrlBasedRouter::URL_PARAM, $_config)) { return $_param; } return $type; } private function getSeparator() { (($pattern = $this->getUrlPattern()) == '') && $pattern = '=&'; $separator = isset($pattern[1]) ? $pattern[1] : $pattern[0]; return array($pattern[0], $separator); } private function buildRewriteURL($params, $routerInfo) { $routerInfo = $this->parseUrlToParams(explode('&', trim($routerInfo, '?')), '&', '='); $routerInfo = implode(self::ROUTE_SEPARATOR, $routerInfo) . '.' . $this->getRouteSuffix(); $separator = $this->getSeparator(); if (empty($params)) return $separator[1] . $routerInfo; $url = ''; foreach ((array) $params as $key => $value) { $url .= $this->buildKey($key, $value, $separator[0], $separator[1]) . $separator[1]; } return $separator[1] . $url . $routerInfo; } private function buildKey($parentKey, $parentValue, $keyAsValue, $separator, $flag = false) { $flag && $parentKey = is_numeric($parentKey) ? '[]' : '[' . $parentKey . ']'; if (!is_array($parentValue)) return $parentKey . $keyAsValue . urlencode($parentValue); $keys = array(); foreach ($parentValue as $key => $value) { $keys[] = $parentKey . $this->buildKey($key, $value, $keyAsValue, $separator, true); } return implode($separator, $keys); } private function buildUrl($params) { if (empty($params)) return ''; $url = ''; foreach ((array) $params as $key => $value) { $url .= $this->buildKey($key, $value, '=', '&', false) . '&'; } return trim($url, '&'); } public function checkUrl($url) { list($protocal, $serverName) = explode('://', $this->getUrlServer(false)); $pos1 = stripos($url, $protocal); $pos2 = stripos($url, $serverName); if (false === $pos1 && false === $pos2) return $protocal . '://' . $serverName . '/' . ltrim($url, '/'); if (false === $pos1) return $protocal . '://' . ltrim($url, '/'); return $url; } public function getRouteSuffix() { if ($this->routeSuffix === '') { $this->routeSuffix = $this->getConfig(self::ROUTE_SUFFIX, WindSystemConfig::VALUE); } return $this->routeSuffix; } public function getRouteParam() { if ($this->routeParam === '') { $this->routeParam = $this->getConfig(self::ROUTE_PARAM, WindSystemConfig::VALUE); } return $this->routeParam; } public function getUrlPattern() { if ($this->urlPattern === '') { $this->urlPattern = $this->getConfig(self::URL_PATTERN, WindSystemConfig::VALUE); } return $this->urlPattern; } public function setRouteSuffix($routeSuffix) { $this->routeSuffix = $routeSuffix; } public function setRouteParam($routeParam) { $this->routeParam = $routeParam; } public function setUrlPattern($urlPattern) { $this->urlPattern = $urlPattern; } public function getWindRouter() { return $this->windRouter; } public function setWindRouter($windRouter) { $this->windRouter = $windRouter; } } class WindWebApplication extends WindModule implements IWindApplication { protected $dispatcher = null; protected $handlerAdapter = null; public function processRequest() { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.web.WindWebApplication.processRequest]', WindLogger::LEVEL_DEBUG, 'wind.core'); } $handler = $this->getHandler(); call_user_func_array(array($handler, 'preAction'), array($this->handlerAdapter)); $forward = call_user_func_array(array($handler, 'doAction'), array($this->handlerAdapter)); call_user_func_array(array($handler, 'postAction'), array($this->handlerAdapter)); $this->doDispatch($forward); } catch (WindActionException $actionException) { $this->sendErrorMessage($actionException); } catch (WindDbException $dbException) { $this->sendErrorMessage($dbException->getMessage()); } catch (WindViewException $viewException) { throw new Exception($viewException->getMessage()); } } public function doDispatch($forward) { if ($forward === null) { Wind::log('[core.web.WindWebApplication.doDispatch] Forward is null, dispatch abort.', WindLogger::LEVEL_DEBUG, 'wind.core'); return; } $this->getDispatcher()->dispatch($this, $forward, $this->handlerAdapter); } protected function getHandler() { $handler = $this->getHandlerAdapter()->doParse(); if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.web.WindWebApplication.getHandler] router result:' . $handler, WindLogger::LEVEL_DEBUG, 'wind.core'); } if (!$this->getSystemFactory()->checkAlias($handler)) { $definition = new WindClassDefinition(); $definition->setPath($handler); $definition->setScope(WindClassDefinition::SCOPE_SINGLETON); $definition->setAlias($handler); $definition->setProxy('true'); $definition->setProperties( array('errorMessage' => array('ref' => COMPONENT_ERRORMESSAGE), 'forward' => array('ref' => COMPONENT_FORWARD), 'urlHelper' => array('ref' => COMPONENT_URLHELPER))); $this->getSystemFactory()->addClassDefinitions($definition); } return $this->getSystemFactory()->getInstance($handler); } protected function sendErrorMessage($actionException) { $_tmp = is_object($actionException) ? $actionException->getError() : $actionException; if (is_string($_tmp)) $_tmp = new WindErrorMessage($_tmp); $forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD); $forward->forwardAnotherAction($_tmp->getErrorAction(), $_tmp->getErrorController()); $this->getRequest()->setAttribute('error', $_tmp->getError()); $this->doDispatch($forward); } protected function getHandlerAdapter() { return $this->_getHandlerAdapter(); } protected function getDispatcher() { return $this->_getDispatcher(); } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array( $this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array( $this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array( $input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array( $this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array( $input, $setMethod), array( $rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); Wind::import('WIND:core.factory.WindFactory'); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindHelper { public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } ?> \ No newline at end of file From c37cdceb68122b2efc953a23fba01508327f5517 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 07:38:16 +0000 Subject: [PATCH 0105/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2163 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/compile.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php index 06412fe4..c5d21c12 100644 --- a/wind/_compile/compile.php +++ b/wind/_compile/compile.php @@ -5,6 +5,7 @@ **/ define('_COMPILE_PATH', WIND_PATH . '_compile' . D_S); Wind::clear(); +Wind::import('COM:log.WindLogger'); Wind::import('WIND:core.*', true); $imports = Wind::getImports(); /* 载入需要的文件信息 */ @@ -18,9 +19,7 @@ foreach ($imports as $key => $value) { $content[$value] = $key; $_key = Wind::getRealPath($key . '.' . self::$_extensions); - $fileList[$_key] = array( - $key, - $value); + $fileList[$_key] = array($key, $value); } $pack->packFromFileList($fileList, COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); /* import信息写入编译文件 */ From db4aa1204bded5d54eb4bb7ed91a35755c4c0062 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 19 Jul 2011 08:04:04 +0000 Subject: [PATCH 0106/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2164 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 1bfaa8cf..c8e418a6 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -53,6 +53,7 @@ + From 1b7089465e39a00afa61c92be054c2f921c87005 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 19 Jul 2011 08:04:16 +0000 Subject: [PATCH 0107/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2165 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindView.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 42a4fda1..f87418d0 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -20,6 +20,7 @@ class WindView extends WindModule { /* 视图配置信息 */ const TEMPLATE_DIR = 'template-dir'; const TEMPLATE_EXT = 'template-ext'; + const COMPILE_DIR = 'compile-dir'; const IS_CACHE = 'is-cache'; /** * 模板路径信息 @@ -45,6 +46,8 @@ class WindView extends WindModule { * @var boolean */ protected $isCache = false; + + protected $compileDir; /** * 视图解析引擎 * @@ -104,7 +107,7 @@ public function getViewTemplate($template = '', $ext = '') { * @return string | false */ public function getCompileFile($template = '', $ext = '') { - return $this->parseFilePath($template, $ext, COMPILE_PATH . 'template', true); + return $this->parseFilePath($template, $ext, $this->getCompileDir(), true); } /** @@ -134,6 +137,7 @@ private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) */ public function init() { $this->setTemplateDir($this->getConfig(self::TEMPLATE_DIR, WIND_CONFIG_VALUE)); + $this->setCompileDir($this->getConfig(self::COMPILE_DIR, WIND_CONFIG_VALUE)); $this->setTemplateExt($this->getConfig(self::TEMPLATE_EXT, WIND_CONFIG_VALUE)); $this->setIsCache($this->getConfig(self::IS_CACHE), WIND_CONFIG_VALUE); } @@ -144,6 +148,13 @@ public function init() { public function getTemplateDir() { return $this->templateDir; } + + /** + * @return string + */ + public function getCompileDir() { + return $this->compileDir; + } /** * @return string @@ -179,6 +190,13 @@ public function getLayout() { public function setTemplateDir($templateDir) { $this->templateDir = $templateDir; } + + /** + * @param string $compileDir + */ + public function setCompileDir($compileDir) { + $this->compileDir = $compileDir; + } /** * @param string $templateExt From 4fe01221a073847621327438a1c07156c2e123e0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 08:08:54 +0000 Subject: [PATCH 0108/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2166 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/wind_imports.php | 44 -------------- wind/components_config.php | 103 --------------------------------- wind/wind_basic.php | 1 - 3 files changed, 148 deletions(-) delete mode 100644 wind/_compile/wind_imports.php delete mode 100644 wind/components_config.php delete mode 100644 wind/wind_basic.php diff --git a/wind/_compile/wind_imports.php b/wind/_compile/wind_imports.php deleted file mode 100644 index 4637fe72..00000000 --- a/wind/_compile/wind_imports.php +++ /dev/null @@ -1,44 +0,0 @@ - 'WIND:core.config.parser.IWindConfigParser', - 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', - 'WindConfig' => 'WIND:core.config.WindConfig', - 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', - 'WindActionException' => 'WIND:core.exception.WindActionException', - 'WindException' => 'WIND:core.exception.WindException', - 'WindFinalException' => 'WIND:core.exception.WindFinalException', - 'IWindFactory' => 'WIND:core.factory.IWindFactory', - 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', - 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', - 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', - 'WindFactory' => 'WIND:core.factory.WindFactory', - 'WindFilter' => 'WIND:core.filter.WindFilter', - 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', - 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', - 'IWindRequest' => 'WIND:core.request.IWindRequest', - 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', - 'IWindResponse' => 'WIND:core.response.IWindResponse', - 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', - 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', - 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', - 'IWindController' => 'WIND:core.web.controller.IWindController', - 'WindController' => 'WIND:core.web.controller.WindController', - 'WindSimpleController' => 'WIND:core.web.controller.WindSimpleController', - 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', - 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', - 'IWindApplication' => 'WIND:core.web.IWindApplication', - 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', - 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', - 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', - 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', - 'WindDispatcher' => 'WIND:core.web.WindDispatcher', - 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', - 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', - 'WindForward' => 'WIND:core.web.WindForward', - 'WindFrontController' => 'WIND:core.web.WindFrontController', - 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', - 'WindWebApplication' => 'WIND:core.web.WindWebApplication', - 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', - 'WindHelper' => 'WIND:core.WindHelper', - 'WindModule' => 'WIND:core.WindModule', -); \ No newline at end of file diff --git a/wind/components_config.php b/wind/components_config.php deleted file mode 100644 index 60a2a379..00000000 --- a/wind/components_config.php +++ /dev/null @@ -1,103 +0,0 @@ - array( - 'path' => 'WIND:core.web.WindWebApplication', - 'scope' => 'singleton', - 'properties' => array( - 'dispatcher' => array( - 'ref' => 'dispatcher', - ), - ), - ), - 'dispatcher' => array( - 'path' => 'WIND:core.web.WindDispatcher', - 'scope' => 'prototype', - 'properties' => array( - 'urlHelper' => array( - 'ref' => 'urlHelper', - ), - ), - ), - 'forward' => array( - 'path' => 'WIND:core.web.WindForward', - 'scope' => 'prototype', - ), - 'urlBasedRouter' => array( - 'path' => 'WIND:core.router.WindUrlBasedRouter', - 'scope' => 'prototype', - 'config' => array( - 'module' => array( - 'url-param' => 'm', - 'default-value' => 'default', - ), - 'controller' => array( - 'url-param' => 'c', - 'default-value' => 'index', - ), - 'action' => array( - 'url-param' => 'a', - 'default-value' => 'run', - ), - ), - ), - 'urlHelper' => array( - 'path' => 'WIND:core.web.WindUrlHelper', - 'scope' => 'singleton', - 'properties' => array( - 'windRouter' => array( - 'ref' => 'urlBasedRouter', - ), - ), - 'config' => array( - 'url-pattern' => array( - 'value' => '-/', - ), - 'route-suffix' => array( - 'value' => 'htm', - ), - 'route-param' => array( - 'value' => 'r', - ), - ), - ), - 'windView' => array( - 'init-method' => 'init', - 'path' => 'COM:viewer.WindView', - 'scope' => 'prototype', - 'config' => array( - 'template-dir' => array( - 'value' => 'template', - ), - 'template-ext' => array( - 'value' => 'htm', - ), - 'is-cache' => array( - 'value' => 'true', - ), - ), - 'properties' => array( - 'viewResolver' => array( - 'ref' => 'viewResolver', - ), - ), - ), - 'viewResolver' => array( - 'path' => 'COM:viewer.WindViewerResolver', - 'scope' => 'prototype', - 'properties' => array( - 'urlHelper' => array( - 'ref' => 'urlHelper', - ), - ), - ), - 'template' => array( - 'path' => 'COM:viewer.compiler.WindViewTemplate', - 'scope' => 'prototype', - 'config' => array( - 'resource' => '', - ), - ), - 'errorMessage' => array( - 'path' => 'WIND:core.web.WindErrorMessage', - 'scope' => 'prototype', - ), -); \ No newline at end of file diff --git a/wind/wind_basic.php b/wind/wind_basic.php deleted file mode 100644 index b4ed2e91..00000000 --- a/wind/wind_basic.php +++ /dev/null @@ -1 +0,0 @@ -buildCacheFilePath($append) : $this->buildCacheFilePath($alias)); if ($alias) { $config = $this->getCacheContent($cacheFileName); if (isset($config[$alias]) && !$this->needCompiled()) { return $config[$alias]; } } if (!($configPath = trim($configPath))) throw new WindException('Please input the file path!'); $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); if (!$alias) return $result; $config[$alias] = $result; $this->saveConfigFile($cacheFileName, $config); return $result; } private function getCacheContent($file) { $content = array(); if (is_file($file)) $content = include ($file); return is_array($content) ? $content : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('init config parser error.'); break; } } private function doParser($configFile, $type) { if (!$configFile) return array(); if (!is_file($configFile)) throw new WindException('The file <' . $configFile . '> is not exists'); if ($type == 'PHP') { $config = include ($configFile); return (isset($config['wind'])) ? $config['wind'] : $config; } if (!isset($this->configParsers[$type])) { $this->configParsers[$type] = $this->createParser($type); } return $this->configParsers[$type]->parse($configFile); } private function needCompiled() { if (IS_DEBUG && is_dir(COMPILE_PATH)) return true; return false; } private function getConfigFormat($configPath) { if ($configPath === '') return self::CONFIG_XML; $format = strtoupper(trim(strrchr($configPath, '.'), '.')); if (!in_array($format, $this->getConfigFormatList())) { throw new WindException("The format of the config file doesn't sopported yet!"); } return $format; } private function saveConfigFile($filename, $data) { if (!$filename || !$data || !is_dir(COMPILE_PATH)) return false; Wind::import('COM:utility.WindFile'); return WindFile::savePhpData($filename, $data); } private function buildCacheFilePath($fileName) { return rtrim(COMPILE_PATH, '/') . D_S . strtolower($fileName) . '.php'; } private function getConfigFormatList() { return array( self::CONFIG_XML, self::CONFIG_PHP, self::CONFIG_INI, self::CONFIG_PROPERTIES); } public function __destruct() { $this->configParser = array(); } } class WindConfig { protected $configParser = null; protected $cacheName; protected $append; protected $config = array(); public function __construct($config, $configParser = null, $cacheName = '', $append = false) { $this->setConfigParser($configParser); $this->setCacheName($cacheName); $this->setAppend($append); $this->initConfig($config); } public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { if (!$config) $config = $this->config; if ($configName === '') return $config; $_config = $default; if (isset($config[$configName])) { $_config = $config[$configName]; } if ($subConfigName === '') return $_config; $_subConfig = $default; if (is_array($_config) && isset($_config[$subConfigName])) { $_subConfig = $_config[$subConfigName]; } return $_subConfig; } protected function initConfig($config) { if (!$config) return; if (!is_array($config)) { $config = $this->parseConfig($config, $this->getCacheName(), $this->getAppend()); } $this->setConfig($config); } protected function parseConfig($config, $cacheName, $append) { if ($this->getConfigParser() === null) { throw new WindException('configParser is null.'); } return $this->getConfigParser()->parse($config, $cacheName, $append); } public function setConfig($config, $merage = false) { if (!is_array($config)) throw new WindException('config error.'); if ($merage) $this->config = array_merge($this->config, $config); else $this->config = $config; } public function getConfigParser() { return $this->configParser; } public function setConfigParser($configParser) { if ($this->configParser || $configParser == null) return; $this->configParser = $configParser; } public function getCacheName() { return $this->cacheName; } public function getAppend() { return $this->append; } public function setCacheName($cacheName) { $this->cacheName = $cacheName; } public function setAppend($append) { $this->append = $append; } } Wind::import('WIND:core.config.WindConfig'); class WindSystemConfig extends WindConfig { const CLASS_PATH = 'class'; const PATH = 'path'; const VALUE = 'value'; const IMPORTS = 'imports'; const IMPORTS_RESOURCE = 'resource'; const IMPORTS_IS_APPEND = 'is-append'; const WEB_APPS = 'web-apps'; const WEB_APP_ROOT_PATH = 'root-path'; const WEB_APP_FACTORY = 'factory'; const WEB_APP_FACTORY_CLASS_DEFINITION = 'class-definition'; const WEB_APP_FILTER = 'filters'; const WEB_APP_ROUTER = 'router'; const WEB_APP_MODULE = 'modules'; const WEB_APP_TEMPLATE = 'template'; protected $appName = ''; protected $imports = array(); public function __construct($config, $configParser, $appName) { $cacheName = $appName . '_config'; $this->appName = $appName; parent::__construct($config, $configParser, $cacheName); } public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { $imports = parent::getConfig(self::IMPORTS); if (key_exists($configName, (array) $imports)) { return $this->parseImport($configName); } return parent::getConfig($configName, $subConfigName, $config, $default); } public function getAppName() { return $this->appName; } public function getAppClass() { $_config = $this->getConfig(self::WEB_APPS, $this->appName); $_tmp = $this->getConfig(self::CLASS_PATH, '', $_config); return $_tmp ? $_tmp : COMPONENT_WEBAPP; } public function getRootPath($appName = '') { if ($appName === '') $appName = $this->appName; $_tmp = $appName . '_RootPath'; if (!isset($this->$_tmp)) { $appConfig = $this->getConfig(self::WEB_APPS, $appName); if (isset($appConfig[self::WEB_APP_ROOT_PATH]) && !empty($appConfig[self::WEB_APP_ROOT_PATH])) $rootPath = $appConfig[self::WEB_APP_ROOT_PATH]; else $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); $this->$_tmp = $rootPath; } return $this->$_tmp; } public function getFactory($name = '') { $_config = $this->getConfig(self::WEB_APPS, $this->appName); return $this->getConfig(self::WEB_APP_FACTORY, $name, $_config); } public function getFilterClass() { return $this->getFilters(self::CLASS_PATH); } public function getFilters($name = '') { $_config = $this->getConfig(self::WEB_APPS, $this->appName); return $this->getConfig(self::WEB_APP_FILTER, $name, $_config); } public function getRouterClass() { return $this->getRouter(WIND_CONFIG_CLASS); } public function getRouter($name = '') { $_config = $this->getConfig(self::WEB_APPS, $this->appName); $_router = $this->getConfig(self::WEB_APP_ROUTER, $name, $_config); return $_router ? $_router : COMPONENT_ROUTER; } public function getModules($name = '') { $_config = $this->getConfig(self::WEB_APPS, $this->appName); return $this->getConfig(self::WEB_APP_MODULE, $name, $_config); } public function getModuleViewClassByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig('view', WIND_CONFIG_CLASS, $module, $default); } public function getModuleViewConfigByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig('view', WIND_CONFIG_CONFIG, $module, $default); } public function getModuleErrorHandlerByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig('error-handler', WIND_CONFIG_CLASS, $module, $default); } public function getModuleControllerPathByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig(WIND_CONFIG_CLASSPATH, '', $module, $default); } public function getModuleControllerSuffixByModuleName($name, $default = '') { $module = $this->getModules($name); return $this->getConfig('controller-suffix', WIND_CONFIG_VALUE, $module, $default); } public function getTemplate($name = '') { return $this->getConfig(self::TEMPLATE, $name); } public function getViewerResolvers($name = '') { return $this->getConfig(self::VIEWER_RESOLVERS, $name); } public function getApplications($name = '') { return $this->getConfig(self::APPLICATIONS, $name); } public function getErrorMessage($name = '') { return $this->getConfig(self::ERROR, $name); } protected function parseImport($name) { if (!isset($this->imports[$name])) { $imports = $this->getConfig(self::IMPORTS); if (!isset($imports[$name])) return array(); $import = $imports[$name]; $config = array(); if (is_array($import) && !empty($import)) { $configPath = Wind::getRealPath($import[self::IMPORTS_RESOURCE]); if (!isset($import[self::IMPORTS_IS_APPEND]) || $import[self::IMPORTS_IS_APPEND] === 'true') { $append = $this->cacheName; } elseif ($import[self::IMPORTS_IS_APPEND] === 'false' || $import[self::IMPORTS_IS_APPEND] === '') { $append = false; } else { $append = $import[self::IMPORTS_IS_APPEND]; } $cacheName = $append ? $name : $this->appName . '_' . $name . '_config'; $config = $this->parseConfig($configPath, $cacheName, $append); } $this->imports[$name] = $config; } return $this->imports[$name]; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } Wind::import('WIND:core.exception.WindException'); class WindActionException extends WindException { private $error; public function __construct($error) { $this->setError($error); parent::__construct(''); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } Wind::import('WIND:core.exception.WindException'); class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } interface IWindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; public function _getReflection(); public function _getInstance(); public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD); } class WindClassProxy implements IWindClassProxy { private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObj = null, $args = array()) { $this->initClassProxy($targetObj, $args); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } protected function initClassProxy($targetObject, $args = array()) { try { if (is_object($targetObject)) { $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; } elseif (is_string($targetObject) && !empty($targetObject)) { $_className = Wind::import($targetObject); $this->_setClassName($_className); } else throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) { $this->_listener[$type] = array(); } $reflection = new ReflectionClass($this->_className); if ($reflection->isAbstract() || $reflection->isInterface()) { throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); } $this->_reflection = $reflection; if ($this->_instance !== null) return; $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); } catch (Exception $e) { Wind::log( '[core.factory.proxy.WindClassProxy.initClassProxy] Initialization proxy failed.' . $e->getMessage(), WindLogger::LEVEL_DEBUG, 'wind.core'); } } private function _getInterceptorChain($event = '') { $interceptorChain = WindFactory::createInstance($this->_interceptorChain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $interceptorChain->setAttribute($this->_getAttribute()); $interceptorChain->setAttribute('instance', $this->_getInstance()); $interceptorChain->setAttribute('event', array($this->_getClassName(), $event)); return $interceptorChain; } else throw new WindException('unable to create interceptorChain.'); } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getReflection() { if ($this->_reflection instanceof ReflectionClass) return $this->_reflection; else throw new WindException(get_class($this) . '->_reflection, ' . gettype($this->_reflection), WindException::ERROR_CLASS_TYPE_ERROR); } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; return true; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } public function _getAttribute($alias = '') { if ($alias === '') return $this->_attributes; else return isset($this->_attributes[$alias]) ? $this->_attributes[$alias] : null; } public function _setAttribute($alias, $object = null) { if (is_array($alias)) $this->_attributes += $alias; elseif (is_string($alias)) $this->_attributes[$alias] = $object; } } class WindClassDefinition { const NAME = 'name'; const PATH = 'path'; const FACTORY_METHOD = 'factory-method'; const INIT_METHOD = 'init-method'; const SCOPE = 'scope'; const PROPERTIES = 'properties'; const CONSTRUCTOR_ARG = 'constructor-arg'; const REF = 'ref'; const VALUE = 'value'; const DELAY = 'delay'; const PROXY = 'proxy'; const CONFIG = 'config'; const RESOURCE = 'resource'; const SCOPE_SINGLETON = 'singleton'; const SCOPE_PROTOTYPE = 'prototype'; const SCOPE_REQUEST = 'request'; protected $proxyClass = 'WIND:core.factory.proxy.WindClassProxy'; protected $config; protected $proxy; protected $className; protected $alias; protected $path; protected $scope; protected $factoryMethod; protected $initMethod; protected $constructArgs = array(); protected $properties = array(); protected $classDefinition; private $instance = null; public function __construct($classDefinition = array()) { $this->init($classDefinition); } public function getInstance($factory, $args = array()) { if ($instance = $this->executeFactoryMethod($args)) return $instance; switch ($this->scope) { case 'prototype': return $this->createInstanceWithPrototype($factory, $args); default: return $this->createInstanceWithSingleton($factory, $args); } } protected function createInstanceWithPrototype($factory, $args) { return $this->createInstance($factory, $args); } protected function createInstanceWithSingleton($factory, $args) { $_instance = $this->createInstance($factory, $args); $factory->setSingled($this->getAlias(), $_instance); return $_instance; } protected function createInstance($factory, $args) { $args = $this->buildConstructArgs($factory, $args); $instance = $factory->createInstance($this->getClassName(), $args); if ($instance instanceof WindModule) { $this->buildConfig($instance, $factory); $this->buildProperties($instance, $factory); $this->executeInitMethod($instance); $this->setHiddenProperty($instance, $factory); $instance = $this->setProxyForClass($instance, $factory); } return $instance; } protected function buildConfig($instance, $factory) { if (!$config = $this->getConfig()) return; if (isset($config[self::RESOURCE])) { $config = $config[self::RESOURCE]; } $instance->setConfig($config); } protected function setHiddenProperty($instance, $factory) { $instance->systemConfig = Wind::getApp()->getWindSystemConfig(); $instance->request = Wind::getApp()->getRequest(); $instance->response = Wind::getApp()->getResponse(); $instance->systemFactory = $factory; } protected function setProxyForClass($instance, $factory) { if (!($proxy = $this->getProxy()) || $proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyClass; $proxy = $factory->createInstance($proxy, array($instance)); if ($proxy !== null) return $proxy; Wind::log( '[core.factory.WindClassDefinition.setProxyForClass] create proxy for ' . $this->getClassName() . ' fail.', WindLogger::LEVEL_DEBUG, 'wind.core'); throw new WindException( '[core.factory.WindClassDefinition.setProxyForClass] create proxy for ' . $this->getClassName() . ' fail.', WindException::ERROR_SYSTEM_ERROR); } private function executeInitMethod($instance) { try { if (!($initMethod = $this->getInitMethod())) return; return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindClassDefinition.executeInitMethod] (' . $this->getClassName() . '->' . $initMethod . '()) "' . $e->getMessage() . '"', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function buildConstructArgs($factory, $args) { if ($args) return $args; $subDefinitions = $this->getConstructArgs(); $_tmp = array(); foreach ($subDefinitions as $key => $subDefinition) { if (isset($subDefinition[self::VALUE])) { $_tmp[$key] = $subDefinition[self::VALUE]; } elseif (isset($subDefinition[self::REF])) $_tmp[$key] = $factory->getInstance($subDefinition[self::REF]); } return $_tmp; } protected function buildProperties($instance, $factory) { if (!$subDefinitions = $this->getPropertys()) return; foreach ($subDefinitions as $key => $subDefinition) { $_value = ''; if (isset($subDefinition[self::VALUE])) $_value = $subDefinition[self::VALUE]; if ($_value) { $_setter = 'set' . ucfirst(trim($key, '_')); call_user_func_array(array($instance, $_setter), array($_value)); } } $instance->setDelayAttributes($subDefinitions); } protected function executeFactoryMethod($args) { try { if (!($factoryMethod = $this->getFactoryMethod())) return null; return call_user_func_array(array($this->getClassName(), $factoryMethod), $args); } catch (Exception $e) { throw new WindException( '[core.factory.WindClassDefinition.executeFactoryMethod] (' . $this->getClassName() . '->' . $factoryMethod . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function init($classDefinition) { try { if (empty($classDefinition)) return; foreach ($classDefinition as $key => $value) { if (strpos($key, '-') !== false) { list($_s1, $_s2) = explode('-', $key); $_s1 = ucfirst($_s1); $_s2 = ucfirst($_s2); $_setter = 'set' . $_s1 . $_s2; } else $_setter = 'set' . ucfirst($key); call_user_func_array(array($this, $_setter), array($value)); } $this->setClassDefinition($classDefinition); } catch (Exception $e) { throw new WindException("[core.factory.WindClassDefinition.init]" . $e->getMessage(), WindException::ERROR_SYSTEM_ERROR); } } public function getClassName() { if (!$this->className) { $this->className = Wind::import($this->getPath()); } return $this->className; } public function getAlias() { return $this->alias; } public function getPath() { return $this->path; } public function getScope() { return $this->scope; } public function setClassName($className) { $this->className = $className; } public function setAlias($alias) { $this->alias = $alias; } public function setPath($path) { $this->path = $path; } public function setScope($scope) { $this->scope = strtolower($scope); } public function getConstructArgs() { return $this->constructArgs; } public function getPropertys() { return $this->properties; } public function getClassDefinition() { return $this->classDefinition; } public function setConstructArgs($constructArgs) { if (is_array($constructArgs) && !empty($constructArgs)) $this->constructArgs += $constructArgs; } public function setProperties($properties) { if (!is_array($properties)) return; $this->properties = array_merge($this->properties, $properties); } public function setClassDefinition($classDefinition) { $this->classDefinition = $classDefinition; } public function getFactoryMethod() { return $this->factoryMethod; } public function getInitMethod() { return $this->initMethod; } public function setFactoryMethod($factoryMethod) { $this->factoryMethod = $factoryMethod; } public function setInitMethod($initMethod) { $this->initMethod = $initMethod; } public function getProxy() { return $this->proxy; } public function setProxy($proxy) { $this->proxy = $proxy; } public function getConfig() { return $this->config; } public function setConfig($config) { $this->config = $config; } } class WindFactory implements IWindFactory { protected $classDefinitionType = 'WIND:core.factory.WindClassDefinition'; protected $classDefinitions = array(); protected $instances = array(); public function __construct($classDefinitions = array()) { $this->loadClassDefinitions($classDefinitions); } public function getInstance($alias) { if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!$classDefinition = $this->getClassDefinitionByAlias($alias)) return null; $args = func_get_args(); unset($args[0]); return $classDefinition->getInstance($this, $args); } public function getPrototype($alias) { $instance = $this->getInstance($alias); if ($instance === null) return null; return clone $instance; } static public function createInstance($className, $args = array()) { try { if (!$className) return null; if (strpos($className, ':') !== false) $className = Wind::import($className); $reflection = new ReflectionClass($className); if ($reflection->isAbstract() || $reflection->isInterface()) return null; Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_INFO, 'core.factory'); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function setSingled($classAlias, $instance) { Wind::log('[core.factory.WindFactory.createInstance] create singled instance:' . $classAlias, WindLogger::LEVEL_INFO, 'core.factory'); $this->instances[$classAlias] = $instance; } protected function getClassDefinitionByAlias($classAlias) { if (!($definition = $this->classDefinitions[$classAlias])) return null; if ($definition instanceof WindClassDefinition) return $definition; $classDefinition = self::createInstance($this->classDefinitionType, array($definition)); $classDefinition->setAlias($classAlias); $this->addClassDefinitions($classDefinition); return $classDefinition; } public function addClassDefinitions($classDefinition) { if ($classDefinition instanceof WindClassDefinition) { $alias = $classDefinition->getAlias(); $this->classDefinitions[$alias] = $classDefinition; } elseif (is_array($classDefinition)) { foreach ($classDefinition as $value) $this->addClassDefinitions($value); } } public function checkAlias($alias) { return isset($this->classDefinitions[$alias]); } protected function loadClassDefinitions($classDefinitions) { if (is_array($classDefinitions)) $this->classDefinitions = $classDefinitions; else throw new WindException('[core.factory.WindFactory.loadClassDefinitions]', WindException::ERROR_PARAMETER_TYPE_ERROR); } } Wind::import('COM:utility.WindUtility'); class WindModule { private $_config = null; private $_array = array(); protected $_typeValidation = false; private $delayAttributes = array(); public function __set($propertyName, $value) { if (!$this->validatePropertyName($propertyName)) { $_setter = 'set' . ucfirst($propertyName); if (method_exists($this, $_setter)) $this->$_setter($value); else Wind::log('[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } else $this->$propertyName = $value; } public function __get($propertyName) { if (!$this->validatePropertyName($propertyName)) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); else Wind::log('[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } else return $this->$propertyName; } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_set') { $this->$_propertyName = $args[0]; } elseif ($_prefix == '_get') { if (property_exists($this, $_propertyName) && $this->$_propertyName) { return $this->$_propertyName; } if (isset($this->delayAttributes[$_propertyName])) { $_instance = null; $_property = $this->delayAttributes[$_propertyName]; if (isset($_property[WindClassDefinition::REF])) { $_ref = $_property[WindClassDefinition::REF]; if ($this->getSystemFactory()->checkAlias($_ref)) $_instance = $this->getSystemFactory()->getInstance($_ref); else $_instance = $this->getSystemFactory()->createInstance($_ref); } $this->$_propertyName = $_instance; Wind::log("[core.WindMOdule.__call] create property $_propertyName fail.", WindLogger::LEVEL_DEBUG, 'wind.core'); } Wind::log("[core.WindModule.__call] attribute is not exist. (" . $methodName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return $this->$_propertyName; } throw new WindException('[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) { Wind::log( "[core.WindModule.__clone] unexcepted value type or the property is not setted.(" . $value . ") need an object type in here. ", WindLogger::LEVEL_DEBUG, 'wind.core'); continue; } $this->$value = clone $this->$value; } } public function toArray() { if (empty($this->_array)) { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } $this->_array = $_result; } return $this->_array; } protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { Wind::log('[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } if (!($_writeTableProperties = $this->writeTableForProperty())) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { if ($value instanceof $_writeTableProperties[$propertyName]) return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. ", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } return true; } public function getConfig($configName = '', $subConfigName = '', $default = '') { if ($this->_config === null) { Wind::log('[core.WindModule.getConfig] config is not exist.', WindLogger::LEVEL_INFO, 'wind.core'); return $default; } return $this->_config->getConfig($configName, $subConfigName, array(), $default); } public function setConfig($config) { if (!$config) return; if (is_string($config)) { Wind::import('WIND:core.config.parser.WindConfigParser'); $config = new WindConfig($config, new WindConfigParser(), get_class($this), WIND_CONFIG_CACHE); } elseif (is_array($config)) $config = new WindConfig($config); if ($this->_config !== null) $this->_config->setConfig($config->getConfig(), true); else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemConfig() { return Wind::getApp()->getWindSystemConfig(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('WIND:core.filter.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); private $_state = true; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException('[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if ($this->_state) { $this->addInterceptors(new WindHandlerInterceptor()); $this->_state = false; } if (count($this->_interceptors) <= 0) return null; $handler = array_shift($this->_interceptors); if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } Wind::log( '[core.filter.WindHandlerInterceptorChain.getHandler] the type of Interceptor ' . gettype($handler) . ' is not supported.', WindLogger::LEVEL_DEBUG, 'wind.core'); return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } } Wind::import('WIND:core.filter.WindHandlerInterceptorChain'); class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes($data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse() { if ($this->_response === null) { Wind::import('WIND:core.response.WindHttpResponse'); $this->_response = new WindHttpResponse(); if ($this->getIsAjaxRequest()) { $this->_response->addHeader('Content-type', 'text/xml;charset=utf-8'); $this->_response->setIsAjax(true); } else $this->_response->addHeader('Content-type', 'text/html;charset=utf-8'); } return $this->_response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace( '/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException( __CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(''); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('WIND:core.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_isAjax = false; private $_data = array(); const SC_CONTINUE = 100; const SC_SWITCHING_PROTOCOLS = 101; const SC_OK = 200; const SC_CREATED = 201; const SC_ACCEPTED = 202; const SC_NON_AUTHORITATIVE_INFORMATION = 203; const SC_NO_CONTENT = 204; const SC_RESET_CONTENT = 205; const SC_PARTIAL_CONTENT = 206; const SC_MULTIPLE_CHOICES = 300; const SC_MOVED_PERMANENTLY = 301; const SC_MOVED_TEMPORARILY = 302; const SC_FOUND = 302; const SC_SEE_OTHER = 303; const SC_NOT_MODIFIED = 304; const SC_USE_PROXY = 305; const SC_TEMPORARY_REDIRECT = 307; const SC_BAD_REQUEST = 400; const SC_UNAUTHORIZED = 401; const SC_PAYMENT_REQUIRED = 402; const SC_FORBIDDEN = 403; const SC_NOT_FOUND = 404; const SC_METHOD_NOT_ALLOWED = 405; const SC_NOT_ACCEPTABLE = 406; const SC_PROXY_AUTHENTICATION_REQUIRED = 407; const SC_REQUEST_TIMEOUT = 408; const SC_CONFLICT = 409; const SC_GONE = 410; const SC_LENGTH_REQUIRED = 411; const SC_PRECONDITION_FAILED = 412; const SC_REQUEST_ENTITY_TOO_LARGE = 413; const SC_REQUEST_URI_TOO_LONG = 414; const SC_UNSUPPORTED_MEDIA_TYPE = 415; const SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const SC_EXPECTATION_FAILED = 417; const SC_INTERNAL_SERVER_ERROR = 500; const SC_NOT_IMPLEMENTED = 501; const SC_BAD_GATEWAY = 502; const SC_SERVICE_UNAVAILABLE = 503; const SC_GATEWAY_TIMEOUT = 504; const SC_HTTP_VERSION_NOT_SUPPORTED = 505; public function setHeader($name, $value, $replace = false) { if (trim($name) == '' || trim($value) == '') return; $name = $this->_normalizeHeader($name); foreach ($this->_headers as $key => $one) { ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); } } public function addHeader($name, $value, $replace = false) { if (trim($name) == '' || trim($value) == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function setStatus($status, $message = '') { if (!is_int($status) || $status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_unshift($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::SC_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message); $this->setStatus($status); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } header('HTTP/1.1 ' . $this->_status); } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { if (trim($name) == '') return ''; $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getIsAjax() { return $this->_isAjax; } public function setIsAjax($_isAjax) { $this->_isAjax = $_isAjax; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '') { if ($key) { $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_data += $data; } } abstract class AbstractWindRouter extends WindModule { const DEFAULT_ERROR_HANDLER = 'WIND:core.web.WindErrorHandler'; const CONTROLLER_DEFAULT_PATH = 'controller'; const CONTROLLER_DEFAULT_SUFFIX = 'Controller'; private $action = 'run'; private $controller = 'index'; private $module = 'default'; protected $modulePath = ''; private $reParse = true; abstract public function parse(); abstract public function buildUrl(); public function doParse() { $_moduleName = $this->getModule(); if (!strcasecmp($this->getController(), WIND_M_ERROR)) { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( '[core.roter.AbstractWindRouter.doParse] action hander: default error action :' . self::DEFAULT_ERROR_HANDLER, WindLogger::LEVEL_DEBUG, 'wind.core'); } return $this->getSystemConfig()->getModuleErrorHandlerByModuleName($_moduleName, self::DEFAULT_ERROR_HANDLER); } if ($this->reParse) { $this->parse(); $this->reParse = false; Wind::log('[core.router.AbstractWindRouter.doParse] parse the request.', WindLogger::LEVEL_DEBUG, 'wind.core'); } $_suffix = $this->getSystemConfig()->getModuleControllerSuffixByModuleName($_moduleName, self::CONTROLLER_DEFAULT_SUFFIX); if ($this->modulePath) $_path = $this->modulePath; else { $_path = $this->getSystemConfig()->getModuleControllerPathByModuleName($_moduleName, self::CONTROLLER_DEFAULT_PATH); } $_path .= '.' . ucfirst($this->controller) . $_suffix; if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.router.AbstractWindRouter.doParse] action handler: ' . $_path, WindLogger::LEVEL_DEBUG, 'wind.core'); } $this->destroy(); return $_path; } protected function destroy() { $this->modulePath = ''; } public function setModule($module) { if (false !== ($pos = strpos($module, ':'))) { $this->modulePath = $module; } else { $this->module = $module; $this->modulePath = ''; } } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getModule() { return $this->module; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function reParse() { $this->reParse = true; } } class WindUrlBasedRouter extends AbstractWindRouter { const URL_PARAM = 'url-param'; const DEFAULT_VALUE = 'default-value'; const CONTROLLER_SUFFIX = 'controller-suffix'; const ACTION_SUFFIX = 'action-suffix'; const URL_RULE_MODULE = 'module'; const URL_RULE_CONTROLLER = 'controller'; const URL_RULE_ACTION = 'action'; public function parse() { $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->getModule())); $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->getController())); $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->getAction())); } public function buildUrl() { $module = $this->getUrlParamValue(self::URL_RULE_MODULE); $controller = $this->getUrlParamValue(self::URL_RULE_CONTROLLER); $action = $this->getUrlParamValue(self::URL_RULE_ACTION); $url = '?' . $module . '=' . $this->getModule(); $url .= '&' . $controller . '=' . $this->getController(); $url .= '&' . $action . '=' . $this->getAction(); return $url; } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, self::URL_PARAM)) { $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE, $defaultValue); return $this->getRequest()->getRequest($_param, $defaultValue); } return $defaultValue; } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $urlHelper = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); Wind::log('[core.web.controller.WindSimpleController.doAction] resolved action method:' . $method, WindLogger::LEVEL_INFO, 'wind.core'); call_user_func_array(array($this, $method), array()); $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '', $errorController = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->setErrorController($errorController); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getUrlHelper() { return $this->_getUrlHelper(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; public function run() {} final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } } protected function setDefaultTemplateName($handlerAdapter) { $_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); $this->setTemplate($_temp); } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); try { if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) throw new WindException( '[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); return $action; } catch (Exception $exception) { throw new WindException( '[core.web.WindController.resolvedActionMethod] action method:' . $action . ' exception message:' . $exception->getMessage()); } } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('WIND:core.filter.WindFilter'); class WindLoggerFilter extends WindFilter { public function preHandle($request = null, $response = null) { if (!IS_DEBUG) return; $this->initWindLogger($request); $this->logger->info('-------------------------------request start!!!!--------------------------------'); } public function postHandle($request = null, $response = null) { if (!IS_DEBUG) return; $this->logger->info('---------------------------------request end!!!!---------------------------------'); if ($this->logger instanceof WindLogger) $this->logger->flush(); } private function initWindLogger($request) { $windFactory = $request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $windFactory->getInstance(COMPONENT_LOGGER); } } Wind::import('WIND:core.filter.WindFilter'); class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { $windFactory = $request->getAttribute(WindFrontController::WIND_FACTORY); $this->urlHelper = $windFactory->getInstance(COMPONENT_URLHELPER); $this->urlHelper->parseUrl(); } public function postHandle($request = null, $response = null) { } } interface IWindApplication { public function processRequest(); public function doDispatch($forward); } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } Wind::import('WIND:core.filter.WindHandlerInterceptor'); class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException('the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet($_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('WIND:core.filter.WindHandlerInterceptor'); Wind::import('WIND:component.log.WindLogger'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim($trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('WIND:core.filter.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost($key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError(($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); Wind::import('WIND:core.factory.WindFactory'); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $urlHelper = null; protected $display = false; public function dispatch($app, $forward, $router) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($app, $forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($app, $forward, $router); else $this->render($app, $forward, $router); $this->destroy(); } protected function dispatchWithRedirect($app, $forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindException('[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request ', WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($app, $forward, $router) { $this->getRequest()->setAttribute($forward->getVars(), $router->getAction() . '_' . $router->getController()); $this->setDisplay($forward->getDisplay()); list($_c, $_m) = WindHelper::resolveController($forward->getController()); $_a = $forward->getAction(); $_a && $router->setAction($_a); $_c && $router->setController($_c); $_m && $router->setModule($_m); if (!$this->checkProcess($router)) { throw new WindException('[core.web.WindDispatcher.dispatchWithAction] Duplicate request ', WindException::ERROR_SYSTEM_ERROR); } $app->processRequest(); } protected function render($app, $forward, $router) { try { if ($windViewClass = $forward->getWindView()) $view = $this->getSystemFactory()->createInstance($windViewClass); elseif ($windViewClass = $this->getSystemConfig()->getModuleViewClassByModuleName($router->getModule())) $view = $this->getSystemFactory()->getInstance($windViewClass); else $view = $this->getSystemFactory()->getInstance(COMPONENT_VIEW); $view->setConfig($this->getSystemConfig()->getModuleViewConfigByModuleName($router->getModule())); $view->render($forward, $router, $this->getDisplay()); } catch (Exception $e) { throw new WindViewException('[core.web.WindDispatcher.render] view render fail.' . $e->getMessage()); } } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === $this->processCache['action'] && $router->getController() === $this->processCache['controller'] && $router->getModule() === $this->processCache['module']) return false; return true; } protected function destroy() { $this->processCache = array(); $this->setDisplay(false); } public function getDisplay() { return $this->display; } public function setDisplay($display) { $this->display = $display; } public function getUrlHelper() { return $this->_getUrlHelper(); } public function setUrlHelper($urlHelper) { $this->urlHelper = $urlHelper; } } class WindErrorHandler extends WindController { protected $error = array(); protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->request->getUrlReferer(); else $this->urlReferer = $this->request->getBaseUrl(); return true; } public function run() { $_tmp = "User Message:\r\n"; $i = 0; foreach ($this->error as $key => $value) { $i++; $_tmp .= "#$i " . $value . "\r\n"; } echo "

User Message: (" . count($this->error) . ")

"; echo "

" . nl2br($_tmp) . "

"; echo "Click to go back."; Wind::log('User Error:', $_tmp); exit(); } final public function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { $errfile = $this->getFile($errfile); $_tmp = "$errstr ($errfile:$errline)\r\nStack trace:\r\n"; $_trace = debug_backtrace(); foreach ($_trace as $key => $value) { if (!isset($value['file'])) continue; if (!isset($value['line'])) $value['line'] = 0; if (!isset($value['function'])) continue; $_tmp .= "#$key {$value['file']}({$value['line']}): "; if (isset($value['object']) && is_object($value['object'])) $_tmp .= get_class($value['object']) . '->'; $_tmp .= "{$value['function']}()\r\n"; } if (IS_DEBUG) { echo "

" . $this->errnoMap($errno) . " $errstr

"; echo "

" . nl2br($_tmp) . "

"; } else echo "

" . $this->errnoMap($errno) . " $errstr

"; Wind::log($this->errnoMap($errno) . $errstr, $_tmp); exit(); } } private function errnoMap($errno) { $_tmp = ''; switch ($errno) { case E_ERROR: $_tmp = "Error"; break; case E_WARNING: $_tmp = "Warning"; break; case E_PARSE: $_tmp = "Parse Error"; break; case E_NOTICE: $_tmp = "Notice"; break; case E_CORE_ERROR: $_tmp = "Core Error"; break; case E_CORE_WARNING: $_tmp = "Core Warning"; break; case E_COMPILE_ERROR: $_tmp = "Compile Error"; break; case E_COMPILE_WARNING: $_tmp = "Compile Warning"; break; case E_USER_ERROR: $_tmp = "User Error"; break; case E_USER_WARNING: $_tmp = "User Warning"; break; case E_USER_NOTICE: $_tmp = "User Notice"; break; case E_STRICT: $_tmp = "Strict Notice"; break; case E_RECOVERABLE_ERROR: $_tmp = "Recoverable Error"; break; default: $_tmp = "Unknown error ($errno)"; break; } return $_tmp; } final public function exceptionHandle($exception) { $_tmp = $exception->getMessage() . ' (' . $this->getFile($exception->getFile()) . ':' . $exception->getLine() . ')'; if (IS_DEBUG) { echo '

' . get_class($exception) . '

'; echo "

$_tmp

"; echo '
' . $exception->getTraceAsString() . '
'; } else { echo '

' . get_class($exception) . '

'; echo '

' . $exception->getMessage() . '

'; } Wind::log("$_tmp:" . $exception->getTraceAsString()); exit(); } private function getFile($filePath) { return $filePath; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction = 'run'; private $errorController = WIND_M_ERROR; public function __construct($message = '', $errorAction = '', $errorController = '') { $this->addError($message); $this->setErrorAction($errorAction); $this->setErrorController($errorController); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; else return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if (!$error) return; if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function getErrorController() { return $this->errorController; } public function setErrorAction($errorAction) { if ($errorAction) $this->errorAction = $errorAction; } public function setErrorController($errorController) { if ($errorController) $this->errorController = $errorController; } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath; private $templateExt; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; private $display = false; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } public function getDisplay() { return $this->display; } public function setDisplay($display) { $this->display = $display; } } class WindFrontController { const WIND_SYSTEM_CONFIG = 'WIND:core.config.WindSystemConfig'; const WIND_SYSTEM_FACTORY = 'WIND:core.factory.WindFactory'; const WIND_COMPONENT_CONFIG_RESOURCE = 'WIND:components_config.php'; private $request; private $response; protected $windSystemConfig = null; protected $windFactory = null; public function __construct($appName, $config = '') { try { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(); $this->initWindConfig($appName, $config); $this->initWindFactory(); } catch (Exception $exception) { throw new Exception('System failed to initialize.' . $exception->getMessage()); } } public function run() { $this->beforeProcess(); $appName = $this->windSystemConfig->getAppClass(); $application = $this->windFactory->getInstance($appName); if ($application === null) { throw new WindException($appName . '[core.web.WindFrontController.process]', WindException::ERROR_CLASS_NOT_EXIST); } $routerAlias = $this->windSystemConfig->getRouterClass(); $application->setDelayAttributes(array('handlerAdapter' => array('ref' => $routerAlias))); if (null !== ($filterChain = $this->getFilterChain())) { $filterChain->setCallBack(array($application, 'processRequest'), array()); $filterChain->getHandler()->handle($this->request, $this->response); } else $application->processRequest($this->request, $this->response); $this->afterProcess(); } protected function getFilterChain() { $filterChainPath = $this->windSystemConfig->getFilterClass(); $filters = $this->windSystemConfig->getFilters(); if (empty($filters) || empty($filterChainPath)) return null; if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( "[core.WindFrontController.getFilterChain] an filter chain defined.(" . $filterChainPath . "," . count($filters) . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); } return $this->windFactory->createInstance($filterChainPath, array($filters)); } protected function initWindFactory() { $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); $factoryClass = Wind::import(self::WIND_SYSTEM_FACTORY); $this->windFactory = new $factoryClass(@include ($configPath)); if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.web.WindFrontController.initWindFactory] system factory:' . self::WIND_SYSTEM_FACTORY, WindLogger::LEVEL_DEBUG, 'wind.core'); } } protected function initWindConfig($appName, $config) { !$appName && $appName = 'default'; $this->windSystemConfig = new WindSystemConfig($config, new WindConfigParser(), $appName); Wind::register($this->windSystemConfig->getRootPath(), $this->windSystemConfig->getAppName(), true); if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( '[core.web.WindFrontController.initWindConfig] rootPath:' . $this->windSystemConfig->getRootPath() . ' appName:' . $this->windSystemConfig->getAppName(), WindLogger::LEVEL_DEBUG, 'wind.core'); } } protected function beforeProcess() {} protected function afterProcess() { $this->response->sendResponse(); } public function getWindSystemConfig() { return $this->windSystemConfig; } public function getWindFactory() { return $this->windFactory; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } } class WindUrlHelper extends WindModule { const URL_PATTERN = 'url-pattern'; const ROUTE_SUFFIX = 'route-suffix'; const ROUTE_PARAM = 'route-param'; const REWRITE = false; const ROUTE_SEPARATOR = '_'; protected $routeSuffix = ''; protected $routeParam = ''; protected $urlPattern = ''; protected $windRouter = null; public function isRewrite() { return self::REWRITE; } public function parseUrl() { if ((($uri = $this->request->getServer('QUERY_STRING')) == '') || !$this->isRewrite()) return; if (($pattern = $this->getUrlPattern()) == '') return; $seperator = isset($pattern[1]) ? $pattern[1] : $pattern[0]; $uri = explode($seperator, $uri); if (strcasecmp($pattern, "=&") != 0) $params = $this->parseUrlToParams($uri, $seperator, $pattern[0]); $_GET = array_merge($_GET, $params); $this->matchRouter(array_pop($uri)); } public function createUrl($action, $controller, $params = array()) { $action && $this->getWindRouter()->setAction($action); list($_c, $_m) = WindHelper::resolveController($controller); $_c && $this->getWindRouter()->setController($_c); $_m && $this->getWindRouter()->setModule($_m); $url = $this->getWindRouter()->buildUrl(); $server = $this->getUrlServer(); if ($this->isRewrite()) { $server = substr($server, 0, strrpos($server, '/')); $url = $server . $this->buildRewriteURL($params, $url); } else { $url = $server . $url . '&' . $this->buildUrl($params); } return $url; } private function getUrlServer($hasPath = true) { list($protocol, ) = explode('/', $this->request->getProtocol()); $protocol = strtolower($protocol) . '://' . $this->request->getServer('SERVER_NAME'); ($hasPath) && $protocol .= $this->request->getServer('PHP_SELF'); return $protocol; } private function matchRouter($mca) { if (strrpos($mca, '.' . $this->getRouteSuffix()) === false) return; $mca = trim(rtrim($mca, '.' . $this->getRouteSuffix())); if ($mca == '') return; $mca = explode(self::ROUTE_SEPARATOR, $mca); $m = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_MODULE); $c = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_CONTROLLER); $a = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_ACTION); if (count($mca) == 1) { $_GET[$c] = $mca[0]; } elseif (count($mca) == 2) { $_GET[$c] = $mca[0]; $_GET[$a] = $mca[1]; } else { ($mca[0]) && $_GET[$m] = $mca[0]; ($mca[1]) && $_GET[$c] = $mca[1]; ($mca[2]) && $_GET[$a] = $mca[2]; } return; } private function parseUrlToParams($url, $seprator = '', $keyAsValue = '=') { $params = array(); if ($seprator == $keyAsValue) { $n = count($url); for ($i = 0; $i < $n / 2; $i++) { $k = 2 * $i; $v = $k + 1; if (isset($url[$v])) { $this->parseKey($params, $url[$k], $url[$v]); } } return $params; } foreach ((array) $url as $key => $value) { if (strpos($value, $keyAsValue) === false) continue; list($key, $value) = explode($keyAsValue, $value); $this->parseKey($params, $key, $value); } return $params; } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } private function getUrlParamConfig($type) { $_config = $this->getWindRouter()->getConfig(WindUrlBasedRouter::URL_RULE); if ($_param = $this->getConfig($type, WindUrlBasedRouter::URL_PARAM, $_config)) { return $_param; } return $type; } private function getSeparator() { (($pattern = $this->getUrlPattern()) == '') && $pattern = '=&'; $separator = isset($pattern[1]) ? $pattern[1] : $pattern[0]; return array($pattern[0], $separator); } private function buildRewriteURL($params, $routerInfo) { $routerInfo = $this->parseUrlToParams(explode('&', trim($routerInfo, '?')), '&', '='); $routerInfo = implode(self::ROUTE_SEPARATOR, $routerInfo) . '.' . $this->getRouteSuffix(); $separator = $this->getSeparator(); if (empty($params)) return $separator[1] . $routerInfo; $url = ''; foreach ((array) $params as $key => $value) { $url .= $this->buildKey($key, $value, $separator[0], $separator[1]) . $separator[1]; } return $separator[1] . $url . $routerInfo; } private function buildKey($parentKey, $parentValue, $keyAsValue, $separator, $flag = false) { $flag && $parentKey = is_numeric($parentKey) ? '[]' : '[' . $parentKey . ']'; if (!is_array($parentValue)) return $parentKey . $keyAsValue . urlencode($parentValue); $keys = array(); foreach ($parentValue as $key => $value) { $keys[] = $parentKey . $this->buildKey($key, $value, $keyAsValue, $separator, true); } return implode($separator, $keys); } private function buildUrl($params) { if (empty($params)) return ''; $url = ''; foreach ((array) $params as $key => $value) { $url .= $this->buildKey($key, $value, '=', '&', false) . '&'; } return trim($url, '&'); } public function checkUrl($url) { list($protocal, $serverName) = explode('://', $this->getUrlServer(false)); $pos1 = stripos($url, $protocal); $pos2 = stripos($url, $serverName); if (false === $pos1 && false === $pos2) return $protocal . '://' . $serverName . '/' . ltrim($url, '/'); if (false === $pos1) return $protocal . '://' . ltrim($url, '/'); return $url; } public function getRouteSuffix() { if ($this->routeSuffix === '') { $this->routeSuffix = $this->getConfig(self::ROUTE_SUFFIX, WindSystemConfig::VALUE); } return $this->routeSuffix; } public function getRouteParam() { if ($this->routeParam === '') { $this->routeParam = $this->getConfig(self::ROUTE_PARAM, WindSystemConfig::VALUE); } return $this->routeParam; } public function getUrlPattern() { if ($this->urlPattern === '') { $this->urlPattern = $this->getConfig(self::URL_PATTERN, WindSystemConfig::VALUE); } return $this->urlPattern; } public function setRouteSuffix($routeSuffix) { $this->routeSuffix = $routeSuffix; } public function setRouteParam($routeParam) { $this->routeParam = $routeParam; } public function setUrlPattern($urlPattern) { $this->urlPattern = $urlPattern; } public function getWindRouter() { return $this->windRouter; } public function setWindRouter($windRouter) { $this->windRouter = $windRouter; } } class WindWebApplication extends WindModule implements IWindApplication { protected $dispatcher = null; protected $handlerAdapter = null; public function processRequest() { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.web.WindWebApplication.processRequest]', WindLogger::LEVEL_DEBUG, 'wind.core'); } $handler = $this->getHandler(); call_user_func_array(array($handler, 'preAction'), array($this->handlerAdapter)); $forward = call_user_func_array(array($handler, 'doAction'), array($this->handlerAdapter)); call_user_func_array(array($handler, 'postAction'), array($this->handlerAdapter)); $this->doDispatch($forward); } catch (WindActionException $actionException) { $this->sendErrorMessage($actionException); } catch (WindDbException $dbException) { $this->sendErrorMessage($dbException->getMessage()); } catch (WindViewException $viewException) { throw new Exception($viewException->getMessage()); } } public function doDispatch($forward) { if ($forward === null) { Wind::log('[core.web.WindWebApplication.doDispatch] Forward is null, dispatch abort.', WindLogger::LEVEL_DEBUG, 'wind.core'); return; } $this->getDispatcher()->dispatch($this, $forward, $this->handlerAdapter); } protected function getHandler() { $handler = $this->getHandlerAdapter()->doParse(); if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.web.WindWebApplication.getHandler] router result:' . $handler, WindLogger::LEVEL_DEBUG, 'wind.core'); } if (!$this->getSystemFactory()->checkAlias($handler)) { $definition = new WindClassDefinition(); $definition->setPath($handler); $definition->setScope(WindClassDefinition::SCOPE_SINGLETON); $definition->setAlias($handler); $definition->setProxy('true'); $definition->setProperties( array('errorMessage' => array('ref' => COMPONENT_ERRORMESSAGE), 'forward' => array('ref' => COMPONENT_FORWARD), 'urlHelper' => array('ref' => COMPONENT_URLHELPER))); $this->getSystemFactory()->addClassDefinitions($definition); } return $this->getSystemFactory()->getInstance($handler); } protected function sendErrorMessage($actionException) { $_tmp = is_object($actionException) ? $actionException->getError() : $actionException; if (is_string($_tmp)) $_tmp = new WindErrorMessage($_tmp); $forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD); $forward->forwardAnotherAction($_tmp->getErrorAction(), $_tmp->getErrorController()); $this->getRequest()->setAttribute('error', $_tmp->getError()); $this->doDispatch($forward); } protected function getHandlerAdapter() { return $this->_getHandlerAdapter(); } protected function getDispatcher() { return $this->_getDispatcher(); } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array( $this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array( $this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array( $input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array( $this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array( $input, $setMethod), array( $rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); Wind::import('WIND:core.factory.WindFactory'); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindHelper { public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } ?> \ No newline at end of file From 75b6060b3c3fae21902e4c02519eb37e49644180 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 08:15:00 +0000 Subject: [PATCH 0109/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2167 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindView.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index f87418d0..c5587db5 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -68,6 +68,7 @@ class WindView extends WindModule { * @param WindUrlBasedRouter $router */ public function render($forward, $router, $display = false) { + $this->init(); if (!($_templateName = $forward->getTemplateName())) { Wind::log('[component.viewer.WindView.render] view render fail. TemplateName is not defined.', WindLogger::LEVEL_DEBUG, 'wind.component'); From 26d910568ef936adcc45efa1522569c0e2a933d9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 10:43:21 +0000 Subject: [PATCH 0110/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2168 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index c10da5ad..ceb77288 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -410,7 +410,50 @@ private static function _checkPhpVersion() { * @return */ private static function _coreLib() { - return array(); + return array( + 'WindLogger' => 'COM:log.WindLogger', + 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', + 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', + 'WindConfig' => 'WIND:core.config.WindConfig', + 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', + 'WindActionException' => 'WIND:core.exception.WindActionException', + 'WindException' => 'WIND:core.exception.WindException', + 'WindFinalException' => 'WIND:core.exception.WindFinalException', + 'IWindFactory' => 'WIND:core.factory.IWindFactory', + 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', + 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', + 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', + 'WindFactory' => 'WIND:core.factory.WindFactory', + 'WindFilter' => 'WIND:core.filter.WindFilter', + 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', + 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', + 'IWindRequest' => 'WIND:core.request.IWindRequest', + 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', + 'IWindResponse' => 'WIND:core.response.IWindResponse', + 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', + 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', + 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', + 'IWindController' => 'WIND:core.web.controller.IWindController', + 'WindController' => 'WIND:core.web.controller.WindController', + 'WindSimpleController' => 'WIND:core.web.controller.WindSimpleController', + 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', + 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', + 'IWindApplication' => 'WIND:core.web.IWindApplication', + 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', + 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', + 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', + 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', + 'WindDispatcher' => 'WIND:core.web.WindDispatcher', + 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', + 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', + 'WindForward' => 'WIND:core.web.WindForward', + 'WindFrontController' => 'WIND:core.web.WindFrontController', + 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', + 'WindWebApplication' => 'WIND:core.web.WindWebApplication', + 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', + 'WindHelper' => 'WIND:core.WindHelper', + 'WindModule' => 'WIND:core.WindModule'); } } Wind::init(); From cce822d5a97f1515b91ae5535ef5ef0a54482106 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 11:47:39 +0000 Subject: [PATCH 0111/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2169 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 7 +++---- wind/core/response/WindHttpResponse.php | 13 ++----------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index ceb77288..acb9e901 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -147,7 +147,7 @@ public static function import($filePath, $recursivePackage = false) { */ public static function register($path, $alias = '', $includePath = false, $reset = false) { if (!$path) return; - $alias = strtolower(trim($alias)); + $alias = strtolower($alias); if (!empty($alias)) { if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = $path; } @@ -206,18 +206,17 @@ public static function getRootPath($namespace = '') { * @return string|array('isPackage','fileName','extension','realPath') */ public static function getRealPath($filePath, $isDir = false) { - $filePath = trim($filePath, ' '); $namespace = $suffix = ''; if (!$isDir) { $_pos1 = strrpos($filePath, '.'); - $suffix = trim(substr($filePath, $_pos1 + 1), '.'); + $suffix = substr($filePath, $_pos1 + 1); $filePath = substr($filePath, 0, $_pos1); } if (($pos = strpos($filePath, ':')) !== false) { $namespace = self::getRootPath(substr($filePath, 0, $pos)); } $filePath = str_replace('.', D_S, $filePath); - if ($namespace) $filePath = rtrim($namespace, D_S) . D_S . substr($filePath, $pos + 1); + if ($namespace) $filePath = $namespace . D_S . substr($filePath, $pos + 1); return $suffix ? $filePath . '.' . $suffix : $filePath; } diff --git a/wind/core/response/WindHttpResponse.php b/wind/core/response/WindHttpResponse.php index 6c587509..977fb52a 100644 --- a/wind/core/response/WindHttpResponse.php +++ b/wind/core/response/WindHttpResponse.php @@ -1,12 +1,4 @@ 2010-11-8 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.response.IWindResponse'); /** * 1xx:信息,请求收到,继续处理 * 2xx:成功,行为被成功地接受、理解和采纳 @@ -310,7 +302,7 @@ class WindHttpResponse implements IWindResponse { * @param string $value 响应头的字段取值 */ public function setHeader($name, $value, $replace = false) { - if (trim($name) == '' || trim($value) == '') return; + if (!$name || !$value) return; $name = $this->_normalizeHeader($name); foreach ($this->_headers as $key => $one) { ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, @@ -325,7 +317,7 @@ public function setHeader($name, $value, $replace = false) { * @param string $value 响应头的字段取值 */ public function addHeader($name, $value, $replace = false) { - if (trim($name) == '' || trim($value) == '') return; + if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } @@ -480,7 +472,6 @@ public function clearHeaders() { * @return string */ private function _normalizeHeader($name) { - if (trim($name) == '') return ''; $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); From ce0742d27f9a2992cac7aa30045cb3d75120e157 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 11:52:27 +0000 Subject: [PATCH 0112/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2170 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index acb9e901..50d9fb8e 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -347,7 +347,7 @@ function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/G * @return */ private static function _setImport($className, $classPath) { - if (self::_isImported($className)) return; +// if (self::_isImported($className)) return; self::$_imports[$classPath] = $className; if (self::$_isAutoLoad) self::$_classes[$className] = $classPath; From 3a71fdc5161e34cc73e070e92ec517de4f6327c4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 12:03:31 +0000 Subject: [PATCH 0113/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2171 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindClassDefinition.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/wind/core/factory/WindClassDefinition.php b/wind/core/factory/WindClassDefinition.php index 56b6444b..d2d99250 100644 --- a/wind/core/factory/WindClassDefinition.php +++ b/wind/core/factory/WindClassDefinition.php @@ -170,7 +170,6 @@ protected function createInstance($factory, $args) { $this->buildConfig($instance, $factory); $this->buildProperties($instance, $factory); $this->executeInitMethod($instance); - $this->setHiddenProperty($instance, $factory); $instance = $this->setProxyForClass($instance, $factory); } return $instance; @@ -191,20 +190,6 @@ protected function buildConfig($instance, $factory) { $instance->setConfig($config); } - /** - * 设置变量隐藏属性 - * - * @param WindModule $instance - * @param WindFactory $factory - * @return - */ - protected function setHiddenProperty($instance, $factory) { - $instance->systemConfig = Wind::getApp()->getWindSystemConfig(); - $instance->request = Wind::getApp()->getRequest(); - $instance->response = Wind::getApp()->getResponse(); - $instance->systemFactory = $factory; - } - /** * 为类设置代理 * From e1e1b611ee2422ecfbd7655c252fa42dc974c87e Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 12:50:31 +0000 Subject: [PATCH 0114/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2172 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindModule.php | 46 ++++++++--------------- wind/core/factory/WindClassDefinition.php | 14 ++----- wind/core/factory/WindFactory.php | 18 +++------ 3 files changed, 24 insertions(+), 54 deletions(-) diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index df4ac025..9455e50d 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -39,15 +39,12 @@ class WindModule { * @return */ public function __set($propertyName, $value) { - if (!$this->validatePropertyName($propertyName)) { - $_setter = 'set' . ucfirst($propertyName); - if (method_exists($this, $_setter)) - $this->$_setter($value); - else - Wind::log('[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, - WindLogger::LEVEL_DEBUG, 'wind.core'); - } else - $this->$propertyName = $value; + $_setter = 'set' . ucfirst($propertyName); + if (method_exists($this, $_setter)) + $this->$_setter($value); + else + Wind::log('[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, + WindLogger::LEVEL_DEBUG, 'wind.core'); } /** @@ -57,15 +54,12 @@ public function __set($propertyName, $value) { * @return value of the property or null */ public function __get($propertyName) { - if (!$this->validatePropertyName($propertyName)) { - $_getter = 'get' . ucfirst($propertyName); - if (method_exists($this, $_getter)) - return $this->$_getter(); - else - Wind::log('[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, - WindLogger::LEVEL_DEBUG, 'wind.core'); - } else - return $this->$propertyName; + $_getter = 'get' . ucfirst($propertyName); + if (method_exists($this, $_getter)) + return $this->$_getter(); + else + Wind::log('[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, + WindLogger::LEVEL_DEBUG, 'wind.core'); } /** @@ -82,10 +76,7 @@ public function __call($methodName, $args) { if ($_prefix == '_set') { $this->$_propertyName = $args[0]; } elseif ($_prefix == '_get') { - if (property_exists($this, $_propertyName) && $this->$_propertyName) { - return $this->$_propertyName; - } - if (isset($this->delayAttributes[$_propertyName])) { + if (!$this->$_propertyName && isset($this->delayAttributes[$_propertyName])) { $_instance = null; $_property = $this->delayAttributes[$_propertyName]; if (isset($_property[WindClassDefinition::REF])) { @@ -96,14 +87,7 @@ public function __call($methodName, $args) { $_instance = $this->getSystemFactory()->createInstance($_ref); } $this->$_propertyName = $_instance; - Wind::log("[core.WindMOdule.__call] create property $_propertyName fail.", WindLogger::LEVEL_DEBUG, - 'wind.core'); - - // unset($this->delayAttributes[$_propertyName]); } - Wind::log("[core.WindModule.__call] attribute is not exist. - (" . $methodName . ")", WindLogger::LEVEL_DEBUG, - 'wind.core'); return $this->$_propertyName; } throw new WindException('[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', @@ -147,7 +131,7 @@ public function toArray() { /** * 验证白名单是否为空,或属性值是否存在于定义的白名单中 - * + * @deprecated * @param string $propertyName * @return boolean */ @@ -220,7 +204,7 @@ public function setConfig($config) { /** * 设置自动实现Getter/Setter方法的属性名称 * 当该方法返回值为空时,类属性的可访问性跟默认相同 - * + * @deprecated * @return array */ protected function writeTableForProperty() { diff --git a/wind/core/factory/WindClassDefinition.php b/wind/core/factory/WindClassDefinition.php index d2d99250..efc71c37 100644 --- a/wind/core/factory/WindClassDefinition.php +++ b/wind/core/factory/WindClassDefinition.php @@ -198,16 +198,10 @@ protected function buildConfig($instance, $factory) { * @return WindClassProxy */ protected function setProxyForClass($instance, $factory) { - if (!($proxy = $this->getProxy()) || $proxy === 'false' || $proxy === false) return $instance; - if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyClass; - $proxy = $factory->createInstance($proxy, array($instance)); - if ($proxy !== null) return $proxy; - Wind::log( - '[core.factory.WindClassDefinition.setProxyForClass] create proxy for ' . $this->getClassName() . ' fail.', - WindLogger::LEVEL_DEBUG, 'wind.core'); - throw new WindException( - '[core.factory.WindClassDefinition.setProxyForClass] create proxy for ' . $this->getClassName() . ' fail.', - WindException::ERROR_SYSTEM_ERROR); + if (!($proxy = $this->getProxy())) return $instance; + if ($proxy === 'false' || $proxy === false) return $instance; + $proxy = Wind::import($this->proxyClass); + return $factory->createInstance($proxy, array($instance)); } /** diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 41e8360c..b7813992 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -11,12 +11,6 @@ * @package */ class WindFactory implements IWindFactory { - /** - * 类定义类型,默认为WindClassDefinition - * - * @var string - */ - protected $classDefinitionType = 'WIND:core.factory.WindClassDefinition'; /** * 类定义集合 * @@ -66,13 +60,11 @@ public function getPrototype($alias) { */ static public function createInstance($className, $args = array()) { try { - if (!$className) return null; - if (strpos($className, ':') !== false) $className = Wind::import($className); + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, + WindLogger::LEVEL_DEBUG, 'core.factory'); + } $reflection = new ReflectionClass($className); - if ($reflection->isAbstract() || $reflection->isInterface()) return null; - - Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_INFO, - 'core.factory'); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); @@ -98,7 +90,7 @@ public function setSingled($classAlias, $instance) { protected function getClassDefinitionByAlias($classAlias) { if (!($definition = $this->classDefinitions[$classAlias])) return null; if ($definition instanceof WindClassDefinition) return $definition; - $classDefinition = self::createInstance($this->classDefinitionType, array($definition)); + $classDefinition = self::createInstance('WindClassDefinition', array($definition)); $classDefinition->setAlias($classAlias); $this->addClassDefinitions($classDefinition); return $classDefinition; From 8a247d21595fa70814b4b7d084b12824b06ffafe Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 19 Jul 2011 12:56:21 +0000 Subject: [PATCH 0115/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2173 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 6 ++++-- wind/core/router/AbstractWindRouter.php | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index b7813992..3288451d 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -76,8 +76,10 @@ static public function createInstance($className, $args = array()) { * @return boolean */ public function setSingled($classAlias, $instance) { - Wind::log('[core.factory.WindFactory.createInstance] create singled instance:' . $classAlias, - WindLogger::LEVEL_INFO, 'core.factory'); + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log('[core.factory.WindFactory.createInstance] create singled instance:' . $classAlias, + WindLogger::LEVEL_DEBUG, 'core.factory'); + } $this->instances[$classAlias] = $instance; } diff --git a/wind/core/router/AbstractWindRouter.php b/wind/core/router/AbstractWindRouter.php index d393c896..c4f771f5 100644 --- a/wind/core/router/AbstractWindRouter.php +++ b/wind/core/router/AbstractWindRouter.php @@ -71,8 +71,6 @@ public function doParse() { if ($this->reParse) { $this->parse(); $this->reParse = false; - Wind::log('[core.router.AbstractWindRouter.doParse] parse the request.', WindLogger::LEVEL_DEBUG, - 'wind.core'); } $_suffix = $this->getSystemConfig()->getModuleControllerSuffixByModuleName($_moduleName, self::CONTROLLER_DEFAULT_SUFFIX); From efd31f82f5e1eb66871b1d2afa67d3de63e8defb Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 02:10:37 +0000 Subject: [PATCH 0116/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=E5=A4=9A?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E6=94=AF=E6=8C=81=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=EF=BC=8C=E5=8A=A0=E8=BD=BD=E7=9A=84=E6=96=87=E4=BB=B6=E5=88=A4?= =?UTF-8?q?=E6=96=AD=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2174 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index 50d9fb8e..3e1f321a 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -347,7 +347,8 @@ function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/G * @return */ private static function _setImport($className, $classPath) { -// if (self::_isImported($className)) return; + //if (self::_isImported($className)) return; + if (strpos($classPath, ':') === false) $classPath = strtoupper(self::getAppName()) . ':' . $classPath; self::$_imports[$classPath] = $className; if (self::$_isAutoLoad) self::$_classes[$className] = $classPath; From 698361fe902d8382edf8da3db0489aeaff6bf4bd Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 03:11:56 +0000 Subject: [PATCH 0117/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E4=B9=8B=E5=90=8E=E8=8E=B7=E5=8F=96=E5=80=BC=EF=BC=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2175 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/router/AbstractWindRouter.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wind/core/router/AbstractWindRouter.php b/wind/core/router/AbstractWindRouter.php index c4f771f5..75722121 100644 --- a/wind/core/router/AbstractWindRouter.php +++ b/wind/core/router/AbstractWindRouter.php @@ -58,6 +58,10 @@ abstract public function buildUrl(); * @return */ public function doParse() { + if ($this->reParse) { + $this->parse(); + $this->reParse = false; + } $_moduleName = $this->getModule(); if (!strcasecmp($this->getController(), WIND_M_ERROR)) { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { @@ -68,10 +72,6 @@ public function doParse() { return $this->getSystemConfig()->getModuleErrorHandlerByModuleName($_moduleName, self::DEFAULT_ERROR_HANDLER); } - if ($this->reParse) { - $this->parse(); - $this->reParse = false; - } $_suffix = $this->getSystemConfig()->getModuleControllerSuffixByModuleName($_moduleName, self::CONTROLLER_DEFAULT_SUFFIX); if ($this->modulePath) From f3b722fe314fe9ff3074e320a343a97193738c30 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 03:12:34 +0000 Subject: [PATCH 0118/1065] =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2176 18ba2127-5a84-46d4-baec-3457e417f034 --- .../WindTemplateCompilerComponent.php | 129 +++++++++++++++--- 1 file changed, 110 insertions(+), 19 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php index e725fd1d..0ab21acb 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php @@ -1,50 +1,141 @@ - * @author Qiong Wu - * @version $Id$ - * @package + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-20 xiaoxiao */ class WindTemplateCompilerComponent extends AbstractWindTemplateCompiler { protected $name = ''; - protected $app = ''; - protected $args = ''; - protected $tpl = ''; + protected $templateDir = ''; + + protected $appConfig = ''; + + protected $componentPath = ''; /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() */ public function compile($key, $content) { - $_output .= $this->getScript() . ''; - return $_output; + return $this->getScript($content); } /** * @return string */ - private function getScript() { - $_tmp = ''; - - return $_tmp; + private function getScript($content) { + $params = $this->matchConfig($content); + if (!isset($params['name']) || !isset($params['componentPath'])) throw new WindException('组件编译错误!'); + $content = "rebuildConfig($params) . (isset($params['args']) ? $this->registerUrlParams($params) : '') . + "\$componentPath = Wind::getRealPath('" . $params['componentPath'] . "', true);\r\n" . + "Wind::register(\$componentPath, '" . $params['name'] . "');\r\n" . + "Wind::run('" . $params['name'] . "', \$config);\r\n?>"; + return $content; } - + /** - * @return string + * 编译获得配置文件 + * @param array $params + * @return array */ - private function getTplContent() { - + private function rebuildConfig($params) { + $temp = "\$configParser = new WindConfigParser();\r\n" . + "\$configPath = Wind::getRealPath('" . $params['appConfig'] . "');\r\n"; + $temp .= "\$config = \$configParser->parse(\$configPath, '" . $params['name'] . "');\r\n"; + if (!isset($params['templateDir'])) return $temp; + if (isset($params['args']['m'])) $temp .= "\$config['web-apps']['" . $params['name'] . "']['modules']['" . $params['args']['m'] . "']['view']['config']['template-dir']['value'] = '" . $params['templateDir'] . "';\r\n"; + else { + $temp .= "foreach(\$config['web-apps']['" . $params['name'] . "']['modules'] as \$key => \$value) {\r\n" . + "\t\$config['web-apps']['" . $params['name'] . "']['modules'][\$key]['view']['config']['template-dir']['value'] = '" . $params['templateDir'] . "';\r\n" . + "}\r\n"; + } + return $temp; } + + /** + * 注册变量信息 + * + * @param array $params + */ + private function registerUrlParams($params) { + $temp = ''; + $temp = "\$mKey = isset(\$config['web-apps']['" . $params['name'] . "']['router']['config']['module']['url-param']) ? \$config['web-apps']['" . $params['name'] . "']['router']['config']['module']['url-param'] : 'm';\r\n" . + "\$cKey = isset(\$config['web-apps']['" . $params['name'] . "']['router']['config']['controller']['url-param']) ? \$config['web-apps']['" . $params['name'] . "']['router']['config']['controller']['url-param'] : 'c';\r\n" . + "\$aKey = isset(\$config['web-apps']['" . $params['name'] . "']['router']['config']['action']['url-param']) ? \$config['web-apps']['" . $params['name'] . "']['router']['config']['action']['url-param'] : 'a';\r\n" . + "\$_GET[\$mKey] = '" . $params['args']['m'] . "';\r\n" . + "\$_GET[\$cKey] = '" . $params['args']['c'] . "';\r\n" . + "\$_GET[\$aKey] = '" . $params['args']['a'] . "';\r\n"; + unset($params['args']['a'], $params['args']['c'], $params['args']['m']); + foreach($params['args'] as $key => $value) { + $temp .= is_array($value) ? "\$_GET['" . $key . "'] = " . $value . ";\r\n" : "\$_GET['" . $key . "'] = '" . $value . "';\r\n"; + } + return $temp; + } + + /** + * 匹配配置信息 + * + * @param string $content + * @return array + */ + private function matchConfig($content) { + preg_match_all('/(\w+=[\'|"]?[\w|.|:]+[\'|"]?)/', $content, $mathcs); + list($config, $key, $val) = array(array(), '', ''); + foreach ($mathcs[0] as $value) { + list($key, $val) = explode('=', $value); + if (!in_array($key, $this->getProperties()) || !$val) continue; + switch($key) { + case 'args': + $config['args'] = $this->compileArgs(trim($val, '\'"')); + break; + default: + $config[$key] = trim($val, '\'"'); + break; + } + } + return $config; + } + + /** + * 解析传递给url的参数信息 + * + * @param string $arg + * @return array + */ + private function compileArgs($arg) { + $args = explode(':', $arg); + $urlParams = array(); + list($urlParams['a'], $urlParams['c'], $urlParams['m']) = array('', '', ''); + switch(count($args)) { + case 1: + $urlParams['a'] = $args[0]; + break; + case 2: + list($urlParams['c'], $urlParams['a']) = $args; + break; + case 3: + list($urlParams['m'], $urlParams['c'], $urlParams['a']) = $args; + break; + default; + break; + } + return $urlParams; + } + /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::getProperties() */ protected function getProperties() { - return array('name', 'app', 'args', 'tpl'); + return array('name', 'templateDir', 'appConfig', 'args', 'componentPath'); } } From 7b38d80ddfc85180eb633f68a9f5c92c8fe5d6f7 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 03:13:22 +0000 Subject: [PATCH 0119/1065] =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2177 18ba2127-5a84-46d4-baec-3457e417f034 --- .../viewer/compiler/WindTemplateCompilerComponent.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php index 0ab21acb..852e8cff 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php @@ -10,15 +10,15 @@ */ class WindTemplateCompilerComponent extends AbstractWindTemplateCompiler { - protected $name = ''; + protected $name = ''; //组件名字 - protected $args = ''; + protected $args = '';//传递给组件的参数 - protected $templateDir = ''; + protected $templateDir = '';//组件调用的模板路径 - protected $appConfig = ''; + protected $appConfig = '';//组件的配置文件 - protected $componentPath = ''; + protected $componentPath = '';//组件的入口地址 /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() From ac4a348a65fe611005c233546071422708bd4748 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 07:14:07 +0000 Subject: [PATCH 0120/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=20=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E6=A0=87=E7=AD=BE=E7=BC=96=E8=AF=91=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2179 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/compiler/WindTemplateCompilerAction.php | 4 +--- .../viewer/compiler/WindTemplateCompilerComponent.php | 2 +- wind/component/viewer/compiler/WindTemplateCompilerPage.php | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerAction.php b/wind/component/viewer/compiler/WindTemplateCompilerAction.php index db76aef2..18a4ba68 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerAction.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerAction.php @@ -33,9 +33,7 @@ public function getScript() { '$_tpl_forward->setDisplay(true);' . '$_tpl_forward->forwardAnotherAction(\'' . $this->action . '\', \'' . $this->controller . '\');' . '$_tpl_app = $this->getSystemFactory()->getInstance(COMPONENT_WEBAPP);'. - '$_tpl_app->doDispatch($_tpl_forward);' . - ''. - 'echo $this->getWindView()->getTemplateName();'; + '$_tpl_app->doDispatch($_tpl_forward);'; return $_tmp; } diff --git a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php index 852e8cff..6a875f86 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php @@ -3,7 +3,7 @@ Wind::import('WIND:core.viewer.AbstractWindTemplateCompiler'); /** - * + * * the last known user to change this file in the repository * @author xiaoxiao * @version 2011-7-20 xiaoxiao diff --git a/wind/component/viewer/compiler/WindTemplateCompilerPage.php b/wind/component/viewer/compiler/WindTemplateCompilerPage.php index 2816e762..c660101c 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerPage.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerPage.php @@ -57,8 +57,8 @@ private function getTplContent() { } private function parsePageTags($content) { - $arrPageTags = array('$total', '$page', '$url'); - $arrPageVars = array('$_tplPageTotal', '$_tplPageCurrent', '$_tplPageUrl'); + $arrPageTags = array('$total', '$page', '$url', '$count'); + $arrPageVars = array('$_tplPageTotal', '$_tplPageCurrent', '$_tplPageUrl', '$_tplPageCount'); return str_ireplace($arrPageTags, $arrPageVars, $content); } From cb68c33404f128dbeeef93fb0f1f5d2a8a2bd3da Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 20 Jul 2011 07:53:29 +0000 Subject: [PATCH 0121/1065] =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E5=A4=9A=E5=BA=94=E7=94=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2180 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 116 ++++++++---------- wind/component/viewer/WindViewerResolver.php | 10 -- .../compiler/WindTemplateCompilerEcho.php | 2 +- wind/core/router/AbstractWindRouter.php | 1 + 4 files changed, 55 insertions(+), 74 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 3e1f321a..1b977a00 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -100,8 +100,8 @@ public static function runWithCompile($appName = 'default', $config = '') { * @return string|null */ public static function import($filePath, $recursivePackage = false) { - if (!$filePath) return false; - if ($className = self::_isImported($filePath)) return $className; + if (!$filePath) return; + if (isset(self::$_imports[$filePath])) return self::$_imports[$filePath]; if (($pos = strrpos($filePath, '.')) !== false) $fileName = substr($filePath, $pos + 1); elseif (($pos1 = strrpos($filePath, ':')) !== false) @@ -174,9 +174,13 @@ public static function autoLoad($className, $path = '') { if ($path === '') { throw new Exception('auto load ' . $className . ' failed.'); } - $path = self::getRealPath($path . '.' . self::$_extensions); - if ((include $path) === false) { - throw new Exception('include file ' . $path . ' failed.'); + list($namespace, $filePath) = explode(':', $path); + if ($namespace && $filePath) { + $namespace = self::getRootPath($namespace); + $path = $namespace . D_S . str_replace('.', D_S, $filePath) . '.' . self::$_extensions; + } + if ((require $path) === false) { + throw new Exception('[wind.Wind.autoLoad] auto load class ' . $className . ' failed.'); } } @@ -193,8 +197,7 @@ public static function getImports($key = '') { * @param string $namespace * @return string|Ambigous */ - public static function getRootPath($namespace = '') { - if (!$namespace) return ''; + public static function getRootPath($namespace) { $namespace = strtolower($namespace); return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; } @@ -206,18 +209,15 @@ public static function getRootPath($namespace = '') { * @return string|array('isPackage','fileName','extension','realPath') */ public static function getRealPath($filePath, $isDir = false) { - $namespace = $suffix = ''; + list($namespace, $filePath) = explode(':', $filePath); + $_tmp = explode('.', $filePath); if (!$isDir) { - $_pos1 = strrpos($filePath, '.'); - $suffix = substr($filePath, $_pos1 + 1); - $filePath = substr($filePath, 0, $_pos1); - } - if (($pos = strpos($filePath, ':')) !== false) { - $namespace = self::getRootPath(substr($filePath, 0, $pos)); - } - $filePath = str_replace('.', D_S, $filePath); - if ($namespace) $filePath = $namespace . D_S . substr($filePath, $pos + 1); - return $suffix ? $filePath . '.' . $suffix : $filePath; + $_suffix = array_pop($_tmp); + $filePath = implode(D_S, $_tmp) . '.' . $_suffix; + } else + $filePath = implode(D_S, $_tmp); + $namespace = self::getRootPath($namespace); + return $namespace ? ($namespace . D_S . $filePath) : $filePath; } /** @@ -347,8 +347,6 @@ function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/G * @return */ private static function _setImport($className, $classPath) { - //if (self::_isImported($className)) return; - if (strpos($classPath, ':') === false) $classPath = strtoupper(self::getAppName()) . ':' . $classPath; self::$_imports[$classPath] = $className; if (self::$_isAutoLoad) self::$_classes[$className] = $classPath; @@ -410,49 +408,41 @@ private static function _checkPhpVersion() { * @return */ private static function _coreLib() { - return array( - 'WindLogger' => 'COM:log.WindLogger', - 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', - 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', - 'WindConfig' => 'WIND:core.config.WindConfig', - 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', - 'WindActionException' => 'WIND:core.exception.WindActionException', - 'WindException' => 'WIND:core.exception.WindException', - 'WindFinalException' => 'WIND:core.exception.WindFinalException', - 'IWindFactory' => 'WIND:core.factory.IWindFactory', - 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', - 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', - 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', - 'WindFactory' => 'WIND:core.factory.WindFactory', - 'WindFilter' => 'WIND:core.filter.WindFilter', - 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', - 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', - 'IWindRequest' => 'WIND:core.request.IWindRequest', - 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', - 'IWindResponse' => 'WIND:core.response.IWindResponse', - 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', - 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', - 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', - 'IWindController' => 'WIND:core.web.controller.IWindController', - 'WindController' => 'WIND:core.web.controller.WindController', - 'WindSimpleController' => 'WIND:core.web.controller.WindSimpleController', - 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', - 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', - 'IWindApplication' => 'WIND:core.web.IWindApplication', - 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', - 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', - 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', - 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', - 'WindDispatcher' => 'WIND:core.web.WindDispatcher', - 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', - 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', - 'WindForward' => 'WIND:core.web.WindForward', - 'WindFrontController' => 'WIND:core.web.WindFrontController', - 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', - 'WindWebApplication' => 'WIND:core.web.WindWebApplication', - 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', - 'WindHelper' => 'WIND:core.WindHelper', + return array('WindLogger' => 'COM:log.WindLogger', + 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', + 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', + 'WindConfig' => 'WIND:core.config.WindConfig', 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', + 'WindActionException' => 'WIND:core.exception.WindActionException', + 'WindException' => 'WIND:core.exception.WindException', + 'WindFinalException' => 'WIND:core.exception.WindFinalException', + 'IWindFactory' => 'WIND:core.factory.IWindFactory', + 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', + 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', + 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', + 'WindFactory' => 'WIND:core.factory.WindFactory', 'WindFilter' => 'WIND:core.filter.WindFilter', + 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', + 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', + 'IWindRequest' => 'WIND:core.request.IWindRequest', 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', + 'IWindResponse' => 'WIND:core.response.IWindResponse', + 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', + 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', + 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', + 'IWindController' => 'WIND:core.web.controller.IWindController', + 'WindController' => 'WIND:core.web.controller.WindController', + 'WindSimpleController' => 'WIND:core.web.controller.WindSimpleController', + 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', + 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', + 'IWindApplication' => 'WIND:core.web.IWindApplication', + 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', + 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', + 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', + 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', + 'WindDispatcher' => 'WIND:core.web.WindDispatcher', 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', + 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', 'WindForward' => 'WIND:core.web.WindForward', + 'WindFrontController' => 'WIND:core.web.WindFrontController', + 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', 'WindWebApplication' => 'WIND:core.web.WindWebApplication', + 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', 'WindHelper' => 'WIND:core.WindHelper', 'WindModule' => 'WIND:core.WindModule'); } } diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index 4aa97e36..c0d02793 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -116,16 +116,6 @@ private function checkReCompile($templateFile, $compileFile) { return $_reCompile; } - /** - * 返回模板变量信息 - * - * @param string $var - * @param string $templateName - */ - private function getVar($var, $templateName) { - return $this->getResponse()->getData($templateName, $var); - } - /** * 当前模板内容 * diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index 1d2b9b93..902fb8a8 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -29,7 +29,7 @@ private function compileVarShare($input) { $input = trim($input); if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) return $input; list($templateName, $var) = explode(':', $input); - $input = '$this->response->getData(\'' . $templateName . '\', \'' . $var .'\')'; + $input = '$this->getResponse()->getData(\'' . $templateName . '\', \'' . $var .'\')'; return $input; } diff --git a/wind/core/router/AbstractWindRouter.php b/wind/core/router/AbstractWindRouter.php index 75722121..d482d82d 100644 --- a/wind/core/router/AbstractWindRouter.php +++ b/wind/core/router/AbstractWindRouter.php @@ -81,6 +81,7 @@ public function doParse() { self::CONTROLLER_DEFAULT_PATH); } $_path .= '.' . ucfirst($this->controller) . $_suffix; + if (strpos($_path, ':') === false) $_path = Wind::getAppName() . ':' . $_path; if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.router.AbstractWindRouter.doParse] action handler: ' . $_path, WindLogger::LEVEL_DEBUG, 'wind.core'); From 2969496b974511373fb3b2024299ccc367f2b3d0 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 09:43:19 +0000 Subject: [PATCH 0122/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=20=20=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E4=B8=8A=E4=BC=A0=E6=94=AF=E6=8C=81=E5=A4=9A=E7=BB=84?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2181 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindFormUpload.php | 115 +++++++++++++++++------ 1 file changed, 84 insertions(+), 31 deletions(-) diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index 0963b43b..b5b7f28f 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -29,43 +29,89 @@ public function __construct($allowType = array()) { * @see AbstractWindUpload::upload() */ public function upload($saveDir, $preFileName = '', $allowType = array()) { - $allowType = $allowType ? (array)$allowType : $this->allowType; + $allowType && $this->allowType = (array)$allowType; $atc_attachment = ''; $uploaddb = $error = array(); + var_dump($_FILES); foreach ($_FILES as $key => $value) { - if (!$this->hasUploadedFile($value['tmp_name'])) continue; - $atc_attachment = $value['tmp_name']; - $upload = $this->initCurrUpload($key, $value); - - if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'], array_keys($allowType))) { - $error['type'][] = $upload; - $this->hasError = true; - continue; + if (is_array($value['name'])) { + $temp = $this->multiUpload($key, $saveDir, $preFileName); + $uploaddb[$key] = isset($uploaddb[$key]) ? array_merge((array)$uploaddb[$key], $temp) : $temp; + } else { + $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName); } - if ($upload['size'] < 1 || ($allowType && $upload['size'] > $allowType[$upload['ext']])) { - $upload['maxSize'] = $allowType[$upload['ext']]; - $error['size'][] = $upload; - $this->hasError = true; - continue; - } - $fileName = $this->getFileName($upload, $preFileName); - $source = $this->getSavePath($fileName, $saveDir); - - if (!$this->postUpload($atc_attachment, $source)) { - $upload['savePath'] = $source; - $error['upload'][] = $upload; - $this->hasError = true; - continue; - } - clearstatcache(); - $upload['size'] = ceil(filesize($source) / 1024); - $upload['savePath'] = $source; - $uploaddb[] = $upload; } $this->errorInfo = $error; return $uploaddb;/*array($uploaddb, $errorType, $errorSize, $uploadError)*/; } + /** + * 单个控件 + * 一个表单中只有一个上传文件的控件 + */ + public function simpleUpload($key, $saveDir, $preFileName = '') { + return $this->doUp($key, $_FILES[$key], $saveDir, $preFileName); + } + + /** + * 多个空间 + * 一个表单中拥有多个上传文件的控件 + */ + public function multiUpload($key, $saveDir, $preFileName = '') { + $uploaddb = array(); + $files = $_FILES[$key]; + $num = count($files['name']); + for($i = 0; $i < $num; $i ++) { + $one = array(); + $one['name'] = $files['name'][$i]; + $one['tmp_name'] = $files['tmp_name'][$i]; + $one['error'] = $files['error'][$i]; + $one['size'] = $files['size'][$i]; + $one['type'] = $files['type'][$i]; + if (!($upload = $this->doUp($key, $one, $saveDir, $preFileName))) continue; + $uploaddb[] = $upload; + } + return $uploaddb; + } + + + /** + * 执行上传操作 + * + * @param array $value + * @return array + */ + private function doUp($key, $value, $saveDir, $preFileName) { + $atc_attachment = ''; + if (!$this->hasUploadedFile($value['tmp_name'])) return array(); + $atc_attachment = $value['tmp_name']; + $upload = $this->initCurrUpload($key, $value); + + if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'], array_keys($this->allowType))) { + $this->errorInfo['type'][$key][] = $upload; + $this->hasError = true; + return array(); + } + if ($upload['size'] < 1 || ($this->allowType && $upload['size'] > $this->allowType[$upload['ext']])) { + $upload['maxSize'] = $this->allowType[$upload['ext']]; + $this->errorInfo['size'][$key][] = $upload; + $this->hasError = true; + return array(); + } + $fileName = $this->getFileName($upload, $preFileName); + $source = $this->getSavePath($fileName, $saveDir); + + if (!$this->postUpload($atc_attachment, $source)) { + $upload['savePath'] = $source; + $this->errorInfo['upload'][$key][] = $upload; + $this->hasError = true; + return array(); + } + $upload['size'] = ceil(filesize($source) / 1024); + $upload['savePath'] = $source; + return $upload; + } + /** * (non-PHPdoc) * @see AbstractWindUpload::getErrorInfo() @@ -125,7 +171,7 @@ private function getSavePath($fileName, $saveDir) { * @return string */ private function getFileName($info, $preFileName = '') { - $fileName = mt_rand(1, 10) . time() . substr(md5(time() . $info['id'] . mt_rand(1, 10)), 10, 15) . '.' . $info['ext']; + $fileName = mt_rand(1, 10) . time() . substr(md5(time() . $info['attname'] . mt_rand(1, 10)), 10, 15) . '.' . $info['ext']; return $preFileName ? $preFileName . $fileName : $fileName; } @@ -150,10 +196,17 @@ private function hasUploadedFile($tmp_name) { * @param string $value */ private function initCurrUpload($key, $value) { - list($t, $i) = explode('_', $key); - $arr = array('id' => intval($i), 'attname' => $t, 'name' => $value['name'], 'size' => intval($value['size']), 'type' => 'zip', 'ifthumb' => 0, 'fileuploadurl' => ''); + $arr = array('attname' => $key, 'name' => $value['name'], 'size' => intval($value['size']), 'type' => 'zip', 'ifthumb' => 0, 'fileuploadurl' => ''); $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1)); return $arr; } + + /** + * 获得上传文件的的数组的可能key值 + * @return array + */ + private function getUploadFileField() { + return array('name', 'tmp_name', 'error', 'size', 'type'); + } } \ No newline at end of file From b5c4dd7f3b847104a8b851b5bce6063e447b6c69 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 09:47:23 +0000 Subject: [PATCH 0123/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=20=20=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E4=B8=8A=E4=BC=A0=E6=94=AF=E6=8C=81=E5=A4=9A=E7=BB=84?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2182 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindFormUpload.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index b5b7f28f..fb23dd34 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -1,18 +1,11 @@ 2010-12-13 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - Wind::import('WIND:component.upload.AbstractWindUpload'); - -/** - * the last known user to change this file in the repository <$LastChangedBy: yishuo $> - * @author Qian Su - * @version $Id: WindFormUpload.php 1994 2011-06-16 04:19:05Z yishuo $ - * @package +/** + * @author xiaoxiao 2011-7-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + * @package */ class WindFormUpload extends AbstractWindUpload { private $errorInfo = array('type' => array(), 'size' => array(), 'upload' => array()); From 5da6697ed62bc7b2d2af6a9d2e4e67f223bd330f Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 10:26:05 +0000 Subject: [PATCH 0124/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=20=20=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2183 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindFormUpload.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index fb23dd34..8b1f493a 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -23,9 +23,7 @@ public function __construct($allowType = array()) { */ public function upload($saveDir, $preFileName = '', $allowType = array()) { $allowType && $this->allowType = (array)$allowType; - $atc_attachment = ''; - $uploaddb = $error = array(); - var_dump($_FILES); + $uploaddb = array(); foreach ($_FILES as $key => $value) { if (is_array($value['name'])) { $temp = $this->multiUpload($key, $saveDir, $preFileName); @@ -34,7 +32,6 @@ public function upload($saveDir, $preFileName = '', $allowType = array()) { $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName); } } - $this->errorInfo = $error; return $uploaddb;/*array($uploaddb, $errorType, $errorSize, $uploadError)*/; } From 7da61d740e83020743a5ce7a9d44e8d271f79100 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 10:27:28 +0000 Subject: [PATCH 0125/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=20=20=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2184 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindFormUpload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index 8b1f493a..731ec642 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -32,7 +32,7 @@ public function upload($saveDir, $preFileName = '', $allowType = array()) { $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName); } } - return $uploaddb;/*array($uploaddb, $errorType, $errorSize, $uploadError)*/; + return 1 == count($uploaddb) ? array_shift($uploaddb) : $uploaddb;/*array($uploaddb, $errorType, $errorSize, $uploadError)*/; } /** From 8a91f57266ed98a302108674b3ce7a15f8ad5f9c Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 20 Jul 2011 10:27:53 +0000 Subject: [PATCH 0126/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2185 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 131 +++++---- wind/_compile/compile.php | 10 +- .../cache/strategy/WindCacheFile.php | 263 +++++++++--------- wind/component/viewer/WindView.php | 8 +- .../WindTemplateCompilerComponent.php | 2 +- wind/core/config/WindConfig.php | 3 +- wind/core/config/WindSystemConfig.php | 132 ++------- wind/core/web/WindFrontController.php | 5 +- 8 files changed, 236 insertions(+), 318 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 1b977a00..c343233e 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -79,7 +79,7 @@ public static function getApp() { * 开发环境脚本入口 */ public static function runWithCompile($appName = 'default', $config = '') { - require_once (self::getRealPath('WIND:_compile.compile.php')); + require_once (self::getRealPath('WIND:_compile.compile')); self::run($appName, $config); } @@ -111,7 +111,7 @@ public static function import($filePath, $recursivePackage = false) { $isPackage = $fileName === '*'; if ($isPackage) { $filePath = substr($filePath, 0, $pos); - $dirPath = self::getRealPath($filePath, true); + $dirPath = self::getRealDir($filePath); if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); while (($file = readdir($dh)) !== false) { if (is_dir($dirPath . D_S . $file)) { @@ -174,12 +174,8 @@ public static function autoLoad($className, $path = '') { if ($path === '') { throw new Exception('auto load ' . $className . ' failed.'); } - list($namespace, $filePath) = explode(':', $path); - if ($namespace && $filePath) { - $namespace = self::getRootPath($namespace); - $path = $namespace . D_S . str_replace('.', D_S, $filePath) . '.' . self::$_extensions; - } - if ((require $path) === false) { + $path = self::getRealPath($path); + if ((include $path) === false) { throw new Exception('[wind.Wind.autoLoad] auto load class ' . $className . ' failed.'); } } @@ -208,16 +204,28 @@ public static function getRootPath($namespace) { * @param boolean $info 是否为目录路径 * @return string|array('isPackage','fileName','extension','realPath') */ - public static function getRealPath($filePath, $isDir = false) { - list($namespace, $filePath) = explode(':', $filePath); - $_tmp = explode('.', $filePath); - if (!$isDir) { - $_suffix = array_pop($_tmp); - $filePath = implode(D_S, $_tmp) . '.' . $_suffix; - } else - $filePath = implode(D_S, $_tmp); - $namespace = self::getRootPath($namespace); - return $namespace ? ($namespace . D_S . $filePath) : $filePath; + public static function getRealPath($filePath, $suffix = '') { + if (($pos = strpos($filePath, ':')) !== false) { + $namespace = self::getRootPath(substr($filePath, 0, $pos)); + if (!$namespace) return $filePath; + $filePath = $namespace . D_S . str_replace('.', D_S, substr($filePath, $pos + 1)); + } + !$suffix && $suffix = self::$_extensions; + return $filePath . '.' . $suffix; + } + + /** + * 解析路径信息,并返回路径的详情 + * @param string $filePath 路径信息 + * @param boolean $info 是否为目录路径 + * @return string|array('isPackage','fileName','extension','realPath') + */ + public static function getRealDir($dirPath) { + if (($pos = strpos($dirPath, ':')) === false) return $dirPath; + $namespace = self::getRootPath(substr($dirPath, 0, $pos)); + if (!$namespace) return $dirPath; + $dirPath = str_replace('.', D_S, substr($dirPath, $pos + 1)); + return $namespace . D_S . $dirPath; } /** @@ -326,8 +334,8 @@ protected static function afterRun() { * @return */ private static function _setDefaultSystemNamespace() { - self::register(WIND_PATH, 'WIND'); - self::register(WIND_PATH . 'component' . D_S, 'COM'); + self::register(WIND_PATH, 'WIND', true); + self::register(WIND_PATH . 'component' . D_S, 'COM', true); } /** @@ -383,9 +391,7 @@ private static function _registerAutoloader() { */ private static function _loadBaseLib() { $_core = self::_coreLib(); - foreach ($_core as $key => $value) { - self::_setImport($key, $value); - } + self::$_classes = $_core; } /* private utility */ @@ -408,42 +414,49 @@ private static function _checkPhpVersion() { * @return */ private static function _coreLib() { - return array('WindLogger' => 'COM:log.WindLogger', - 'IWindConfigParser' => 'WIND:core.config.parser.IWindConfigParser', - 'WindConfigParser' => 'WIND:core.config.parser.WindConfigParser', - 'WindConfig' => 'WIND:core.config.WindConfig', 'WindSystemConfig' => 'WIND:core.config.WindSystemConfig', - 'WindActionException' => 'WIND:core.exception.WindActionException', - 'WindException' => 'WIND:core.exception.WindException', - 'WindFinalException' => 'WIND:core.exception.WindFinalException', - 'IWindFactory' => 'WIND:core.factory.IWindFactory', - 'IWindClassProxy' => 'WIND:core.factory.proxy.IWindClassProxy', - 'WindClassProxy' => 'WIND:core.factory.proxy.WindClassProxy', - 'WindClassDefinition' => 'WIND:core.factory.WindClassDefinition', - 'WindFactory' => 'WIND:core.factory.WindFactory', 'WindFilter' => 'WIND:core.filter.WindFilter', - 'WindFilterChain' => 'WIND:core.filter.WindFilterChain', - 'WindHandlerInterceptor' => 'WIND:core.filter.WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'WIND:core.filter.WindHandlerInterceptorChain', - 'IWindRequest' => 'WIND:core.request.IWindRequest', 'WindHttpRequest' => 'WIND:core.request.WindHttpRequest', - 'IWindResponse' => 'WIND:core.response.IWindResponse', - 'WindHttpResponse' => 'WIND:core.response.WindHttpResponse', - 'AbstractWindRouter' => 'WIND:core.router.AbstractWindRouter', - 'WindUrlBasedRouter' => 'WIND:core.router.WindUrlBasedRouter', - 'IWindController' => 'WIND:core.web.controller.IWindController', - 'WindController' => 'WIND:core.web.controller.WindController', - 'WindSimpleController' => 'WIND:core.web.controller.WindSimpleController', - 'WindLoggerFilter' => 'WIND:core.web.filter.WindLoggerFilter', - 'WindUrlFilter' => 'WIND:core.web.filter.WindUrlFilter', - 'IWindApplication' => 'WIND:core.web.IWindApplication', - 'IWindErrorMessage' => 'WIND:core.web.IWindErrorMessage', - 'WindFormListener' => 'WIND:core.web.listener.WindFormListener', - 'WindLoggerListener' => 'WIND:core.web.listener.WindLoggerListener', - 'WindValidateListener' => 'WIND:core.web.listener.WindValidateListener', - 'WindDispatcher' => 'WIND:core.web.WindDispatcher', 'WindErrorHandler' => 'WIND:core.web.WindErrorHandler', - 'WindErrorMessage' => 'WIND:core.web.WindErrorMessage', 'WindForward' => 'WIND:core.web.WindForward', - 'WindFrontController' => 'WIND:core.web.WindFrontController', - 'WindUrlHelper' => 'WIND:core.web.WindUrlHelper', 'WindWebApplication' => 'WIND:core.web.WindWebApplication', - 'WindEnableValidateModule' => 'WIND:core.WindEnableValidateModule', 'WindHelper' => 'WIND:core.WindHelper', - 'WindModule' => 'WIND:core.WindModule'); + return array('WindLogger' => 'log\\WindLogger', + 'IWindConfigParser' => 'core\\config\\parser\\IWindConfigParser', + 'WindConfigParser' => 'core\\config\\parser\\WindConfigParser', + 'WindConfig' => 'core\\config\\WindConfig', + 'WindSystemConfig' => 'core\\config\\WindSystemConfig', + 'WindActionException' => 'core\\exception\\WindActionException', + 'WindException' => 'core\\exception\\WindException', + 'WindFinalException' => 'core\\exception\\WindFinalException', + 'IWindFactory' => 'core\\factory\\IWindFactory', + 'IWindClassProxy' => 'core\\factory\\proxy\\IWindClassProxy', + 'WindClassProxy' => 'core\\factory\\proxy\\WindClassProxy', + 'WindClassDefinition' => 'core\\factory\\WindClassDefinition', + 'WindFactory' => 'core\\factory\\WindFactory', + 'WindFilter' => 'core\\filter\\WindFilter', + 'WindFilterChain' => 'core\\filter\\WindFilterChain', + 'WindHandlerInterceptor' => 'core\\filter\\WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'core\\filter\\WindHandlerInterceptorChain', + 'IWindRequest' => 'core\\request\\IWindRequest', + 'WindHttpRequest' => 'core\\request\\WindHttpRequest', + 'IWindResponse' => 'core\\response\\IWindResponse', + 'WindHttpResponse' => 'core\\response\\WindHttpResponse', + 'AbstractWindRouter' => 'core\\router\\AbstractWindRouter', + 'WindUrlBasedRouter' => 'core\\router\\WindUrlBasedRouter', + 'IWindController' => 'core\\web\\controller\\IWindController', + 'WindController' => 'core\\web\\controller\\WindController', + 'WindSimpleController' => 'core\\web\\controller\\WindSimpleController', + 'WindLoggerFilter' => 'core\\web\\filter\\WindLoggerFilter', + 'WindUrlFilter' => 'core\\web\\filter\\WindUrlFilter', + 'IWindApplication' => 'core\\web\\IWindApplication', + 'IWindErrorMessage' => 'core\\web\\IWindErrorMessage', + 'WindFormListener' => 'core\\web\\listener\\WindFormListener', + 'WindLoggerListener' => 'core\\web\\listener\\WindLoggerListener', + 'WindValidateListener' => 'core\\web\\listener\\WindValidateListener', + 'WindDispatcher' => 'core\\web\\WindDispatcher', + 'WindErrorHandler' => 'core\\web\\WindErrorHandler', + 'WindErrorMessage' => 'core\\web\\WindErrorMessage', + 'WindForward' => 'core\\web\\WindForward', + 'WindFrontController' => 'core\\web\\WindFrontController', + 'WindUrlHelper' => 'core\\web\\WindUrlHelper', + 'WindWebApplication' => 'core\\web\\WindWebApplication', + 'WindEnableValidateModule' => 'core\\WindEnableValidateModule', + 'WindHelper' => 'core\\WindHelper', + 'WindModule' => 'core\\WindModule',); } } Wind::init(); diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php index c5d21c12..a822f95e 100644 --- a/wind/_compile/compile.php +++ b/wind/_compile/compile.php @@ -17,15 +17,21 @@ $fileList = array(); $content = array(); foreach ($imports as $key => $value) { - $content[$value] = $key; - $_key = Wind::getRealPath($key . '.' . self::$_extensions); + $_key = Wind::getRealPath($key); $fileList[$_key] = array($key, $value); + $content[$value] = parseFilePath($key); } $pack->packFromFileList($fileList, COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); /* import信息写入编译文件 */ WindFile::write(_COMPILE_PATH . 'wind_imports.php', 'parse(_COMPILE_PATH . 'components_config.xml'); WindFile::write($_systemConfig, ' * @author Su Qian * @version $Id$ * @package - */ -class WindCacheFile extends AbstractWindCache { - + */ +class WindCacheFile extends AbstractWindCache { + /** * 缓存目录 * @var string - */ - protected $cacheDir; - + */ + protected $cacheDir; + /** * 缓存后缀 * @var string - */ - protected $cacheFileSuffix = ''; - + */ + protected $cacheFileSuffix = ''; + /** * 缓存多级目录。最好不要超3层目录 * @var int - */ - protected $cacheDirectoryLevel = ''; - - const CACHEDIR = 'cache-dir'; - - const SUFFIX = 'cache-suffix'; - - const LEVEL = 'cache-level'; - + */ + protected $cacheDirectoryLevel = ''; + + const CACHEDIR = 'cache-dir'; + + const SUFFIX = 'cache-suffix'; + + const LEVEL = 'cache-level'; + /* (non-PHPdoc) * @see AbstractWindCache::set() - */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire; - return $this->writeData($this->getRealCacheKey($key), $this->storeData($value, $expire, $denpendency), $expire); - } - + */ + public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { + $expire = null === $expire ? $this->getExpire() : $expire; + return $this->writeData($this->getRealCacheKey($key), $this->storeData($value, $expire, $denpendency), $expire); + } + /* (non-PHPdoc) * @see AbstractWindCache::get() - */ - public function get($key) { - return $this->getDataFromMeta($key, $this->readData($this->getRealCacheKey($key))); - } - + */ + public function get($key) { + return $this->getDataFromMeta($key, $this->readData($this->getRealCacheKey($key))); + } + /* (non-PHPdoc) * @see AbstractWindCache::delete() - */ - public function delete($key) { - $cacheFile = $this->getRealCacheKey($key); - if (is_file($cacheFile)) { - return WindFile::delFile($cacheFile); - } - return false; - } - + */ + public function delete($key) { + $cacheFile = $this->getRealCacheKey($key); + if (is_file($cacheFile)) { + return WindFile::delFile($cacheFile); + } + return false; + } + /* (non-PHPdoc) * @see AbstractWindCache::clear() - */ - public function clear($isExpired = false) { - return WindFile::clearDir($this->getCacheDir(), $isExpired); - } + */ + public function clear($isExpired = false) { + return WindFile::clearDir($this->getCacheDir(), $isExpired); + } + /** * 获取缓存文件名。 * @param string $key * @return string - */ - protected function getRealCacheKey($key, $getDir = false) { - $filename = $this->buildSecurityKey($key) . '.' . ltrim($this->getCacheFileSuffix(), '.'); - $_tmp = $this->getCacheDir(); - if (0 < $this->getCacheDirectoryLevel()) { - for ($i = $this->getCacheDirectoryLevel(); $i > 0; --$i) { - if (false === isset($key[$i])) continue; - $_tmp .= $key[$i] . DIRECTORY_SEPARATOR; - } - if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); - } - if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); - return $getDir ? $_tmp : $_tmp . $filename; - } - + */ + protected function getRealCacheKey($key, $getDir = false) { + $filename = $this->buildSecurityKey($key) . '.' . ltrim($this->getCacheFileSuffix(), '.'); + $_tmp = $this->getCacheDir(); + if (0 < $this->getCacheDirectoryLevel()) { + for ($i = $this->getCacheDirectoryLevel(); $i > 0; --$i) { + if (false === isset($key[$i])) continue; + $_tmp .= $key[$i] . DIRECTORY_SEPARATOR; + } + if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); + } + if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); + return $getDir ? $_tmp : $_tmp . $filename; + } + /** * 写入文件缓存 * @param string $file 缓存文件名 * @param string $data 缓存数据 * @param int $mtime 缓存文件的修改时间,即缓存的过期时间 * @return boolean - */ - protected function writeData($file, $data, $mtime = 0) { - if (WindFile::write($file, $data) == strlen($data)) { - $mtime += $mtime ? time() : 0; - chmod($file, 0777); - return touch($file, $mtime); - } - return false; - } - + */ + protected function writeData($file, $data, $mtime = 0) { + if (WindFile::write($file, $data) == strlen($data)) { + $mtime += $mtime ? time() : 0; + chmod($file, 0777); + return touch($file, $mtime); + } + return false; + } + /** * 从文件中读取缓存内容 * @param string $file 缓存文件名 * @return null|string - */ - protected function readData($file) { - if (false === is_file($file)) return null; - $mtime = filemtime($file); - if (0 === $mtime || ($mtime && $mtime > time())) - return unserialize(WindFile::read($file)); - elseif (0 < $mtime) - WindFile::delFile($file); - return null; - } - + */ + protected function readData($file) { + if (false === is_file($file)) return null; + $mtime = filemtime($file); + if (0 === $mtime || ($mtime && $mtime > time())) + return unserialize(WindFile::read($file)); + elseif (0 < $mtime) + WindFile::delFile($file); + return null; + } + /* (non-PHPdoc) * @see AbstractWindCache::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->setCacheDir($this->getConfig(self::CACHEDIR, WIND_CONFIG_VALUE)); - } - + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setCacheDir($this->getConfig(self::CACHEDIR, WIND_CONFIG_VALUE)); + } + /** * 设置缓存目录 * @param string $dir - */ - private function setCacheDir($dir) { - $this->cacheDir = Wind::getRealPath($dir,true) . DIRECTORY_SEPARATOR; - } - + */ + private function setCacheDir($dir) { + $this->cacheDir = Wind::getRealDir($dir) . DIRECTORY_SEPARATOR; + } + /** * @return the $cacheDir - */ - public function getCacheDir() { - if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0777, true); - return $this->cacheDir; - } - + */ + public function getCacheDir() { + if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0777, true); + return $this->cacheDir; + } + /** * @return the $cacheFileSuffix - */ - protected function getCacheFileSuffix() { - if ('' === $this->cacheFileSuffix) { - $this->cacheFileSuffix = $this->getConfig(self::SUFFIX, WIND_CONFIG_VALUE, '', 'bin'); - } - return $this->cacheFileSuffix; - } - + */ + protected function getCacheFileSuffix() { + if ('' === $this->cacheFileSuffix) { + $this->cacheFileSuffix = $this->getConfig(self::SUFFIX, WIND_CONFIG_VALUE, '', 'bin'); + } + return $this->cacheFileSuffix; + } + /** * 返回cache目录级别,默认为0,不分级,最大分级为5 * @return the $cacheDirectoryLevel - */ - protected function getCacheDirectoryLevel() { - if ('' === $this->cacheDirectoryLevel) { - $this->cacheDirectoryLevel = $this->getConfig(self::LEVEL, WIND_CONFIG_VALUE, '', 0); - } - return $this->cacheDirectoryLevel > 5 ? 5 : $this->cacheDirectoryLevel; - } - + */ + protected function getCacheDirectoryLevel() { + if ('' === $this->cacheDirectoryLevel) { + $this->cacheDirectoryLevel = $this->getConfig(self::LEVEL, WIND_CONFIG_VALUE, '', 0); + } + return $this->cacheDirectoryLevel > 5 ? 5 : $this->cacheDirectoryLevel; + } + /** * @param string $cacheFileSuffix - */ - public function setCacheFileSuffix($cacheFileSuffix) { - $this->cacheFileSuffix = $cacheFileSuffix; - } - + */ + public function setCacheFileSuffix($cacheFileSuffix) { + $this->cacheFileSuffix = $cacheFileSuffix; + } + /** * @param int $cacheDirectoryLevel - */ - public function setCacheDirectoryLevel($cacheDirectoryLevel) { - $this->cacheDirectoryLevel = $cacheDirectoryLevel; - } - + */ + public function setCacheDirectoryLevel($cacheDirectoryLevel) { + $this->cacheDirectoryLevel = $cacheDirectoryLevel; + } + /** * 垃圾回收,清理过期缓存 - */ - public function __destruct() { - $this->clear(true); - } - + */ + public function __destruct() { + $this->clear(true); + } + } \ No newline at end of file diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index c5587db5..b87874ca 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -121,14 +121,14 @@ private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) if (!$fileExt) $fileExt = $this->getTemplateExt(); if (strrpos($path, ':') === false) $path = Wind::getAppName() . ':' . $path; if ($ifCheckPath) { - $dir = Wind::getRealPath($path, true); + $dir = Wind::getRealDir($path); if (!is_dir($dir)) { @mkdir($dir); Wind::log('[component.viewer.WindView.parseFilePath] template dir is not exist.', WindLogger::LEVEL_DEBUG, 'wind.component'); } } - return Wind::getRealPath($path . '.' . $fileName . '.' . $fileExt); + return Wind::getRealPath($path . '.' . $fileName, $fileExt); } /** @@ -149,7 +149,7 @@ public function init() { public function getTemplateDir() { return $this->templateDir; } - + /** * @return string */ @@ -191,7 +191,7 @@ public function getLayout() { public function setTemplateDir($templateDir) { $this->templateDir = $templateDir; } - + /** * @param string $compileDir */ diff --git a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php index 6a875f86..8f8dc8dc 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php @@ -35,7 +35,7 @@ private function getScript($content) { if (!isset($params['name']) || !isset($params['componentPath'])) throw new WindException('组件编译错误!'); $content = "rebuildConfig($params) . (isset($params['args']) ? $this->registerUrlParams($params) : '') . - "\$componentPath = Wind::getRealPath('" . $params['componentPath'] . "', true);\r\n" . + "\$componentPath = Wind::getRealDir('" . $params['componentPath'] . "');\r\n" . "Wind::register(\$componentPath, '" . $params['name'] . "');\r\n" . "Wind::run('" . $params['name'] . "', \$config);\r\n?>"; return $content; diff --git a/wind/core/config/WindConfig.php b/wind/core/config/WindConfig.php index 403f8aad..20280bcf 100644 --- a/wind/core/config/WindConfig.php +++ b/wind/core/config/WindConfig.php @@ -81,9 +81,8 @@ protected function parseConfig($config, $cacheName, $append) { * @author Qiong Wu */ public function setConfig($config, $merage = false) { - if (!is_array($config)) throw new WindException('config error.'); if ($merage) - $this->config = array_merge($this->config, $config); + $this->config = array_merge($this->config, (array) $config); else $this->config = $config; } diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index ddd3528f..68fed652 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -1,11 +1,4 @@ 2010-12-21 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:core.config.WindConfig'); /** * 框架配置对象windConfig类, * the last known user to change this file in the repository <$LastChangedBy$> @@ -18,90 +11,60 @@ class WindSystemConfig extends WindConfig { const CLASS_PATH = 'class'; const PATH = 'path'; const VALUE = 'value'; - /* import 外部配置文件包含 */ - const IMPORTS = 'imports'; - const IMPORTS_RESOURCE = 'resource'; - const IMPORTS_IS_APPEND = 'is-append'; + /* app 相关配置 */ const WEB_APPS = 'web-apps'; const WEB_APP_ROOT_PATH = 'root-path'; - const WEB_APP_FACTORY = 'factory'; const WEB_APP_FACTORY_CLASS_DEFINITION = 'class-definition'; const WEB_APP_FILTER = 'filters'; const WEB_APP_ROUTER = 'router'; const WEB_APP_MODULE = 'modules'; const WEB_APP_TEMPLATE = 'template'; - protected $appName = ''; - protected $imports = array(); /** - * Enter description here ... - * * @param string $config * @param WindConfigParser $configParser * @param string $appName */ public function __construct($config, $configParser, $appName) { $cacheName = $appName . '_config'; - $this->appName = $appName; parent::__construct($config, $configParser, $cacheName); - } - - /* (non-PHPdoc) - * @see AbstractWindConfig::getConfig() - */ - public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { - $imports = parent::getConfig(self::IMPORTS); - if (key_exists($configName, (array) $imports)) { - return $this->parseImport($configName); - } - return parent::getConfig($configName, $subConfigName, $config, $default); + $_config = $this->getConfig(self::WEB_APPS, $appName); + $this->setConfig($_config); } /** * @return the $appName */ public function getAppName() { - return $this->appName; + return Wind::getAppName(); } /** * 返回当前应用的启动脚本位置 */ public function getAppClass() { - $_config = $this->getConfig(self::WEB_APPS, $this->appName); - $_tmp = $this->getConfig(self::CLASS_PATH, '', $_config); - return $_tmp ? $_tmp : COMPONENT_WEBAPP; + return $this->getConfig(self::CLASS_PATH, '', array(), COMPONENT_WEBAPP); } /** - * 返回应用路径信息 + * 返回应用路径信息 + * * @return string */ - public function getRootPath($appName = '') { - if ($appName === '') $appName = $this->appName; - $_tmp = $appName . '_RootPath'; + public function getRootPath() { + $_tmp = '_rootPath'; if (!isset($this->$_tmp)) { - $appConfig = $this->getConfig(self::WEB_APPS, $appName); - if (isset($appConfig[self::WEB_APP_ROOT_PATH]) && !empty($appConfig[self::WEB_APP_ROOT_PATH])) - $rootPath = $appConfig[self::WEB_APP_ROOT_PATH]; - else - $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); + $rootPath = $this->getConfig(self::WEB_APP_ROOT_PATH); + if (!$rootPath) $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); $this->$_tmp = $rootPath; } return $this->$_tmp; } - /** - * @param string $name - */ - public function getFactory($name = '') { - $_config = $this->getConfig(self::WEB_APPS, $this->appName); - return $this->getConfig(self::WEB_APP_FACTORY, $name, $_config); - } - /** * 返回filterChain的类型 + * * @return array */ public function getFilterClass() { @@ -111,12 +74,12 @@ public function getFilterClass() { /** * 返回配置定义中定义的过滤链列表 * 如果定义$name则返回在filters定义标签内对应的属性值 + * * @param string $name * @return array|string */ public function getFilters($name = '') { - $_config = $this->getConfig(self::WEB_APPS, $this->appName); - return $this->getConfig(self::WEB_APP_FILTER, $name, $_config); + return $this->getConfig(self::WEB_APP_FILTER, $name); } /** @@ -132,9 +95,7 @@ public function getRouterClass() { * @return array|string */ public function getRouter($name = '') { - $_config = $this->getConfig(self::WEB_APPS, $this->appName); - $_router = $this->getConfig(self::WEB_APP_ROUTER, $name, $_config); - return $_router ? $_router : COMPONENT_ROUTER; + return $this->getConfig(self::WEB_APP_ROUTER, $name, array(), COMPONENT_ROUTER); } /** @@ -162,8 +123,7 @@ public function getRouter($name = '') { * @return array|string */ public function getModules($name = '') { - $_config = $this->getConfig(self::WEB_APPS, $this->appName); - return $this->getConfig(self::WEB_APP_MODULE, $name, $_config); + return $this->getConfig(self::WEB_APP_MODULE, $name); } /** @@ -217,64 +177,4 @@ public function getModuleControllerSuffixByModuleName($name, $default = '') { return $this->getConfig('controller-suffix', WIND_CONFIG_VALUE, $module, $default); } - /** - * @param string $name - * @return array|string - */ - public function getTemplate($name = '') { - return $this->getConfig(self::TEMPLATE, $name); - } - - /** - * @param string $name - * @return array|string - */ - public function getViewerResolvers($name = '') { - return $this->getConfig(self::VIEWER_RESOLVERS, $name); - } - - /** - * @param string $name - * @return Ambigous - */ - public function getApplications($name = '') { - return $this->getConfig(self::APPLICATIONS, $name); - } - - /** - * @param string $name - * @return Ambigous - */ - public function getErrorMessage($name = '') { - return $this->getConfig(self::ERROR, $name); - } - - /** - * @param name - * @param cacheName - * @param configPath - * @param append - */ - protected function parseImport($name) { - if (!isset($this->imports[$name])) { - $imports = $this->getConfig(self::IMPORTS); - if (!isset($imports[$name])) return array(); - $import = $imports[$name]; - $config = array(); - if (is_array($import) && !empty($import)) { - $configPath = Wind::getRealPath($import[self::IMPORTS_RESOURCE]); - if (!isset($import[self::IMPORTS_IS_APPEND]) || $import[self::IMPORTS_IS_APPEND] === 'true') { - $append = $this->cacheName; - } elseif ($import[self::IMPORTS_IS_APPEND] === 'false' || $import[self::IMPORTS_IS_APPEND] === '') { - $append = false; - } else { - $append = $import[self::IMPORTS_IS_APPEND]; - } - $cacheName = $append ? $name : $this->appName . '_' . $name . '_config'; - $config = $this->parseConfig($configPath, $cacheName, $append); - } - $this->imports[$name] = $config; - } - return $this->imports[$name]; - } } \ No newline at end of file diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index c38c8e5b..91087b9f 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -22,7 +22,7 @@ class WindFrontController { /** * 框架系统配置信息资源地址,只接受php格式配置 */ - const WIND_COMPONENT_CONFIG_RESOURCE = 'WIND:components_config.php'; + const WIND_COMPONENT_CONFIG_RESOURCE = 'WIND:components_config'; /** * @var WindHttpRequest */ @@ -114,9 +114,8 @@ protected function initWindFactory() { * @param string $config */ protected function initWindConfig($appName, $config) { - !$appName && $appName = 'default'; $this->windSystemConfig = new WindSystemConfig($config, new WindConfigParser(), $appName); - Wind::register($this->windSystemConfig->getRootPath(), $this->windSystemConfig->getAppName(), true); + Wind::register($this->windSystemConfig->getRootPath(), $appName, true); if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( '[core.web.WindFrontController.initWindConfig] rootPath:' . $this->windSystemConfig->getRootPath() . From b91900a92bd479a741cb53ae28cfb7afc9292494 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 10:28:36 +0000 Subject: [PATCH 0127/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=20=20=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2186 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindFormUpload.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index 731ec642..1cfadd16 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -16,8 +16,7 @@ public function __construct($allowType = array()) { $allowType && $this->allowType = $allowType; } - /** - * + /* * (non-PHPdoc) * @see AbstractWindUpload::upload() */ From 2764fac927f928d3d56304feb332cb620e4d94a2 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 10:30:22 +0000 Subject: [PATCH 0128/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=20=20=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2187 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindFormUpload.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index 1cfadd16..2652a14c 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -189,13 +189,5 @@ private function initCurrUpload($key, $value) { $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1)); return $arr; } - - /** - * 获得上传文件的的数组的可能key值 - * @return array - */ - private function getUploadFileField() { - return array('name', 'tmp_name', 'error', 'size', 'type'); - } } \ No newline at end of file From e583e117e35c417c324f02159619134ef1fa4e8c Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 20 Jul 2011 10:49:26 +0000 Subject: [PATCH 0129/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2188 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 82 ++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 46 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index c343233e..df33288e 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -4,8 +4,8 @@ define('PHPVERSION', '5.1.2'); /* 路径相关配置信息 */ !defined('D_S') && define('D_S', DIRECTORY_SEPARATOR); -!defined('WIND_PATH') && define('WIND_PATH', dirname(__FILE__) . D_S); -!defined('COMPILE_PATH') && define('COMPILE_PATH', WIND_PATH . D_S); +!defined('WIND_PATH') && define('WIND_PATH', dirname(__FILE__)); +!defined('COMPILE_PATH') && define('COMPILE_PATH', WIND_PATH); !defined('COMPILE_LIBRARY_PATH') && define('COMPILE_LIBRARY_PATH', WIND_PATH . 'wind_basic.php'); /* debug/log */ !defined('IS_DEBUG') && define('IS_DEBUG', 1); @@ -335,7 +335,7 @@ protected static function afterRun() { */ private static function _setDefaultSystemNamespace() { self::register(WIND_PATH, 'WIND', true); - self::register(WIND_PATH . 'component' . D_S, 'COM', true); + self::register(WIND_PATH . D_S . 'component', 'COM', true); } /** @@ -414,49 +414,39 @@ private static function _checkPhpVersion() { * @return */ private static function _coreLib() { - return array('WindLogger' => 'log\\WindLogger', - 'IWindConfigParser' => 'core\\config\\parser\\IWindConfigParser', - 'WindConfigParser' => 'core\\config\\parser\\WindConfigParser', - 'WindConfig' => 'core\\config\\WindConfig', - 'WindSystemConfig' => 'core\\config\\WindSystemConfig', - 'WindActionException' => 'core\\exception\\WindActionException', - 'WindException' => 'core\\exception\\WindException', - 'WindFinalException' => 'core\\exception\\WindFinalException', - 'IWindFactory' => 'core\\factory\\IWindFactory', - 'IWindClassProxy' => 'core\\factory\\proxy\\IWindClassProxy', - 'WindClassProxy' => 'core\\factory\\proxy\\WindClassProxy', - 'WindClassDefinition' => 'core\\factory\\WindClassDefinition', - 'WindFactory' => 'core\\factory\\WindFactory', - 'WindFilter' => 'core\\filter\\WindFilter', - 'WindFilterChain' => 'core\\filter\\WindFilterChain', - 'WindHandlerInterceptor' => 'core\\filter\\WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'core\\filter\\WindHandlerInterceptorChain', - 'IWindRequest' => 'core\\request\\IWindRequest', - 'WindHttpRequest' => 'core\\request\\WindHttpRequest', - 'IWindResponse' => 'core\\response\\IWindResponse', - 'WindHttpResponse' => 'core\\response\\WindHttpResponse', - 'AbstractWindRouter' => 'core\\router\\AbstractWindRouter', - 'WindUrlBasedRouter' => 'core\\router\\WindUrlBasedRouter', - 'IWindController' => 'core\\web\\controller\\IWindController', - 'WindController' => 'core\\web\\controller\\WindController', - 'WindSimpleController' => 'core\\web\\controller\\WindSimpleController', - 'WindLoggerFilter' => 'core\\web\\filter\\WindLoggerFilter', - 'WindUrlFilter' => 'core\\web\\filter\\WindUrlFilter', - 'IWindApplication' => 'core\\web\\IWindApplication', - 'IWindErrorMessage' => 'core\\web\\IWindErrorMessage', - 'WindFormListener' => 'core\\web\\listener\\WindFormListener', - 'WindLoggerListener' => 'core\\web\\listener\\WindLoggerListener', - 'WindValidateListener' => 'core\\web\\listener\\WindValidateListener', - 'WindDispatcher' => 'core\\web\\WindDispatcher', - 'WindErrorHandler' => 'core\\web\\WindErrorHandler', - 'WindErrorMessage' => 'core\\web\\WindErrorMessage', - 'WindForward' => 'core\\web\\WindForward', - 'WindFrontController' => 'core\\web\\WindFrontController', - 'WindUrlHelper' => 'core\\web\\WindUrlHelper', - 'WindWebApplication' => 'core\\web\\WindWebApplication', - 'WindEnableValidateModule' => 'core\\WindEnableValidateModule', - 'WindHelper' => 'core\\WindHelper', - 'WindModule' => 'core\\WindModule',); + return array('WindLogger' => 'log\\WindLogger', + 'IWindConfigParser' => 'core\\config\\parser\\IWindConfigParser', + 'WindConfigParser' => 'core\\config\\parser\\WindConfigParser', 'WindConfig' => 'core\\config\\WindConfig', + 'WindSystemConfig' => 'core\\config\\WindSystemConfig', + 'WindActionException' => 'core\\exception\\WindActionException', + 'WindException' => 'core\\exception\\WindException', + 'WindFinalException' => 'core\\exception\\WindFinalException', + 'IWindFactory' => 'core\\factory\\IWindFactory', + 'IWindClassProxy' => 'core\\factory\\proxy\\IWindClassProxy', + 'WindClassProxy' => 'core\\factory\\proxy\\WindClassProxy', + 'WindClassDefinition' => 'core\\factory\\WindClassDefinition', 'WindFactory' => 'core\\factory\\WindFactory', + 'WindFilter' => 'core\\filter\\WindFilter', 'WindFilterChain' => 'core\\filter\\WindFilterChain', + 'WindHandlerInterceptor' => 'core\\filter\\WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'core\\filter\\WindHandlerInterceptorChain', + 'IWindRequest' => 'core\\request\\IWindRequest', 'WindHttpRequest' => 'core\\request\\WindHttpRequest', + 'IWindResponse' => 'core\\response\\IWindResponse', 'WindHttpResponse' => 'core\\response\\WindHttpResponse', + 'AbstractWindRouter' => 'core\\router\\AbstractWindRouter', + 'WindUrlBasedRouter' => 'core\\router\\WindUrlBasedRouter', + 'IWindController' => 'core\\web\\controller\\IWindController', + 'WindController' => 'core\\web\\controller\\WindController', + 'WindSimpleController' => 'core\\web\\controller\\WindSimpleController', + 'WindLoggerFilter' => 'core\\web\\filter\\WindLoggerFilter', + 'WindUrlFilter' => 'core\\web\\filter\\WindUrlFilter', 'IWindApplication' => 'core\\web\\IWindApplication', + 'IWindErrorMessage' => 'core\\web\\IWindErrorMessage', + 'WindFormListener' => 'core\\web\\listener\\WindFormListener', + 'WindLoggerListener' => 'core\\web\\listener\\WindLoggerListener', + 'WindValidateListener' => 'core\\web\\listener\\WindValidateListener', + 'WindDispatcher' => 'core\\web\\WindDispatcher', 'WindErrorHandler' => 'core\\web\\WindErrorHandler', + 'WindErrorMessage' => 'core\\web\\WindErrorMessage', 'WindForward' => 'core\\web\\WindForward', + 'WindFrontController' => 'core\\web\\WindFrontController', 'WindUrlHelper' => 'core\\web\\WindUrlHelper', + 'WindWebApplication' => 'core\\web\\WindWebApplication', + 'WindEnableValidateModule' => 'core\\WindEnableValidateModule', 'WindHelper' => 'core\\WindHelper', + 'WindModule' => 'core\\WindModule'); } } Wind::init(); From 4db53cb013e4bc4821d39ec65dc69fefded8615f Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 20 Jul 2011 11:00:42 +0000 Subject: [PATCH 0130/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2190 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index df33288e..74f2da39 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -4,8 +4,8 @@ define('PHPVERSION', '5.1.2'); /* 路径相关配置信息 */ !defined('D_S') && define('D_S', DIRECTORY_SEPARATOR); -!defined('WIND_PATH') && define('WIND_PATH', dirname(__FILE__)); -!defined('COMPILE_PATH') && define('COMPILE_PATH', WIND_PATH); +!defined('WIND_PATH') && define('WIND_PATH', dirname(__FILE__) . D_S); +!defined('COMPILE_PATH') && define('COMPILE_PATH', WIND_PATH . D_S); !defined('COMPILE_LIBRARY_PATH') && define('COMPILE_LIBRARY_PATH', WIND_PATH . 'wind_basic.php'); /* debug/log */ !defined('IS_DEBUG') && define('IS_DEBUG', 1); @@ -335,7 +335,7 @@ protected static function afterRun() { */ private static function _setDefaultSystemNamespace() { self::register(WIND_PATH, 'WIND', true); - self::register(WIND_PATH . D_S . 'component', 'COM', true); + self::register(WIND_PATH . 'component', 'COM', true); } /** From 077ff218807cd63eb2f88ed8159932b55bb2c857 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 20 Jul 2011 11:06:54 +0000 Subject: [PATCH 0131/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2191 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 65 +++++++++++++++++++-------------------- wind/_compile/compile.php | 2 +- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 74f2da39..98948277 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -334,7 +334,7 @@ protected static function afterRun() { * @return */ private static function _setDefaultSystemNamespace() { - self::register(WIND_PATH, 'WIND', true); + self::register(trim(WIND_PATH, D_S), 'WIND', true); self::register(WIND_PATH . 'component', 'COM', true); } @@ -414,39 +414,36 @@ private static function _checkPhpVersion() { * @return */ private static function _coreLib() { - return array('WindLogger' => 'log\\WindLogger', - 'IWindConfigParser' => 'core\\config\\parser\\IWindConfigParser', - 'WindConfigParser' => 'core\\config\\parser\\WindConfigParser', 'WindConfig' => 'core\\config\\WindConfig', - 'WindSystemConfig' => 'core\\config\\WindSystemConfig', - 'WindActionException' => 'core\\exception\\WindActionException', - 'WindException' => 'core\\exception\\WindException', - 'WindFinalException' => 'core\\exception\\WindFinalException', - 'IWindFactory' => 'core\\factory\\IWindFactory', - 'IWindClassProxy' => 'core\\factory\\proxy\\IWindClassProxy', - 'WindClassProxy' => 'core\\factory\\proxy\\WindClassProxy', - 'WindClassDefinition' => 'core\\factory\\WindClassDefinition', 'WindFactory' => 'core\\factory\\WindFactory', - 'WindFilter' => 'core\\filter\\WindFilter', 'WindFilterChain' => 'core\\filter\\WindFilterChain', - 'WindHandlerInterceptor' => 'core\\filter\\WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'core\\filter\\WindHandlerInterceptorChain', - 'IWindRequest' => 'core\\request\\IWindRequest', 'WindHttpRequest' => 'core\\request\\WindHttpRequest', - 'IWindResponse' => 'core\\response\\IWindResponse', 'WindHttpResponse' => 'core\\response\\WindHttpResponse', - 'AbstractWindRouter' => 'core\\router\\AbstractWindRouter', - 'WindUrlBasedRouter' => 'core\\router\\WindUrlBasedRouter', - 'IWindController' => 'core\\web\\controller\\IWindController', - 'WindController' => 'core\\web\\controller\\WindController', - 'WindSimpleController' => 'core\\web\\controller\\WindSimpleController', - 'WindLoggerFilter' => 'core\\web\\filter\\WindLoggerFilter', - 'WindUrlFilter' => 'core\\web\\filter\\WindUrlFilter', 'IWindApplication' => 'core\\web\\IWindApplication', - 'IWindErrorMessage' => 'core\\web\\IWindErrorMessage', - 'WindFormListener' => 'core\\web\\listener\\WindFormListener', - 'WindLoggerListener' => 'core\\web\\listener\\WindLoggerListener', - 'WindValidateListener' => 'core\\web\\listener\\WindValidateListener', - 'WindDispatcher' => 'core\\web\\WindDispatcher', 'WindErrorHandler' => 'core\\web\\WindErrorHandler', - 'WindErrorMessage' => 'core\\web\\WindErrorMessage', 'WindForward' => 'core\\web\\WindForward', - 'WindFrontController' => 'core\\web\\WindFrontController', 'WindUrlHelper' => 'core\\web\\WindUrlHelper', - 'WindWebApplication' => 'core\\web\\WindWebApplication', - 'WindEnableValidateModule' => 'core\\WindEnableValidateModule', 'WindHelper' => 'core\\WindHelper', - 'WindModule' => 'core\\WindModule'); + return array('WindLogger' => 'log/WindLogger', 'IWindConfigParser' => 'core/config/parser/IWindConfigParser', + 'WindConfigParser' => 'core/config/parser/WindConfigParser', 'WindConfig' => 'core/config/WindConfig', + 'WindSystemConfig' => 'core/config/WindSystemConfig', + 'WindActionException' => 'core/exception/WindActionException', + 'WindException' => 'core/exception/WindException', + 'WindFinalException' => 'core/exception/WindFinalException', 'IWindFactory' => 'core/factory/IWindFactory', + 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', + 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', + 'WindClassDefinition' => 'core/factory/WindClassDefinition', 'WindFactory' => 'core/factory/WindFactory', + 'WindFilter' => 'core/filter/WindFilter', 'WindFilterChain' => 'core/filter/WindFilterChain', + 'WindHandlerInterceptor' => 'core/filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'core/filter/WindHandlerInterceptorChain', + 'IWindRequest' => 'core/request/IWindRequest', 'WindHttpRequest' => 'core/request/WindHttpRequest', + 'IWindResponse' => 'core/response/IWindResponse', 'WindHttpResponse' => 'core/response/WindHttpResponse', + 'AbstractWindRouter' => 'core/router/AbstractWindRouter', + 'WindUrlBasedRouter' => 'core/router/WindUrlBasedRouter', + 'IWindController' => 'core/web/controller/IWindController', + 'WindController' => 'core/web/controller/WindController', + 'WindSimpleController' => 'core/web/controller/WindSimpleController', + 'WindLoggerFilter' => 'core/web/filter/WindLoggerFilter', 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', + 'IWindApplication' => 'core/web/IWindApplication', 'IWindErrorMessage' => 'core/web/IWindErrorMessage', + 'WindFormListener' => 'core/web/listener/WindFormListener', + 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', + 'WindValidateListener' => 'core/web/listener/WindValidateListener', + 'WindDispatcher' => 'core/web/WindDispatcher', 'WindErrorHandler' => 'core/web/WindErrorHandler', + 'WindErrorMessage' => 'core/web/WindErrorMessage', 'WindForward' => 'core/web/WindForward', + 'WindFrontController' => 'core/web/WindFrontController', 'WindUrlHelper' => 'core/web/WindUrlHelper', + 'WindWebApplication' => 'core/web/WindWebApplication', + 'WindEnableValidateModule' => 'core/WindEnableValidateModule', 'WindHelper' => 'core/WindHelper', + 'WindModule' => 'core/WindModule'); } } Wind::init(); diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php index a822f95e..96826f31 100644 --- a/wind/_compile/compile.php +++ b/wind/_compile/compile.php @@ -33,5 +33,5 @@ function parseFilePath($filePath) { list($namespace, $filePath) = explode(':', $filePath); - return str_replace('.', D_S, $filePath); + return str_replace('.', '/', $filePath); } From ba7c409bbcb28746d7b9fa25acc68f95a9c628d7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 20 Jul 2011 11:12:33 +0000 Subject: [PATCH 0132/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2192 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index 98948277..17357ff0 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -334,7 +334,7 @@ protected static function afterRun() { * @return */ private static function _setDefaultSystemNamespace() { - self::register(trim(WIND_PATH, D_S), 'WIND', true); + self::register(WIND_PATH, 'WIND', true); self::register(WIND_PATH . 'component', 'COM', true); } From 85c6ed3bd5138239af9b3b0a35dd8ff29428e22f Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 20 Jul 2011 11:44:27 +0000 Subject: [PATCH 0133/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D:=20=20=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E4=B8=8A=E4=BC=A0=E6=94=AF=E6=8C=81=E5=A4=9A=E7=BB=84?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2193 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindFormUpload.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index 2652a14c..4e85ef7a 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -88,16 +88,17 @@ private function doUp($key, $value, $saveDir, $preFileName) { return array(); } $fileName = $this->getFileName($upload, $preFileName); + $upload['filename'] = $fileName; $source = $this->getSavePath($fileName, $saveDir); if (!$this->postUpload($atc_attachment, $source)) { - $upload['savePath'] = $source; + $upload['fileuploadurl'] = $source; $this->errorInfo['upload'][$key][] = $upload; $this->hasError = true; return array(); } $upload['size'] = ceil(filesize($source) / 1024); - $upload['savePath'] = $source; + $upload['fileuploadurl'] = $source; return $upload; } From 8e8e762b94ccef1fbf53193eb5beeef711ec1852 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 21 Jul 2011 02:30:25 +0000 Subject: [PATCH 0134/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2194 18ba2127-5a84-46d4-baec-3457e417f034 --- .../WindTemplateCompilerComponent.php | 213 +++++++++--------- 1 file changed, 112 insertions(+), 101 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php index 8f8dc8dc..f6182575 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php @@ -1,25 +1,29 @@ + * * the last known user to change this file in the repository * @author xiaoxiao * @version 2011-7-20 xiaoxiao */ class WindTemplateCompilerComponent extends AbstractWindTemplateCompiler { - + protected $name = ''; //组件名字 + - protected $args = '';//传递给组件的参数 + protected $args = ''; //传递给组件的参数 + - protected $templateDir = '';//组件调用的模板路径 + protected $templateDir = ''; //组件调用的模板路径 - protected $appConfig = '';//组件的配置文件 + + protected $appConfig = ''; //组件的配置文件 - protected $componentPath = '';//组件的入口地址 + protected $componentPath = ''; //组件的入口地址 + + /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() */ @@ -35,108 +39,115 @@ private function getScript($content) { if (!isset($params['name']) || !isset($params['componentPath'])) throw new WindException('组件编译错误!'); $content = "rebuildConfig($params) . (isset($params['args']) ? $this->registerUrlParams($params) : '') . - "\$componentPath = Wind::getRealDir('" . $params['componentPath'] . "');\r\n" . - "Wind::register(\$componentPath, '" . $params['name'] . "');\r\n" . - "Wind::run('" . $params['name'] . "', \$config);\r\n?>"; + "\$componentPath = Wind::getRealDir('" . $params['componentPath'] . "');\r\n" . + "Wind::register(\$componentPath, '" . $params['name'] . "');\r\n" . "Wind::run('" . $params['name'] . + "', \$config);\r\n?>"; return $content; } - + /** * 编译获得配置文件 * @param array $params * @return array */ private function rebuildConfig($params) { - $temp = "\$configParser = new WindConfigParser();\r\n" . - "\$configPath = Wind::getRealPath('" . $params['appConfig'] . "');\r\n"; - $temp .= "\$config = \$configParser->parse(\$configPath, '" . $params['name'] . "');\r\n"; - if (!isset($params['templateDir'])) return $temp; - if (isset($params['args']['m'])) $temp .= "\$config['web-apps']['" . $params['name'] . "']['modules']['" . $params['args']['m'] . "']['view']['config']['template-dir']['value'] = '" . $params['templateDir'] . "';\r\n"; - else { - $temp .= "foreach(\$config['web-apps']['" . $params['name'] . "']['modules'] as \$key => \$value) {\r\n" . - "\t\$config['web-apps']['" . $params['name'] . "']['modules'][\$key]['view']['config']['template-dir']['value'] = '" . $params['templateDir'] . "';\r\n" . - "}\r\n"; - } - return $temp; - } - - /** - * 注册变量信息 - * - * @param array $params - */ - private function registerUrlParams($params) { - $temp = ''; - $temp = "\$mKey = isset(\$config['web-apps']['" . $params['name'] . "']['router']['config']['module']['url-param']) ? \$config['web-apps']['" . $params['name'] . "']['router']['config']['module']['url-param'] : 'm';\r\n" . - "\$cKey = isset(\$config['web-apps']['" . $params['name'] . "']['router']['config']['controller']['url-param']) ? \$config['web-apps']['" . $params['name'] . "']['router']['config']['controller']['url-param'] : 'c';\r\n" . - "\$aKey = isset(\$config['web-apps']['" . $params['name'] . "']['router']['config']['action']['url-param']) ? \$config['web-apps']['" . $params['name'] . "']['router']['config']['action']['url-param'] : 'a';\r\n" . - "\$_GET[\$mKey] = '" . $params['args']['m'] . "';\r\n" . - "\$_GET[\$cKey] = '" . $params['args']['c'] . "';\r\n" . - "\$_GET[\$aKey] = '" . $params['args']['a'] . "';\r\n"; - unset($params['args']['a'], $params['args']['c'], $params['args']['m']); - foreach($params['args'] as $key => $value) { - $temp .= is_array($value) ? "\$_GET['" . $key . "'] = " . $value . ";\r\n" : "\$_GET['" . $key . "'] = '" . $value . "';\r\n"; - } - return $temp; - } - - /** - * 匹配配置信息 - * - * @param string $content - * @return array - */ - private function matchConfig($content) { - preg_match_all('/(\w+=[\'|"]?[\w|.|:]+[\'|"]?)/', $content, $mathcs); - list($config, $key, $val) = array(array(), '', ''); - foreach ($mathcs[0] as $value) { - list($key, $val) = explode('=', $value); - if (!in_array($key, $this->getProperties()) || !$val) continue; - switch($key) { - case 'args': - $config['args'] = $this->compileArgs(trim($val, '\'"')); - break; - default: - $config[$key] = trim($val, '\'"'); - break; + $temp = "\$configParser = new WindConfigParser();\r\n" . "\$configPath = Wind::getRealPath('" . + $params['appConfig'] . "');\r\n"; + $temp .= "\$config = \$configParser->parse(\$configPath, '" . $params['name'] . "');\r\n"; + if (!isset($params['templateDir'])) return $temp; + if (isset($params['args']['m'])) + $temp .= "\$config['web-apps']['" . $params['name'] . "']['modules']['" . $params['args']['m'] . + "']['view']['config']['template-dir']['value'] = '" . $params['templateDir'] . "';\r\n"; + else { + $temp .= "foreach(\$config['web-apps']['" . $params['name'] . + "']['modules'] as \$key => \$value) {\r\n" . "\t\$config['web-apps']['" . $params['name'] . + "']['modules'][\$key]['view']['config']['template-dir']['value'] = '" . $params['templateDir'] . + "';\r\n" . "}\r\n"; + } + return $temp; } - } - return $config; - } - - /** - * 解析传递给url的参数信息 - * - * @param string $arg - * @return array - */ - private function compileArgs($arg) { - $args = explode(':', $arg); - $urlParams = array(); - list($urlParams['a'], $urlParams['c'], $urlParams['m']) = array('', '', ''); - switch(count($args)) { - case 1: - $urlParams['a'] = $args[0]; - break; - case 2: - list($urlParams['c'], $urlParams['a']) = $args; - break; - case 3: - list($urlParams['m'], $urlParams['c'], $urlParams['a']) = $args; - break; - default; - break; - } - return $urlParams; - } - - /* (non-PHPdoc) + /** + * 注册变量信息 + * + * @param array $params + */ + private function registerUrlParams($params) { + $temp = ''; + $temp = "\$mKey = isset(\$config['web-apps']['" . $params['name'] . + "']['router']['config']['module']['url-param']) ? \$config['web-apps']['" . $params['name'] . + "']['router']['config']['module']['url-param'] : 'm';\r\n" . "\$cKey = isset(\$config['web-apps']['" . + $params['name'] . "']['router']['config']['controller']['url-param']) ? \$config['web-apps']['" . + $params['name'] . "']['router']['config']['controller']['url-param'] : 'c';\r\n" . + "\$aKey = isset(\$config['web-apps']['" . $params['name'] . + "']['router']['config']['action']['url-param']) ? \$config['web-apps']['" . $params['name'] . + "']['router']['config']['action']['url-param'] : 'a';\r\n" . "\$_GET[\$mKey] = '" . + $params['args']['m'] . "';\r\n" . "\$_GET[\$cKey] = '" . $params['args']['c'] . "';\r\n" . + "\$_GET[\$aKey] = '" . $params['args']['a'] . "';\r\n"; + unset($params['args']['a'], $params['args']['c'], $params['args']['m']); + foreach ($params['args'] as $key => $value) { + $temp .= is_array($value) ? "\$_GET['" . $key . "'] = " . $value . ";\r\n" : "\$_GET['" . $key . + "'] = '" . $value . "';\r\n"; + } + return $temp; + } + + /** + * 匹配配置信息 + * + * @param string $content + * @return array + */ + private function matchConfig($content) { + preg_match_all('/(\w+=[\'|"]?[\w|.|:]+[\'|"]?)/', $content, $mathcs); + list($config, $key, $val) = array(array(), '', ''); + foreach ($mathcs[0] as $value) { + list($key, $val) = explode('=', $value); + if (!in_array($key, $this->getProperties()) || !$val) continue; + switch ($key) { + case 'args': + $config['args'] = $this->compileArgs(trim($val, '\'"')); + break; + default: + $config[$key] = trim($val, '\'"'); + break; + } + } + return $config; + } + + /** + * 解析传递给url的参数信息 + * + * @param string $arg + * @return array + */ + private function compileArgs($arg) { + $args = explode(':', $arg); + $urlParams = array(); + list($urlParams['a'], $urlParams['c'], $urlParams['m']) = array('', '', ''); + switch (count($args)) { + case 1: + $urlParams['a'] = $args[0]; + break; + case 2: + list($urlParams['c'], $urlParams['a']) = $args; + break; + case 3: + list($urlParams['m'], $urlParams['c'], $urlParams['a']) = $args; + break; + default: + break; + } + return $urlParams; + } + + /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::getProperties() */ - protected function getProperties() { - return array('name', 'templateDir', 'appConfig', 'args', 'componentPath'); - } -} - -?> \ No newline at end of file + protected function getProperties() { + return array('name', 'templateDir', 'appConfig', 'args', 'componentPath'); + } + } + + ?> \ No newline at end of file From 83c340402ee9a0f3afdd0fffd011fa227f7e08b9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 21 Jul 2011 08:16:13 +0000 Subject: [PATCH 0135/1065] =?UTF-8?q?bug=20fixed=20{{$a}}=20=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=BD=A2=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2195 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/compiler/WindViewTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/viewer/compiler/WindViewTemplate.php b/wind/component/viewer/compiler/WindViewTemplate.php index 854bd5b2..22bf1aba 100644 --- a/wind/component/viewer/compiler/WindViewTemplate.php +++ b/wind/component/viewer/compiler/WindViewTemplate.php @@ -101,7 +101,7 @@ protected function getTags() { /*标签解析结束*/ $_tags += (array) parent::getTags(); $_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', - '/({@|{\$)[^{@=\n]*}/i'); + '/({@|{\$)[^}{@=\n]*}/i'); $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); return $_tags; } From ae3cb7726012e94709d453611c734d21c1b3affa Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 21 Jul 2011 09:06:39 +0000 Subject: [PATCH 0136/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2196 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 45 ++++------------------- wind/core/factory/WindClassDefinition.php | 1 - 2 files changed, 7 insertions(+), 39 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 17357ff0..2d12f72a 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -343,8 +343,10 @@ private static function _setDefaultSystemNamespace() { * @return */ private static function _checkEnvironment() { - if (!self::_checkPhpVersion()) throw new Exception('php version is too old, php ' . PHPVERSION . ' or later.', - E_WARNING); + if (version_compare(PHP_VERSION, PHPVERSION) === -1) { + throw new Exception('[wind._checkEnvironment] php version is lower, php ' . PHPVERSION . ' or later.', + E_WARNING); + } if (!defined('COMPILE_PATH')) throw new Exception('compile path undefined.'); function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); } @@ -362,17 +364,6 @@ private static function _setImport($className, $classPath) { self::autoLoad($className, $classPath); } - /** - * 判断是否类是否已经被加载,如果已经被加载则返回路径信息,如果没有被加载则返回false - * @param string $path - * @return boolean|string - */ - private static function _isImported($param) { - if (isset(self::$_imports[$param])) return self::$_imports[$param]; - if (in_array($param, self::$_imports)) return $param; - return false; - } - /** * 注册自动加载回调方法 * @return @@ -387,34 +378,12 @@ private static function _registerAutoloader() { /** * 加载核心层库函数 + * * @return */ private static function _loadBaseLib() { - $_core = self::_coreLib(); - self::$_classes = $_core; - } - - /* private utility */ - private static function _checkPhpVersion() { - $v1 = $v2 = $v3 = $m1 = $m2 = $m3 = 0; - $phpversion = phpversion(); - sscanf($phpversion, "%d.%d.%d", $v1, $v2, $v3); - sscanf(PHPVERSION, "%d.%d.%d", $m1, $m2, $m3); - if ($v1 > $m1) return true; - if ($v1 < $m1) return false; - if ($v2 > $m2) return true; - if ($v2 < $m2) return false; - if ($v3 > $m3) return true; - if ($v3 < $m3) return false; - return true; - } - - /** - * 核心库文件 - * @return - */ - private static function _coreLib() { - return array('WindLogger' => 'log/WindLogger', 'IWindConfigParser' => 'core/config/parser/IWindConfigParser', + self::$_classes = array('WindLogger' => 'log/WindLogger', + 'IWindConfigParser' => 'core/config/parser/IWindConfigParser', 'WindConfigParser' => 'core/config/parser/WindConfigParser', 'WindConfig' => 'core/config/WindConfig', 'WindSystemConfig' => 'core/config/WindSystemConfig', 'WindActionException' => 'core/exception/WindActionException', diff --git a/wind/core/factory/WindClassDefinition.php b/wind/core/factory/WindClassDefinition.php index efc71c37..6c59b4b7 100644 --- a/wind/core/factory/WindClassDefinition.php +++ b/wind/core/factory/WindClassDefinition.php @@ -285,7 +285,6 @@ protected function executeFactoryMethod($args) { */ protected function init($classDefinition) { try { - if (empty($classDefinition)) return; foreach ($classDefinition as $key => $value) { if (strpos($key, '-') !== false) { list($_s1, $_s2) = explode('-', $key); From 3bfe701911e963b01a2704047e3dcc0950992cef Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 21 Jul 2011 11:06:46 +0000 Subject: [PATCH 0137/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2197 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 183 +++++++------ wind/component/cache/IWindCacheDependency.php | 13 +- .../cache/dependency/WindCacheDependency.php | 126 ++++----- .../cache/exception/WindCacheException.php | 19 -- wind/component/cache/operator/WindApc.php | 65 ----- .../cache/operator/WindEaccelerator.php | 118 -------- .../component/cache/operator/WindMemcache.php | 141 ---------- .../component/cache/operator/WindWinCache.php | 88 ------ wind/component/cache/operator/WindXCache.php | 66 ----- .../cache/operator/WindZendCache.php | 55 ---- .../component/cache/strategy/WindApcCache.php | 45 ++++ .../component/cache/strategy/WindCacheApc.php | 55 ---- wind/component/cache/strategy/WindCacheDb.php | 251 ------------------ .../cache/strategy/WindCacheEaccelerator.php | 58 ---- .../component/cache/strategy/WindCacheMem.php | 114 -------- .../component/cache/strategy/WindCacheWin.php | 54 ---- .../cache/strategy/WindCacheXCache.php | 55 ---- .../cache/strategy/WindCacheZend.php | 52 ++-- wind/component/cache/strategy/WindDbCache.php | 233 ++++++++++++++++ .../cache/strategy/WindEacceleratorCache.php | 54 ++++ .../{WindCacheFile.php => WindFileCache.php} | 114 ++++---- .../component/cache/strategy/WindMemCache.php | 157 +++++++++++ .../component/cache/strategy/WindWinCache.php | 44 +++ wind/component/cache/strategy/WindXCache.php | 49 ++++ 24 files changed, 810 insertions(+), 1399 deletions(-) delete mode 100644 wind/component/cache/exception/WindCacheException.php delete mode 100644 wind/component/cache/operator/WindApc.php delete mode 100644 wind/component/cache/operator/WindEaccelerator.php delete mode 100644 wind/component/cache/operator/WindMemcache.php delete mode 100644 wind/component/cache/operator/WindWinCache.php delete mode 100644 wind/component/cache/operator/WindXCache.php delete mode 100644 wind/component/cache/operator/WindZendCache.php create mode 100644 wind/component/cache/strategy/WindApcCache.php delete mode 100644 wind/component/cache/strategy/WindCacheApc.php delete mode 100644 wind/component/cache/strategy/WindCacheDb.php delete mode 100644 wind/component/cache/strategy/WindCacheEaccelerator.php delete mode 100644 wind/component/cache/strategy/WindCacheMem.php delete mode 100644 wind/component/cache/strategy/WindCacheWin.php delete mode 100644 wind/component/cache/strategy/WindCacheXCache.php create mode 100644 wind/component/cache/strategy/WindDbCache.php create mode 100644 wind/component/cache/strategy/WindEacceleratorCache.php rename wind/component/cache/strategy/{WindCacheFile.php => WindFileCache.php} (57%) create mode 100644 wind/component/cache/strategy/WindMemCache.php create mode 100644 wind/component/cache/strategy/WindWinCache.php create mode 100644 wind/component/cache/strategy/WindXCache.php diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index 53c56066..eb99991c 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -38,20 +38,20 @@ abstract class AbstractWindCache extends WindModule { */ const DATA = 'data'; /** - * 配置文件中标志过期时间名称定义(也包含缓存元数据中过期时间 的定义) + * 配置文件中标志缓存依赖名称的定义 * @var string */ - const EXPIRE = 'expires'; + const DEPENDENCY = 'dependency'; /** - * 配置文件中标志缓存依赖名称的定义 + * 配置文件中标志过期时间名称定义(也包含缓存元数据中过期时间 的定义) * @var string */ - const DEPENDENCY = 'dependency'; + const EXPIRE = 'expires'; /** * 配置文件中缓存安全码名称的定义 * @var string */ - const SECURITY = 'security'; + const SECURITYCODE = 'securityCode'; /** * 配置文件中缓存键的前缀名称的定义 * @var string @@ -66,14 +66,61 @@ abstract class AbstractWindCache extends WindModule { * @param IWindCacheDependency $denpendency 缓存依赖 * @return boolean */ - public abstract function set($key, $value, $expires = 0, IWindCacheDependency $denpendency = null); + public function set($key, $value, $expires = 0, IWindCacheDependency $denpendency = null) { + $data = array( + self::DATA => $value, + self::EXPIRE => $expires, + self::STORETIME => time(), + self::DEPENDENCY => null, + self::DEPENDENCYCLASS => ''); + if (null != $denpendency) { + $denpendency->injectDependent(); + $data[self::DEPENDENCY] = serialize($denpendency); + $data[self::DEPENDENCYCLASS] = get_class($denpendency); + } + return $this->addValue($this->buildSecurityKey($key), serialize($data), $expires); + } + + protected function + /** + * 执行添加操作 + * + * @param string $key + * @param object $value + * @param int $expires + * @throws WindException + */ + protected abstract function addValue($key, $value, $expires = 0); /** * 获取指定缓存 * @param string $key 获取缓存数据的标识,即键 * @return mixed */ - public abstract function get($key); + public function get($key) { + return $this->formatData($this->getValue($this->buildSecurityKey($key))); + + } + + /** + * 格式化输出 + * @param string $value + * @return array + */ + protected function formatData($value) { + $data = unserialize($value); + if (!is_array($data)) return null; + if ($this->hasChanged($key, $data)) return null; + return isset($data[self::DATA]) ? $data[self::DATA] : null; + } + + /** + * 执行获取操作 + * + * @param string $key + * @throws WindException + */ + protected abstract function getValue($key); /** * 通过key批量获取缓存数据 @@ -87,13 +134,22 @@ public function batchGet(array $keys) { } return $data; } - + /** - * 删除缓存数据 + * 删除缓存数据 + * * @param string $key 获取缓存数据的标识,即键 * @return string */ - public abstract function delete($key); + public function delete($key) { + return $this->deleteValue($this->buildSecurityKey($key)); + } + + /** + * 需要实现的删除操作 + * @param string $key + */ + protected abstract function deleteValue($key); /** * 通过key批量删除缓存数据 @@ -101,9 +157,7 @@ public abstract function delete($key); * @return boolean */ public function batchDelete(array $keys) { - foreach ($keys as $key) { - $this->delete($key); - } + foreach ($keys as $key) $this->delete($key); return true; } @@ -118,69 +172,23 @@ public abstract function clear(); * @param array $data 缓存中的数据 * @return boolean true表示缓存依赖已变更,false表示缓存依赖未变改 */ - protected function checkDependencyChanged($key, array $data) { - if (isset($data[self::DEPENDENCY]) && isset($data[self::DEPENDENCYCLASS])) { - Wind::import('Wind:component.cache.dependency.' . $data[self::DEPENDENCYCLASS]); - /* @var $dependency IWindCacheDependency*/ - $dependency = unserialize($data[self::DEPENDENCY]); - if (($dependency instanceof IWindCacheDependency) && $dependency->hasChanged()) { - $this->delete($key); - return true; - } + protected function hasChanged($key, array $data) { + if (null === $data[self::DEPENDENCY] && '' === $data[self::DEPENDENCYCLASS]) return false; + $dependency = unserialize($data[self::DEPENDENCY]); + if (($dependency instanceof IWindCacheDependency) && $dependency->hasChanged()) { + $this->delete($key); + return true; } return false; } - /** - * 从缓存元数据中取得真实的数据 - * @param string $key - * @param mixed $data - * @return mixed - */ - protected function getDataFromMeta($key, $data) { - if (is_array($data)) { - if ($this->checkDependencyChanged($key, $data)) { - return null; - } - return isset($data[self::DATA]) ? $data[self::DATA] : null; - } - return $data; - } - - /** - * 获取存储的数据 - * @param string $value - * @param string $expires - * @param IWindCacheDependency $denpendency - * @return string - */ - protected function storeData($value, $expires = null, $denpendency = null) { - $data = array( - self::DATA => $value, - self::EXPIRE => $expires, - self::STORETIME => time()); - if ($denpendency && (($denpendency instanceof IWindCacheDependency))) { - $denpendency->injectDependent($this); - $data[self::DEPENDENCY] = serialize($denpendency); - $data[self::DEPENDENCYCLASS] = get_class($denpendency); - } - return serialize($data); - } - /** * 生成安全的key * @param string $key * @return string */ protected function buildSecurityKey($key) { - return $this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key : $key; - } - - /** - * @return the $securityCode - */ - protected function getSecurityCode() { - return $this->getConfig(self::SECURITY, WIND_CONFIG_VALUE, '', $this->securityCode); + return $this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key . $this->getSecurityCode() : $key . $this->getSecurityCode(); } /** @@ -190,18 +198,21 @@ protected function getSecurityCode() { protected function getKeyPrefix() { return $this->keyPrefix; } - + /** - * 返回过期时间设置,默认值为0永不过期 - * @return the $expire + * @param sting $keyPrefix */ - public function getExpire() { - if ('' === $this->expire) { - $this->expire = $this->getConfig(self::EXPIRE, WIND_CONFIG_VALUE, '', '0'); - } - return $this->expire; + public function setKeyPrefix($keyPrefix) { + $this->keyPrefix = $keyPrefix; } - + + /** + * @return the $securityCode + */ + protected function getSecurityCode() { + return $this->securityCode; + } + /** * @param string $securityCode */ @@ -210,16 +221,28 @@ public function setSecurityCode($securityCode) { } /** - * @param sting $keyPrefix + * 返回过期时间设置,默认值为0永不过期 + * @return the $expire */ - public function setKeyPrefix($keyPrefix) { - $this->keyPrefix = $keyPrefix; + public function getExpire() { + return $this->expire; } - + /** * @param int $expire */ public function setExpire($expire) { - $this->expire = $expire; + $this->expire = intval($expire); + } + + /** + * 设置配置信息 + * @param array $config + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setSecurityCode($this->getConfig(self::SECURITYCODE, '', '')); + $this->setKeyPrefix($this->getConfig(self::KEYPREFIX, '', '')); + $this->setExpire($this->getCofnig(self::EXPIRE, '', 0)); } } \ No newline at end of file diff --git a/wind/component/cache/IWindCacheDependency.php b/wind/component/cache/IWindCacheDependency.php index d0776536..6e489703 100644 --- a/wind/component/cache/IWindCacheDependency.php +++ b/wind/component/cache/IWindCacheDependency.php @@ -20,24 +20,19 @@ interface IWindCacheDependency { /** * 注入依赖 - * @param IWindCache $cache + * @param mixed */ - public function injectDependent(IWindCache $cache); + public function injectDependent(); /** - * CacheDependency 对象是否已更改 + * 是否已更新 * @return boolean */ public function hasChanged(); /** * 获取依赖项的上次更改时间 - * @return string + * @return int */ public function getLastModified(); - - /** - * 标记依赖项的上次更改时间。 - */ - public function setLastModified(); } \ No newline at end of file diff --git a/wind/component/cache/dependency/WindCacheDependency.php b/wind/component/cache/dependency/WindCacheDependency.php index 5bf4ad77..2f6aa893 100644 --- a/wind/component/cache/dependency/WindCacheDependency.php +++ b/wind/component/cache/dependency/WindCacheDependency.php @@ -1,88 +1,58 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -Wind::import('WIND:component.cache.IWindCacheDependency'); -/** - * 缓存依赖基类 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindCacheDependency implements IWindCacheDependency{ + + * @author Qian Su + * @version $Id$ + * @package + */ +Wind::import('WIND:component.cache.IWindCacheDependency'); +class WindCacheDependency implements IWindCacheDependency { /** * @var mixed 缓存依赖控制者 - */ - protected $dependent = null; + */ + protected $dependent = ''; + + protected $data = ''; + /** * @var string 依赖项的上次更改时间 - */ - protected $lastModified; + */ + protected $lastModified; /** * @var IWindCache 缓存创建者 - */ - protected $cache = null; - - public function __construct(){ - - } - - /** + */ + protected $cache = null; + + public function __construct($dependent = null) { + $this->dependent = $dependent; + } + + /* * @see wind/component/cache/base/IWindCacheDependency#injectDependent() - */ - public function injectDependent(IWindCache $cache){ - $this->cache = $cache; - $this->setLastModified(); - $this->dependent = $this->notifyDependencyChanged(); - } - - /** + */ + public function injectDependent() { + $this->lastModified = time(); + } + + /* * @see wind/component/cache/base/IWindCacheDependency#hasChanged() - */ - public function hasChanged(){ - return $this->getDependent() != $this->notifyDependencyChanged(); - } - /** + */ + public function hasChanged() { + return $this->data != $this->notifyDependencyChanged(); + } + + /* * @see wind/component/cache/base/IWindCacheDependency#getLastModified() - */ - public function getLastModified(){ - return $this->lastModified; - } - - - /** - * @see wind/component/cache/base/IWindCacheDependency#setLastModified() - */ - public function setLastModified(){ - $this->lastModified = time(); - } - - /** - * 获取缓存依赖控制者 - * @return mixed - */ - public function getDependent(){ - return $this->dependent; - } - - /** - * 取得创建缓存依赖的创造者. - * @return IWindCache - */ - public function getCache(){ - return $this->cache; - } - - /* - * 通知依赖项已更改。 - */ - protected function notifyDependencyChanged(){ - return null; - } - + */ + public function getLastModified() { + return $this->lastModified; + } + + /** + * 是否有变化 + * @return NULL + */ + protected abstract function notifyDependencyChanged(); + } \ No newline at end of file diff --git a/wind/component/cache/exception/WindCacheException.php b/wind/component/cache/exception/WindCacheException.php deleted file mode 100644 index 649964bf..00000000 --- a/wind/component/cache/exception/WindCacheException.php +++ /dev/null @@ -1,19 +0,0 @@ - 2010-11-7 -*@link http://www.phpwind.com -*@copyright Copyright © 2003-2110 phpwind.com -*@license -*/ - -Wind::import('WIND:core.exception.WindException'); - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindCacheException extends WindException{ - -} \ No newline at end of file diff --git a/wind/component/cache/operator/WindApc.php b/wind/component/cache/operator/WindApc.php deleted file mode 100644 index b164fa39..00000000 --- a/wind/component/cache/operator/WindApc.php +++ /dev/null @@ -1,65 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - * tags - */ -class WindApc { - - public function __construct() { - if (!function_exists('apc_store')) { - throw new WindException('The apc extension must be loaded !'); - } - } - - /** - * 添加缓存 - * @param string $key 缓存键 - * @param mixed $value 缓存键对应的值 - * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 - */ - public function add($key, $value, $ttl = 0){ - return apc_add($key, $value, $ttl); - } - /** - * 设置缓存,如果缓存存在,则覆写,否则添加 - * @param string $key 缓存键 - * @param mixed $value 缓存键对应的值 - * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 - */ - public function set($key, $value, $ttl = 0) { - return apc_store($key, $value, $ttl); - } - - /** - * 根据键移除缓存 - * @param string $key 缓存的键 - * @return mixed - */ - public function get($key) { - return apc_fetch($key); - } - /** - * 删除缓存 - * @param string $key - */ - public function delete($key) { - return apc_delete($key); - } - /** - * 清空所有缓存 - */ - public function flush() { - apc_clear_cache(); - return apc_clear_cache('user'); - } -} \ No newline at end of file diff --git a/wind/component/cache/operator/WindEaccelerator.php b/wind/component/cache/operator/WindEaccelerator.php deleted file mode 100644 index 24d1403b..00000000 --- a/wind/component/cache/operator/WindEaccelerator.php +++ /dev/null @@ -1,118 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindEaccelerator { - public function __construct() { - if (!function_exists('eaccelerator_get')) { - throw new WindException('The eaccelerator extension must be loaded !'); - } - } - /** - * @param string $key 缓存键 - * @param mixed $value 缓存键对应的值 - * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 - * @return boolean - */ - public function set($key, $value, $ttl = 0) { - return eaccelerator_put($key, $value, $ttl); - } - - /** - * 根据键移除缓存 - * @param string $key 缓存的键 - * @return mixed - */ - public function get($key) { - return eaccelerator_get($key); - } - - /** - * 删除缓存 - * @param string $key - */ - public function delete($key) { - return eaccelerator_rm($key); - } - - /** - * 为 键加上锁定操作,以保证多进程多线程操作时数据的同步。 - * @param string $key - */ - public function lock($key) { - return eaccelerator_lock($key); - } - - /** - * 来释放这个锁或等待程序请求结束时自动释放这个锁。 - * @param string $key - * @return - */ - public function unlock($key) { - return eaccelerator_unlock($key); - } - /** - * 将 $eval_code 代码的输出缓存 $ttl 秒 - * @param string $key - * @param string $eval_code - * @param int $ttl - */ - public function cacheOutput($key, $eval_code, $ttl = 0) { - return eaccelerator_cache_output($key, $eval_code, $ttl); - } - - /** - * 将 $eval_code 代码的执行结果缓存 $ttl 秒 - * @param string $key - * @param string $eval_code - * @param int $ttl - */ - public function cacheResult($key, $eval_code, $ttl = 0) { - return eaccelerator_cache_result($key, $eval_code, $ttl); - } - - /** - * 将当前整页缓存 $ttl 秒。 - * @param string $key - * @param int $ttl - */ - public function pageCache($key, $ttl = 0) { - return eaccelerator_cache_page($key, $ttl); - } - - /** - * 删除由 eaccelerator_cache_page() 执行的缓存, - * @param string $key - */ - public function deletePageCache($key) { - return eaccelerator_rm_page($key); - } - - /** - * 移除清理所有已过期的key - */ - public function clearExpiredCache() { - return eaccelerator_gc(); - } - - /** - * 清空所有缓存 - */ - public function flush() { - $this->clearExpiredCache(); - $cacheKeys = eaccelerator_list_keys(); - foreach ($cacheKeys as $key) { - $this->delete(substr($key['name'], 1)); - } - } -} \ No newline at end of file diff --git a/wind/component/cache/operator/WindMemcache.php b/wind/component/cache/operator/WindMemcache.php deleted file mode 100644 index a7b73b71..00000000 --- a/wind/component/cache/operator/WindMemcache.php +++ /dev/null @@ -1,141 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * WindMemcache操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindMemcache { - - const HOST = 'host'; - - const PORT = 'port'; - - const PCONNECT = 'pconn'; - - const WEIGHT = 'weight'; - - const TIMEOUT = 'timeout'; - - const RETRY = 'retry'; - - const STATUS = 'status'; - - const FCALLBACK = 'fcallback'; - - const COMPRESS = 'compress'; - - const SERVERCONFIG = 'servers'; - - /** - * @var Memcache - */ - private $memcache = null; - - public function __construct() { - if (!extension_loaded('Memcache')) { - throw new WindException('The memcache extension must be loaded !'); - } - $this->memcache = new Memcache(); - } - - /** - * 设置一个指定 key 的缓存变量内容 - * @param string $key 缓存数据的键, 其长度不能超过250个字符 - * @param mixed $value 值,整型将直接存储,其他类型将被序列化存储,其值最大为1M - * @param int $flag 是否使用 zlib 压缩 - * @param int $expire 过期时间,0 为永不过期,可使用 unix 时间戳格式或距离当前时间的秒数,设为秒数时不能大于 2592000(30 天) - */ - public function set($key, $value, $flag = 0, $expire = 0) { - return $this->memcache->set($key, $value, $flag, $expire); - } - - /** - * 获取某个或者一组 key 的变量缓存值 - * @param mixed $key - */ - public function get($key) { - return $this->memcache->get($key); - } - - /** - * 删除某一个或一组变量的缓存 - * @param string $key 存的键 键值不能为null和'’,当它等于前面两个值的时候php会有警告错误。 - * @param int $timeout 删除这项的时间,如果它等于0,这项将被立刻删除反之如果它等于30秒,那么这项被删除在30秒内 - */ - public function delete($key, $timeout = 0) { - return $this->memcache->delete($key, $timeout); - } - - /** - * 清空所有缓存内容,不是真的删除缓存的内容,只是使所有变量的缓存过期,使内存中的内容被重写 - */ - public function flush() { - $this->memcache->flush(); - } - - /** - * 取得缓存操作句柄 - * @return Memcache - */ - public function getMemcache() { - return $this->memcache; - } - - /** - * 批量添加memecache服务器 - * @param array $servers - */ - public function setServers(array $servers) { - foreach ($servers as $server) { - if (!is_array($server)) { - throw new WindException('The memcache config is incorrect'); - } - $this->setServer($server); - } - } - - /** - * 添加memached服务器 - * @example $server = array( - * array( - * 'host'=>'localhost', - * 'port'=>11211 - * 'pconn'=>true - * ), - * array( - * 'host'=>'localhost', - * 'port'=>11212 - * 'pconn'=>false - * ) - * @param array $server - */ - public function setServer(array $server) { - if (!isset($server[self::HOST])) { - throw new WindException('The memcache server ip address is not exist'); - } - if (!isset($server[self::PORT])) { - throw new WindException('The memcache server port is not exist'); - } - $defaultServer = array(self::HOST => '', self::PORT => '', self::PCONNECT => true, self::WEIGHT => 1, - self::TIMEOUT => 15, self::RETRY => 15, self::STATUS => true, self::FCALLBACK => null); - list($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback) = array_values(array_merge($defaultServer, $server)); - $this->memcache->addServer($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback); - } - - public function close() { - return $this->memcache->close(); - } - - public function __destruct() { - $this->close(); - } -} \ No newline at end of file diff --git a/wind/component/cache/operator/WindWinCache.php b/wind/component/cache/operator/WindWinCache.php deleted file mode 100644 index e0cf5a53..00000000 --- a/wind/component/cache/operator/WindWinCache.php +++ /dev/null @@ -1,88 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - * tags - */ -class WindWinCache{ - public function __construct() { - if (!function_exists('wincache_ucache_get')) { - throw new WindException('The wincache extension must be loaded !'); - } - } - - /** - * 添加缓存 - * @param string $key 缓存键 - * @param mixed $value 缓存键对应的值 - * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 - */ - public function add($key, $value, $ttl = 0){ - return wincache_ucache_add($key, $value, $ttl); - } - /** - * 设置缓存,如果缓存存在,则覆写,否则添加 - * @param string $key 缓存键 - * @param mixed $value 缓存键对应的值 - * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 - */ - public function set($key, $value, $ttl = 0) { - return wincache_ucache_set($key, $value, $ttl); - } - - /** - * 根据键移除缓存 - * @param string $key 缓存的键 - * @return mixed - */ - public function get($key) { - return wincache_ucache_get($key); - } - /** - * 删除缓存 - * @param string $key - */ - public function delete($key) { - return wincache_ucache_delete($key); - } - - /** - * 为 键加上锁定操作,以保证多进程多线程操作时数据的同步。 - * @param string $key - */ - public function lock($key) { - return wincache_lock($key); - } - - /** - * 来释放这个锁或等待程序请求结束时自动释放这个锁。 - * @param string $key - * @return - */ - public function unlock($key) { - return wincache_unlock($key); - } - - /** - * 判断一个某个键对应的缓存是否存在 - * @param string $key - */ - public function exist($key){ - return wincache_ucache_exists($key); - } - /** - * 清空所有缓存 - */ - public function flush() { - return wincache_ucache_clear(); - } -} diff --git a/wind/component/cache/operator/WindXCache.php b/wind/component/cache/operator/WindXCache.php deleted file mode 100644 index 5ccb1c97..00000000 --- a/wind/component/cache/operator/WindXCache.php +++ /dev/null @@ -1,66 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - * tags - */ -class WindXCache { - - public function __construct() { - if (!function_exists('xcache_get')) { - throw new WindException('The xcache extension must be loaded !'); - } - } - - /** - * 设置缓存,如果缓存存在,则覆写,否则添加 - * @param string $key 缓存键 - * @param mixed $value 缓存键对应的值 - * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 - */ - public function set($key, $value, $ttl = 0) { - return xcache_set($key, $value, $ttl); - } - - /** - * 根据键移除缓存 - * @param string $key 缓存的键 - * @return mixed - */ - public function get($key) { - return xcache_get($key); - } - /** - * 删除缓存 - * @param string $key - */ - public function delete($key) { - return xcache_unset($key); - } - - /** - * 判断一个某个键对应的缓存是否存在 - * @param string $key - */ - public function exist($key) { - return xcache_isset($key); - } - /** - * 清空所有缓存 - */ - public function flush() { - for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) { - xcache_clear_cache(XC_TYPE_VAR, $i); - } - return true; - } -} diff --git a/wind/component/cache/operator/WindZendCache.php b/wind/component/cache/operator/WindZendCache.php deleted file mode 100644 index c482a0de..00000000 --- a/wind/component/cache/operator/WindZendCache.php +++ /dev/null @@ -1,55 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindZendCache{ - - public function __construct() { - if (!function_exists('zend_shm_cache_fetch')) { - throw new WindException('The zend cache extension must be loaded !'); - } - } - - /** - * 设置缓存,如果缓存存在,则覆写,否则添加 - * @param string $key 缓存键 - * @param mixed $value 缓存键对应的值 - * @param int $ttl 缓存的生命周期,单位是秒,省略该参数或指定为 0 表示不限时,直到服务器重启清空为止。 - */ - public function set($key, $value, $ttl = 0) { - return zend_shm_cache_store($key, $value, $ttl); - } - - /** - * 根据键移除缓存 - * @param string $key 缓存的键 - * @return mixed - */ - public function get($key) { - return zend_shm_cache_fetch($key); - } - /** - * 删除缓存 - * @param string $key - */ - public function delete($key) { - return zend_shm_cache_delete($key); - } - - /** - * 清空所有缓存 - */ - public function flush() { - return zend_shm_cache_clear(); - } -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindApcCache.php b/wind/component/cache/strategy/WindApcCache.php new file mode 100644 index 00000000..0ce4671a --- /dev/null +++ b/wind/component/cache/strategy/WindApcCache.php @@ -0,0 +1,45 @@ + 2011-07-21 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.cache.AbstractWindCache'); + +class WindApcCache extends AbstractWindCache { + + public function __construct(){ + if (!extension_loaded('apc')) { + throw new WindException('The apc extension must be loaded !'); + } + } + + /* + * @see AbstractWindCache#addValue() + */ + protected function addValue($key, $value, $expires = 0) { + return apc_store($key, $value, $ttl); + } + + /* + * @see AbstractWindCache#getValue() + */ + protected function getValue($key) { + return apc_fetch($key); + } + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + return apc_delete($key); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + apc_clear_cache(); + return apc_clear_cache('user'); + } +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheApc.php b/wind/component/cache/strategy/WindCacheApc.php deleted file mode 100644 index 72ade731..00000000 --- a/wind/component/cache/strategy/WindCacheApc.php +++ /dev/null @@ -1,55 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.cache.AbstractWindCache'); -Wind::import('WIND:component.cache.operator.WindApc'); -/** - * php加速器缓存 - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindCacheApc extends AbstractWindCache { - - /** - * @var WindApc - */ - protected $apc = null; - - public function __construct(){ - $this->apc = new WindApc(); - } - /* - * @see AbstractWindCache#set() - */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire;echo $expire; - return $this->apc->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); - } - - /* - * @see AbstractWindCache#get() - */ - public function get($key) { - return $this->getDataFromMeta($key, unserialize($this->apc->get($this->buildSecurityKey($key)))); - } - /* - * @see AbstractWindCache#delete() - */ - public function delete($key) { - return $this->apc->delete($this->buildSecurityKey($key)); - } - /** - * @see AbstractWindCache#clear() - */ - public function clear() { - return $this->apc->flush(); - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheDb.php b/wind/component/cache/strategy/WindCacheDb.php deleted file mode 100644 index 28bfa87d..00000000 --- a/wind/component/cache/strategy/WindCacheDb.php +++ /dev/null @@ -1,251 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.cache.AbstractWindCache'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindCacheDb extends AbstractWindCache { - - /** - * 分布式管理 - * @var AbstractWindDbAdapter - */ - protected $dbHandler; - - /** - * 缓存表 - * @var string - */ - protected $table = 'pw_cache'; - - /** - * 缓存表的键字段 - * @var string - */ - protected $keyField = 'key'; - - /** - * 缓存表的值字段 - * @var string - */ - protected $valueField = 'value'; - - /** - * 缓存表过期时间字段 - * @var string - */ - protected $expireField = 'expire'; - - /** - * 数据过期策略 - * @var boolean - */ - protected $expirestrage = true; - - const CACHETABLE = 'cache-table'; - - const TABLENAME = 'table-name'; - - const KEY = 'field-key'; - - const VALUE = 'field-value'; - - const EXPIRE = 'field-expire'; - - const STRAGE = 'expirestrage'; - - public function __construct(AbstractWindDbAdapter $dbHandler = null) { - $dbHandler && $this->setDbHandler($dbHandler); - } - - /* - * @see AbstractWindCache#set() - */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire; - $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->expireField)->where($this->keyField . ' = :key ', array( - ':key' => $this->buildSecurityKey($key)))->select()->getRow(); - if ($data) { - return !$this->expirestrage && '0' === $data[$this->expireField] ? null : $this->update($key, $value, $expire, $denpendency); - } else { - return $this->store($key, $value, $expire, $denpendency); - } - return true; - } - - /* - * @see AbstractWindCache#get() - */ - public function get($key) { - if ($this->expirestrage) { - $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->valueField)->where($this->keyField . ' = :key ', array( - ':key' => $this->buildSecurityKey($key)))->select()->getRow(); - } else { - $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->valueField)->where($this->expireField . ' != 0 AND ' . $this->keyField . ' = :key ', array( - ':key' => $this->buildSecurityKey($key)))->select()->getRow(); - } - return $this->getDataFromMeta($key, unserialize($data[$this->valueField])); - } - - /* - * @see AbstractWindCache#batchFetch() - */ - public function batchGet(array $keys) { - foreach ($keys as $key => $value) { - $keys[$key] = $this->buildSecurityKey($value); - } - if (true === $this->expirestrage) { - $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->valueField, $this->keyField)->where($this->keyField . ' in ( :key ) ', array( - ':key' => $keys))->select()->getAllRow(); - } else { - $data = $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->valueField, $this->keyField)->where($this->expireField . ' != 0 AND ' . $this->keyField . ' in ( :key ) ', array( - ':key' => $keys))->select()->getAllRow(); - } - $result = $changed = array(); - foreach ($data as $_data) { - $_data = unserialize($_data[$this->valueField]); - if (isset($_data[self::DEPENDENCY]) && $_data[self::DEPENDENCY] instanceof IWindCacheDependency) { - if ($_data[self::DEPENDENCY]->hasChanged()) { - $changed[] = $_data[$this->keyField]; - } else { - $result[$_data[$this->keyField]] = $_data[self::DATA]; - } - } - } - $changed && $this->batchDelete($changed); - return $result; - } - - /* - * @see AbstractWindCache#delete() - */ - public function delete($key) { - if ($this->expirestrage) { - $this->dbHandler->getSqlBuilder()->from($this->table)->where($this->keyField . ' = :key ', array( - ':key' => $this->buildSecurityKey($key)))->delete(); - } else { - $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->expireField . ' = 0')->where($this->keyField . ' = :key ', array( - ':key' => $this->buildSecurityKey($key)))->update(); - } - } - - /* - * @see AbstractWindCache#batchDelete() - */ - public function batchDelete(array $keys) { - foreach ($keys as $key => $value) { - $keys[$key] = $this->buildSecurityKey($value); - } - if ($this->expirestrage) { - $this->dbHandler->getSqlBuilder()->from($this->table)->where($this->keyField . ' in (:key) ', array( - ':key' => $keys))->delete(); - } else { - $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->expireField . ' = 0')->where($this->keyField . ' in (:key) ', array( - ':key' => $keys))->update(); - } - } - - /* - * @see AbstractWindCache#clear() - */ - public function clear() { - if ($this->expirestrage) { - return $this->dbHandler->getSqlBuilder()->from($this->table)->delete(); - } else { - return $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->expireField . ' = 0')->update(); - } - return false; - } - - /** - * 删除过期数据 - */ - public function deleteExpiredCache() { - if ($this->expirestrage) { - $this->dbHandler->getSqlBuilder()->from($this->table)->where($this->expireField . ' !=0 AND ' . $this->expireField . ' < :expires', array( - ':expires' => time()))->delete(); - } else { - $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->expireField . ' = 0')->where($this->expireField . ' < :expires', array( - ':expires' => time()))->update(); - } - } - - public function setDbHandler(AbstractWindDbAdapter $dbHandler) { - $this->dbHandler = $dbHandler; - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->expirestrage = 'true' === $this->getTableConfig(self::STRAGE,WIND_CONFIG_VALUE); - $this->table = $this->getTableConfig(self::TABLENAME,WIND_CONFIG_VALUE); - $this->keyField = $this->getTableConfig(self::KEY,WIND_CONFIG_VALUE); - $this->valueField = $this->getTableConfig(self::VALUE,WIND_CONFIG_VALUE); - $this->expireField = $this->getTableConfig(self::EXPIRE,WIND_CONFIG_VALUE);; - } - - /** - * @return mixed - */ - protected function getTableConfig($name = '', $subname = '') { - $tableConfig = $this->getConfig(self::CACHETABLE); - if (empty($name)) { - return $tableConfig; - } - if (empty($subname)) { - return isset($tableConfig[$name]) ? $tableConfig[$name] : $tableConfig; - } - return isset($tableConfig[$name][$subname]) ? $tableConfig[$name][$subname] : $tableConfig[$name]; - } - - /** - * 存储数据 - * @param string $key - * @param string $value - * @param int $expires - * @param IWindCacheDependency $denpendency - * @return boolean - */ - protected function store($key, $value, $expires = 0, IWindCacheDependency $denpendency = null) { - $data = addslashes($this->storeData($value, $expires, $denpendency)); - if ($expires) { - $expires += time(); - } - return $this->dbHandler->getSqlBuilder()->from($this->table)->field($this->keyField, $this->valueField, $this->expireField)->data($this->buildSecurityKey($key), $data, $expires)->insert(); - } - - /** - * 更新数据 - * @param string $key - * @param int $value - * @param int $expires - * @param IWindCacheDependency $denpendency - * @return boolean - */ - protected function update($key, $value, $expires = 0, IWindCacheDependency $denpendency = null) { - $data = $this->storeData($value, $expires, $denpendency); - if ($expires) { - $expires += time(); - } - return $this->dbHandler->getSqlBuilder()->from($this->table)->set($this->valueField . ' = :value,' . $this->expireField . ' = :expires', array( - ':value' => $data, ':expires' => $expires))->where($this->keyField . '=:key', array( - ':key' => $this->buildSecurityKey($key)))->update(); - } - - public function __destruct() { - if (null !== $this->dbHandler) { - $this->deleteExpiredCache(); - } - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheEaccelerator.php b/wind/component/cache/strategy/WindCacheEaccelerator.php deleted file mode 100644 index 74347ea0..00000000 --- a/wind/component/cache/strategy/WindCacheEaccelerator.php +++ /dev/null @@ -1,58 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.cache.AbstractWindCache'); -Wind::import('WIND:component.cache.operator.WindEaccelerator'); -/** - * Eaccelerator是一款php加速器、优化器、编码器及动态内容缓存。 - * WindEaccelerator实现Eaccelerator动态内容缓存功能。 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindCacheEaccelerator extends AbstractWindCache { - - /** - * @var WindEaccelerator - */ - protected $eaccelerator = null; - - public function __construct() { - $this->eaccelerator = new WindEaccelerator(); /* @var WindEaccelerator*/ - } - - /* - * @see AbstractWindCache#set() - */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire; - return $this->eaccelerator->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); - } - - /* - * @see AbstractWindCache#get() - */ - public function get($key) { - return $this->getDataFromMeta($key, unserialize($this->eaccelerator->get($this->buildSecurityKey($key)))); - } - - /* - * @see AbstractWindCache#delete() - */ - public function delete($key) { - return $this->eaccelerator->delete($this->buildSecurityKey($key)); - } - - /* - * @see AbstractWindCache#clear() - * @return boolean - */ - public function clear() { - return $this->eaccelerator->flush(); - } -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheMem.php b/wind/component/cache/strategy/WindCacheMem.php deleted file mode 100644 index 2b9c7a83..00000000 --- a/wind/component/cache/strategy/WindCacheMem.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @author Su Qian - * @version $Id$ - * @package - * tags - */ -Wind::import('WIND:component.cache.AbstractWindCache'); -Wind::import('WIND:component.cache.operator.WindMemcache'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindCacheMem extends AbstractWindCache { - - /** - * memcache缓存操作句柄 - * @var WindMemcache - */ - protected $memcache = null; - - /** - * 是否对缓存采取压缩存储 - * @var int - */ - protected $compress = 0; - - //配置信息 - /** - * 是否对缓存进行压缩,如果缓存的值较大,可进行压缩 - * @var int - */ - const COMPRESS = 'compress'; - - /** - * 取得memcache配置项 - * @var string - */ - const SERVERCONFIG = 'servers'; - - public function __construct() { - $this->memcache = new WindMemcache(); - } - - /* - * @see AbstractWindCache::set() - */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire; - return $this->memcache->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $this->compress, (int) $expire); - } - - /* - * @see AbstractWindCache::get() - */ - public function get($key) { - return $this->getDataFromMeta($key, unserialize($this->memcache->get($this->buildSecurityKey($key), $this->compress))); - } - - /* - * @see AbstractWindCache::delete() - */ - public function delete($key) { - return $this->memcache->delete($this->buildSecurityKey($key)); - } - - /* - * @see AbstractWindCache::clear() - */ - public function clear() { - return $this->memcache->flush(); - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->memcache->setServers($this->getServersConfig()); - $this->compress = $this->getCompress(); - } - - /* - * @see AbstractWindCache#getCacheHandler() - * @return WindMemcache - */ - public function getCacheHandler() { - return $this->memcache; - } - - /** - * 取得缓存配置 - * @return array|mixed - */ - protected function getServersConfig($name = '', $subName = '') { - $servers = $this->getConfig(self::SERVERCONFIG); - if (empty($name)) { - return $servers; - } - if (empty($subName)) { - return isset($servers[$name]) ? $servers[$name] : $servers; - } - return isset($servers[$name][$subName]) ? $servers[$name][$subName] : $servers[$name]; - } - - protected function getCompress() { - $compress = $this->getConfig(self::COMPRESS, WIND_CONFIG_VALUE, '', 0); - return $compress ? MEMCACHE_COMPRESSED : 0; - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheWin.php b/wind/component/cache/strategy/WindCacheWin.php deleted file mode 100644 index 0e58bcaf..00000000 --- a/wind/component/cache/strategy/WindCacheWin.php +++ /dev/null @@ -1,54 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.cache.AbstractWindCache'); -Wind::import('WIND:component.cache.operator.WindWinCache'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ - -class WindCacheWin extends AbstractWindCache { - /** - * @var WindWinCache - */ - protected $wincache = null; - - public function __construct(){ - $this->wincache = new WindWinCache(); - } - /* - * @see AbstractWindCache#set() - */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire; - return $this->wincache->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); - } - /* - * @see AbstractWindCache#fetch() - */ - public function get($key) { - return $this->getDataFromMeta($key, unserialize($this->wincache->get($this->buildSecurityKey($key)))); - } - - /* - * @see AbstractWindCache#delete() - */ - public function delete($key) { - return $this->wincache->delete($this->buildSecurityKey($key)); - } - - /* - * @see AbstractWindCache#clear() - */ - public function clear() { - return $this->wincache->flush(); - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheXCache.php b/wind/component/cache/strategy/WindCacheXCache.php deleted file mode 100644 index 90b08a73..00000000 --- a/wind/component/cache/strategy/WindCacheXCache.php +++ /dev/null @@ -1,55 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.cache.AbstractWindCache'); -Wind::import('WIND:component.cache.operator.WindUXCache'); -/** - * xcache加速缓存 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindCacheXCache extends AbstractWindCache { - - /** - * @var WindXCache - */ - protected $xcache = null; - - public function __construct(){ - $this->xcache = new WindXCache(); - } - /* - * @see AbstractWindCache#set() - */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire; - return $this->xcache->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); - } - /* - * @see AbstractWindCache#fetch() - */ - public function get($key) { - return $this->getDataFromMeta($key, unserialize($this->xcache->get($this->buildSecurityKey($key)))); - } - - /* - * @see AbstractWindCache#delete() - */ - public function delete($key) { - return $this->xcache->delete($this->buildSecurityKey($key)); - } - - /* - * @see AbstractWindCache#clear() - */ - public function clear() { - return $this->xcache->flush(); - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheZend.php b/wind/component/cache/strategy/WindCacheZend.php index e4e4b2e9..e6081bcf 100644 --- a/wind/component/cache/strategy/WindCacheZend.php +++ b/wind/component/cache/strategy/WindCacheZend.php @@ -1,58 +1,46 @@ - * @author Su Qian - * @version $Id$ - * @package - * tags +/** + * @author xiaoxia.xu 2011-07-21 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license */ Wind::import('WIND:component.cache.AbstractWindCache'); -Wind::import('WIND:component.cache.operator.WindUZendCache'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindCacheZend extends AbstractWindCache { - /** - * @var WindZendCache - */ - protected $zendCache = null; +class WindZendCache extends AbstractWindCache { public function __construct() { - $this->zendCache = new WindZendCache(); + if (!function_exists('zend_shm_cache_fetch')) { + throw new WindException('The zend cache extension must be loaded !'); + } } /* (non-PHPdoc) - * @see AbstractWindCache::set() + * @see AbstractWindCache::setValue() */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire; - return $this->zendCache->set($this->buildSecurityKey($key), $this->storeData($value, $expire, $denpendency), $expire); + protected function setValue($key, $value, $expire = 0) { + return zend_shm_cache_store($key, $value, $expire); } /* (non-PHPdoc) - * @see AbstractWindCache::get() + * @see AbstractWindCache::getValue() */ - public function get($key) { - return $this->getDataFromMeta($key, unserialize($this->zendCache->get($this->buildSecurityKey($key)))); + protected function getValue($key) { + return zend_shm_cache_fetch($key); } /* (non-PHPdoc) - * @see AbstractWindCache::delete() + * @see AbstractWindCache::deleteValue() */ - public function delete($key) { - return $this->zendCache->delete($this->buildSecurityKey($key)); + protected function deleteValue($key) { + return zend_shm_cache_delete($key); } - /** + /* (non-PHPdoc) * @see AbstractWindCache::clear() - * @return boolean */ public function clear() { - return $this->zendCache->flush(); + return zend_shm_cache_clear(); } } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php new file mode 100644 index 00000000..ffffe370 --- /dev/null +++ b/wind/component/cache/strategy/WindDbCache.php @@ -0,0 +1,233 @@ + 2011-7-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +class WindDbCache extends AbstractWindCache { + + /** + * 分布式管理 + * @var AbstractWindDbAdapter + */ + protected $dbHandler; + + /** + * 缓存表 + * @var string + */ + protected $table = 'pw_cache'; + + /** + * 缓存表的键字段 + * @var string + */ + protected $keyField = 'key'; + + /** + * 缓存表的值字段 + * @var string + */ + protected $valueField = 'value'; + + /** + * 缓存表过期时间字段 + * @var string + */ + protected $expireField = 'expire'; + + /** + * 数据过期策略 + * @var boolean + */ + protected $expirestrage = true; + + const CACHETABLE = 'cache-table'; + + const TABLENAME = 'table-name'; + + const KEY = 'field-key'; + + const VALUE = 'field-value'; + + const EXPIRE = 'field-expire'; + + const STRAGE = 'expirestrage'; + + public function __construct(WindConnection $connection = null, $config = array()) { + $connection && $this->setConnection($connection); + $config && $this->setConfig($config); + } + + /* + * @see AbstractWindCache#addValue() + */ + protected function addValue($key, $value, $expire = 0) { + (mt_rand(100, 1000000) % 100 == 0) && $this->deleteExpiredCache(); + $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =?' ; + $data = $this->getConnection()->createStatement($sql)->getOne(array($key)); + if ($data) { + return $this->update($key, $value, $expire); + } + return $this->store($key, $value, $expire); + } + + /* + * @see AbstractWindCache#getValue() + */ + protected function getValue($key) { + $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; + $data = $this->getConnection()->createStatement($sql)->getOne(array($key), time())); + return $data[$this->valueField]; + } + + /* + * @see AbstractWindCache#batchFetch() + */ + public function batchGet(array $keys) { + foreach ($keys as $key => $value) { + $keys[$key] = $this->buildSecurityKey($value); + } + list($sql, $result) = array('', array()); + $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys) . ' AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; + $data = $this->getConnection()->createStatement($sql)->queryAll(array(time())); + foreach ($data as $tmp) { + $result[] = $this->formatData($tmp[$this->valueField]); + } + return $result; + } + + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` = ? '; + return $this->getConnection()->createStatement($sql)->update(array($key)); + } + + /* + * @see AbstractWindCache#batchDelete() + */ + public function batchDelete(array $keys) { + foreach ($keys as $key => $value) { + $keys[$key] = $this->buildSecurityKey($value); + } + $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys); + return $this->getConnection()->execute($sql); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + return $this->getConnection()->execute('DELETE FROM ' . $this->getTableName()); + } + + /** + * 删除过期数据 + */ + public function deleteExpiredCache() { + $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->expireField . '`>0 AND `' . $this->expireField . '`<'.time(); + return $this->getConnection()->execute($sql); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->dbConfig = $this->getConfig(self::DBCONFIG); + + $this->table = $this->getTableConfig(self::TABLENAME); + $this->keyField = $this->getTableConfig(self::KEY); + $this->valueField = $this->getTableConfig(self::VALUE); + $this->expireField = $this->getTableConfig(self::EXPIRE); + } + + /** + * @return mixed + */ + private function getTableConfig($name = '', $subname = '') { + $tableConfig = $this->getConfig(self::CACHETABLE); + if (empty($name)) { + return $tableConfig; + } + if (empty($subname)) { + return isset($tableConfig[$name]) ? $tableConfig[$name] : $tableConfig; + } + return isset($tableConfig[$name][$subname]) ? $tableConfig[$name][$subname] : $tableConfig[$name]; + } + + /** + * 存储数据 + * @param string $key + * @param string $value + * @param int $expires + * @param IWindCacheDependency $denpendency + * @return boolean + */ + protected function store($key, $value, $expires = 0) { + ($expires > 0) ? $expires += time() : $expire=0; + $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires); + $sql = 'INSERT INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db); + return $this->getConnection()->createStatement($sql)->update(); + } + + /** + * 更新数据 + * @param string $key + * @param int $value + * @param int $expires + * @param IWindCacheDependency $denpendency + * @return boolean + */ + protected function update($key, $value, $expires = 0) { + ($expires > 0) ? $expires += time() : $expire=0; + $db = array($this->valueField => $value, $this->expireField => $expires); + $sql = "UPDATE " . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db) . ' WHERE `' . $this->keyField . '`=?'; + return $this->getConnection()->createStatement($sql)->update(array($key), true); + } + + public function __destruct() { + if (null !== $this->dbHandler) { + $this->deleteExpiredCache(); + } + } + + /** + * 返回表名 + * @return string + */ + private function getTableName() { + return $this->table; + } + + /** + * 获得链接对象 + * @return WindConnection + */ + private function getConnection() { + if (null == $this->connection) { + $this->connection = new WindConnection(); + $this->connection->setConfig($this->dbConfig); + $this->connection->init(); + } + return $this->connection; + } + + /** + * @return mixed + */ + private function getTableConfig($name = '', $subname = '') { + $tableConfig = $this->getConfig(self::CACHETABLE); + if (empty($name)) { + return $tableConfig; + } + if (empty($subname)) { + return isset($tableConfig[$name]) ? $tableConfig[$name] : $tableConfig; + } + return isset($tableConfig[$name][$subname]) ? $tableConfig[$name][$subname] : $tableConfig[$name]; + } +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindEacceleratorCache.php b/wind/component/cache/strategy/WindEacceleratorCache.php new file mode 100644 index 00000000..c2cedbce --- /dev/null +++ b/wind/component/cache/strategy/WindEacceleratorCache.php @@ -0,0 +1,54 @@ + 2011-7-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + * @package + */ +Wind::import('WIND:component.cache.AbstractWindCache'); +/** + * Eaccelerator是一款php加速器、优化器、编码器及动态内容缓存。 + * WindEaccelerator实现Eaccelerator动态内容缓存功能。 + */ +class WindEacceleratorCache extends AbstractWindCache { + + public function __construct() { + if (!function_exists('eaccelerator_get')) { + throw new WindException('The eaccelerator extension must be loaded !'); + } + } + + /* + * @see AbstractWindCache#set() + */ + protected function setValue($key, $value, $expire = 0) { + return eaccelerator_put($key, $value, $expire); + } + + /* + * @see AbstractWindCache#get() + */ + protected function getValue($key) { + return eaccelerator_get($key); + } + + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + return eaccelerator_rm($key); + } + + /* + * @see AbstractWindCache#clear() + * @return boolean + */ + public function clear() { + eaccelerator_gc(); + $cacheKeys = eaccelerator_list_keys(); + foreach ($cacheKeys as $key) { + $this->delete(substr($key['name'], 1)); + } + } +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindCacheFile.php b/wind/component/cache/strategy/WindFileCache.php similarity index 57% rename from wind/component/cache/strategy/WindCacheFile.php rename to wind/component/cache/strategy/WindFileCache.php index aec893d1..78903e12 100644 --- a/wind/component/cache/strategy/WindCacheFile.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -1,16 +1,15 @@ 2011-7-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + * @package + */ Wind::import('WIND:component.cache.AbstractWindCache'); Wind::import('WIND:component.utility.WindFile'); -/** - * 文件缓存类 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindCacheFile extends AbstractWindCache { +class WindFileCache extends AbstractWindCache { /** * 缓存目录 @@ -37,28 +36,24 @@ class WindCacheFile extends AbstractWindCache { const LEVEL = 'cache-level'; /* (non-PHPdoc) - * @see AbstractWindCache::set() + * @see AbstractWindCache::setValue() */ - public function set($key, $value, $expire = null, IWindCacheDependency $denpendency = null) { - $expire = null === $expire ? $this->getExpire() : $expire; - return $this->writeData($this->getRealCacheKey($key), $this->storeData($value, $expire, $denpendency), $expire); + protected function setValue($key, $value, $expire = 0) { + return $this->writeData($key, $value, $expire); } /* (non-PHPdoc) * @see AbstractWindCache::get() */ - public function get($key) { - return $this->getDataFromMeta($key, $this->readData($this->getRealCacheKey($key))); + protected function getValue($key) { + return $this->readData($key); } /* (non-PHPdoc) - * @see AbstractWindCache::delete() + * @see AbstractWindCache::deleteValue() */ - public function delete($key) { - $cacheFile = $this->getRealCacheKey($key); - if (is_file($cacheFile)) { - return WindFile::delFile($cacheFile); - } + protected function deleteValue($key) { + if (is_file($cacheFile)) return WindFile::delFile($cacheFile); return false; } @@ -74,15 +69,14 @@ public function clear($isExpired = false) { * @param string $key * @return string */ - protected function getRealCacheKey($key, $getDir = false) { - $filename = $this->buildSecurityKey($key) . '.' . ltrim($this->getCacheFileSuffix(), '.'); + protected function buildSecurityKey($key, $getDir = false) { + $filename = parent::buildSecurityKey($key) . '.' . ltrim($this->getCacheFileSuffix(), '.'); $_tmp = $this->getCacheDir(); if (0 < $this->getCacheDirectoryLevel()) { for ($i = $this->getCacheDirectoryLevel(); $i > 0; --$i) { - if (false === isset($key[$i])) continue; - $_tmp .= $key[$i] . DIRECTORY_SEPARATOR; + if (($prefix = substr($key, $i+$i, 2)) ===false) continue; + $_tmp .= DIRECTORY_SEPARATOR . $prefix; } - if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); } if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); return $getDir ? $_tmp : $_tmp . $filename; @@ -95,7 +89,7 @@ protected function getRealCacheKey($key, $getDir = false) { * @param int $mtime 缓存文件的修改时间,即缓存的过期时间 * @return boolean */ - protected function writeData($file, $data, $mtime = 0) { + private function writeData($file, $data, $mtime = 0) { if (WindFile::write($file, $data) == strlen($data)) { $mtime += $mtime ? time() : 0; chmod($file, 0777); @@ -109,60 +103,32 @@ protected function writeData($file, $data, $mtime = 0) { * @param string $file 缓存文件名 * @return null|string */ - protected function readData($file) { + private function readData($file) { if (false === is_file($file)) return null; $mtime = filemtime($file); if (0 === $mtime || ($mtime && $mtime > time())) - return unserialize(WindFile::read($file)); + return WindFile::read($file); elseif (0 < $mtime) WindFile::delFile($file); return null; } - /* (non-PHPdoc) - * @see AbstractWindCache::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->setCacheDir($this->getConfig(self::CACHEDIR, WIND_CONFIG_VALUE)); - } - /** * 设置缓存目录 * @param string $dir */ - private function setCacheDir($dir) { - $this->cacheDir = Wind::getRealDir($dir) . DIRECTORY_SEPARATOR; + public function setCacheDir($dir) { + $this->cacheDir = Wind::getRealPath($dir, true) . DIRECTORY_SEPARATOR; } /** * @return the $cacheDir */ - public function getCacheDir() { + private function getCacheDir() { if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0777, true); return $this->cacheDir; } - /** - * @return the $cacheFileSuffix - */ - protected function getCacheFileSuffix() { - if ('' === $this->cacheFileSuffix) { - $this->cacheFileSuffix = $this->getConfig(self::SUFFIX, WIND_CONFIG_VALUE, '', 'bin'); - } - return $this->cacheFileSuffix; - } - - /** - * 返回cache目录级别,默认为0,不分级,最大分级为5 - * @return the $cacheDirectoryLevel - */ - protected function getCacheDirectoryLevel() { - if ('' === $this->cacheDirectoryLevel) { - $this->cacheDirectoryLevel = $this->getConfig(self::LEVEL, WIND_CONFIG_VALUE, '', 0); - } - return $this->cacheDirectoryLevel > 5 ? 5 : $this->cacheDirectoryLevel; - } /** * @param string $cacheFileSuffix @@ -170,12 +136,28 @@ protected function getCacheDirectoryLevel() { public function setCacheFileSuffix($cacheFileSuffix) { $this->cacheFileSuffix = $cacheFileSuffix; } + + /** + * @return the $cacheFileSuffix + */ + private function getCacheFileSuffix() { + return $this->cacheFileSuffix; + } /** * @param int $cacheDirectoryLevel */ public function setCacheDirectoryLevel($cacheDirectoryLevel) { - $this->cacheDirectoryLevel = $cacheDirectoryLevel; + $cacheDirectoryLevel = intval($cacheDirectoryLevel); + $this->cacheDirectoryLevel = $cacheDirectoryLevel > 5 ? 5 : ($cacheDirectoryLevel < 1 ? 1 : $cacheDirectoryLevel); + } + + /** + * 返回cache目录级别,默认为0,不分级,最大分级为5 + * @return the $cacheDirectoryLevel + */ + private function getCacheDirectoryLevel() { + return $this->cacheDirectoryLevel; } /** @@ -184,5 +166,15 @@ public function setCacheDirectoryLevel($cacheDirectoryLevel) { public function __destruct() { $this->clear(true); } + + /* (non-PHPdoc) + * @see AbstractWindCache::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setCacheDir($this->getConfig(self::CACHEDIR)); + $this->setCacheFileSuffix($this->getConfig(self::SUFFIX)); + $this->setCacheDirectoryLevel($this->getConfig(self::LEVEL)); + } } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php new file mode 100644 index 00000000..36955a16 --- /dev/null +++ b/wind/component/cache/strategy/WindMemCache.php @@ -0,0 +1,157 @@ + 2011-7-18 + * @link http://www.cnblogs.com/xiaoyaoxia/ + * @copyright Copyright © 2011-2012 xiaoxiao + * @license + * @package + */ +Wind::import('WIND:component.cache.AbstractWindCache'); + +class WindMemCache extends AbstractWindCache { + + /** + * memcache缓存操作句柄 + * @var WindMemcache + */ + protected $memcache = null; + + /** + * 是否对缓存采取压缩存储 + * @var int + */ + protected $compress = 0; + + //配置信息 + /** + * 是否对缓存进行压缩,如果缓存的值较大,可进行压缩 + * @var int + */ + const COMPRESS = 'compress'; + + /** + * 取得memcache配置项 + * @var string + */ + const SERVERCONFIG = 'servers'; + + const HOST = 'host'; + + const PORT = 'port'; + + const PCONNECT = 'pconn'; + + const WEIGHT = 'weight'; + + const TIMEOUT = 'timeout'; + + const RETRY = 'retry'; + + const STATUS = 'status'; + + const FCALLBACK = 'fcallback'; + + public function __construct() { + if (!extension_loaded('Memcache')) { + throw new WindException('WindMemCache requires PHP `Memcache` extension to be loaded !'); + } + $this->memcache = new Memcache(); + } + + /* + * @see AbstractWindCache::setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return $this->memcache->set($key, $value, $this->compress, (int) $expire); + } + + /* + * @see AbstractWindCache::getValue() + */ + protected function getValue($key) { + return $this->memcache->get($key); + } + + /* + * @see AbstractWindCache::deleteValue() + */ + protected function deleteValue($key) { + return $this->memcache->delete($key); + } + + /* + * @see AbstractWindCache::clear() + */ + public function clear() { + return $this->memcache->flush(); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setServers($this->getServersConfig()); + $this->compress = $this->$this->getConfig(self::COMPRESS, WIND_CONFIG_VALUE, 0); + } + + /** + * 取得缓存配置 + * @return array|mixed + */ + protected function getServersConfig($name = '', $subName = '') { + $servers = $this->getConfig(self::SERVERCONFIG); + if (empty($name)) { + return $servers; + } + if (empty($subName)) { + return isset($servers[$name]) ? $servers[$name] : $servers; + } + return isset($servers[$name][$subName]) ? $servers[$name][$subName] : $servers[$name]; + } + + /** + * 设置配置信息 + * + * @param array $servers + * @example + * $server = array( + * array( + * 'host'=>'localhost', + * 'port'=>11211 + * 'pconn'=>true + * ), + * array( + * 'host'=>'localhost', + * 'port'=>11212 + * 'pconn'=>false + * ) + * @throws WindException + */ + private function setServers($servers) { + foreach ($servers as $server) { + if (!is_array($server)) { + throw new WindException('The memcache config is incorrect'); + } + $this->setServer($server); + } + } + + /** + * 设置配置信息 + * + * @throws WindException + */ + private function setServer($server) { + if (!isset($server[self::HOST])) { + throw new WindException('The memcache server ip address is not exist'); + } + if (!isset($server[self::PORT])) { + throw new WindException('The memcache server port is not exist'); + } + $defaultServer = array(self::HOST => '', self::PORT => '', self::PCONNECT => true, self::WEIGHT => 1, + self::TIMEOUT => 15, self::RETRY => 15, self::STATUS => true, self::FCALLBACK => null); + list($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback) = array_values(array_merge($defaultServer, $server)); + $this->memcache->addServer($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback); + } +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindWinCache.php b/wind/component/cache/strategy/WindWinCache.php new file mode 100644 index 00000000..0177c630 --- /dev/null +++ b/wind/component/cache/strategy/WindWinCache.php @@ -0,0 +1,44 @@ + 2011-07-21 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.cache.AbstractWindCache'); + +class WindWinCache extends AbstractWindCache { + + public function __construct(){ + if (!function_exists('wincache_ucache_get')) { + throw new WindException('The wincache extension must be loaded !'); + } + } + /* + * @see AbstractWindCache#setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return wincache_ucache_set($key, $value, $expire); + } + /* + * @see AbstractWindCache#getValue() + */ + protected function getValue($key) { + return wincache_ucache_get($key); + } + + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + return wincache_ucache_delete($key); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + return wincache_ucache_clear(); + } + +} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindXCache.php b/wind/component/cache/strategy/WindXCache.php new file mode 100644 index 00000000..1e3f16e0 --- /dev/null +++ b/wind/component/cache/strategy/WindXCache.php @@ -0,0 +1,49 @@ + 2011-7-19 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + * @package + */ +Wind::import('WIND:component.cache.AbstractWindCache'); + +class WindXCache extends AbstractWindCache { + + public function __construct(){ + if (!function_exists('xcache_get')) { + throw new WindException('The xcache extension must be loaded !'); + } + } + /* + * @see AbstractWindCache#setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return xcache_set($key, $value, $expire); + } + /* + * @see AbstractWindCache#getValue() + */ + protected function getValue($key) { + return xcache_get($key); + } + + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + return xcache_unset($key); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + $max = xcache_count(XC_TYPE_VAR); + for ($i = 0; $i < $max; $i++) { + xcache_clear_cache(XC_TYPE_VAR, $i); + } + return true; + } + +} \ No newline at end of file From 76bc676c35a36f60128276a0bf7ccad9374f56d1 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 21 Jul 2011 11:07:09 +0000 Subject: [PATCH 0138/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2198 18ba2127-5a84-46d4-baec-3457e417f034 --- .../cache/strategy/{WindCacheZend.php => WindZendCache.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename wind/component/cache/strategy/{WindCacheZend.php => WindZendCache.php} (100%) diff --git a/wind/component/cache/strategy/WindCacheZend.php b/wind/component/cache/strategy/WindZendCache.php similarity index 100% rename from wind/component/cache/strategy/WindCacheZend.php rename to wind/component/cache/strategy/WindZendCache.php From f1f38e59e930f520aa34439b891c8431b25148da Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 22 Jul 2011 02:37:57 +0000 Subject: [PATCH 0139/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2199 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index eb99991c..f47014e1 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -81,7 +81,6 @@ public function set($key, $value, $expires = 0, IWindCacheDependency $denpendenc return $this->addValue($this->buildSecurityKey($key), serialize($data), $expires); } - protected function /** * 执行添加操作 * From 61d64487429408e07d9597e5acf589cc87b705c9 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 22 Jul 2011 03:10:05 +0000 Subject: [PATCH 0140/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2200 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 72 ++++++----- .../component/cache/strategy/WindApcCache.php | 2 +- wind/component/cache/strategy/WindDbCache.php | 118 ++++++++---------- .../cache/strategy/WindFileCache.php | 16 ++- .../component/cache/strategy/WindMemCache.php | 20 +-- .../component/cache/strategy/WindWinCache.php | 62 ++++----- wind/component/cache/strategy/WindXCache.php | 70 ++++++----- .../cache/strategy/WindZendCache.php | 2 +- 8 files changed, 175 insertions(+), 187 deletions(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index f47014e1..798d3034 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -42,6 +42,9 @@ abstract class AbstractWindCache extends WindModule { * @var string */ const DEPENDENCY = 'dependency'; + /* + * 配置项 + */ /** * 配置文件中标志过期时间名称定义(也包含缓存元数据中过期时间 的定义) * @var string @@ -67,12 +70,7 @@ abstract class AbstractWindCache extends WindModule { * @return boolean */ public function set($key, $value, $expires = 0, IWindCacheDependency $denpendency = null) { - $data = array( - self::DATA => $value, - self::EXPIRE => $expires, - self::STORETIME => time(), - self::DEPENDENCY => null, - self::DEPENDENCYCLASS => ''); + $data = array(self::DATA => $value, self::EXPIRE => $expires, self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); if (null != $denpendency) { $denpendency->injectDependent(); $data[self::DEPENDENCY] = serialize($denpendency); @@ -80,7 +78,7 @@ public function set($key, $value, $expires = 0, IWindCacheDependency $denpendenc } return $this->addValue($this->buildSecurityKey($key), serialize($data), $expires); } - + /** * 执行添加操作 * @@ -98,21 +96,8 @@ protected abstract function addValue($key, $value, $expires = 0); */ public function get($key) { return $this->formatData($this->getValue($this->buildSecurityKey($key))); - } - - /** - * 格式化输出 - * @param string $value - * @return array - */ - protected function formatData($value) { - $data = unserialize($value); - if (!is_array($data)) return null; - if ($this->hasChanged($key, $data)) return null; - return isset($data[self::DATA]) ? $data[self::DATA] : null; - } - + /** * 执行获取操作 * @@ -133,7 +118,7 @@ public function batchGet(array $keys) { } return $data; } - + /** * 删除缓存数据 * @@ -143,7 +128,7 @@ public function batchGet(array $keys) { public function delete($key) { return $this->deleteValue($this->buildSecurityKey($key)); } - + /** * 需要实现的删除操作 * @param string $key @@ -156,7 +141,8 @@ protected abstract function deleteValue($key); * @return boolean */ public function batchDelete(array $keys) { - foreach ($keys as $key) $this->delete($key); + foreach ($keys as $key) + $this->delete($key); return true; } @@ -165,6 +151,18 @@ public function batchDelete(array $keys) { */ public abstract function clear(); + /** + * 格式化输出 + * @param string $value + * @return array + */ + protected function formatData($value) { + $data = unserialize($value); + if (!is_array($data)) return null; + if ($this->hasChanged($key, $data)) return null; + return isset($data[self::DATA]) ? $data[self::DATA] : null; + } + /** * 如果缓存中有数据,则检查缓存依赖是否已经变更,如果变更则删除缓存 * @param string $key 键 @@ -197,21 +195,21 @@ protected function buildSecurityKey($key) { protected function getKeyPrefix() { return $this->keyPrefix; } - + /** * @param sting $keyPrefix */ public function setKeyPrefix($keyPrefix) { $this->keyPrefix = $keyPrefix; } - + /** * @return the $securityCode */ protected function getSecurityCode() { return $this->securityCode; } - + /** * @param string $securityCode */ @@ -226,14 +224,14 @@ public function setSecurityCode($securityCode) { public function getExpire() { return $this->expire; } - + /** * @param int $expire */ public function setExpire($expire) { $this->expire = intval($expire); } - + /** * 设置配置信息 * @param array $config @@ -244,4 +242,20 @@ public function setConfig($config) { $this->setKeyPrefix($this->getConfig(self::KEYPREFIX, '', '')); $this->setExpire($this->getCofnig(self::EXPIRE, '', 0)); } + + + /** + * 获得缓存表相关配置 + * + * @param array $config + * @param string $name + * @param string $subname + * @param string $default + * @return string + */ + protected function getSubConfig($config, $name, $subname = '', $default = '') { + $result = (isset($config[$name])) ? $config[$name] : $default; + if (!$subname || !isset($result[$subname])) return $result; + return isset($result[$subname]) ? $result[$subname] : $default; + } } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindApcCache.php b/wind/component/cache/strategy/WindApcCache.php index 0ce4671a..2961e3be 100644 --- a/wind/component/cache/strategy/WindApcCache.php +++ b/wind/component/cache/strategy/WindApcCache.php @@ -19,7 +19,7 @@ public function __construct(){ * @see AbstractWindCache#addValue() */ protected function addValue($key, $value, $expires = 0) { - return apc_store($key, $value, $ttl); + return apc_store($key, $value, $expires); } /* diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index ffffe370..a2cd0c70 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -12,38 +12,44 @@ class WindDbCache extends AbstractWindCache { * 分布式管理 * @var AbstractWindDbAdapter */ - protected $dbHandler; + private $dbHandler; + + /** + * 链接配置信息 + * @var array + */ + private $dbconfig; /** * 缓存表 * @var string */ - protected $table = 'pw_cache'; + private $table = 'pw_cache'; /** * 缓存表的键字段 * @var string */ - protected $keyField = 'key'; + private $keyField = 'key'; /** * 缓存表的值字段 * @var string */ - protected $valueField = 'value'; + private $valueField = 'value'; /** * 缓存表过期时间字段 * @var string */ - protected $expireField = 'expire'; + private $expireField = 'expire'; - /** - * 数据过期策略 - * @var boolean + /* + * 配置项常量定义 */ - protected $expirestrage = true; - + const DBCACHE = 'dbCache'; + const DBCONFIG = 'dbconfig'; + const CACHETABLE = 'cache-table'; const TABLENAME = 'table-name'; @@ -54,7 +60,6 @@ class WindDbCache extends AbstractWindCache { const EXPIRE = 'field-expire'; - const STRAGE = 'expirestrage'; public function __construct(WindConnection $connection = null, $config = array()) { $connection && $this->setConnection($connection); @@ -138,28 +143,44 @@ public function deleteExpiredCache() { */ public function setConfig($config) { parent::setConfig($config); - $this->dbConfig = $this->getConfig(self::DBCONFIG); - - $this->table = $this->getTableConfig(self::TABLENAME); - $this->keyField = $this->getTableConfig(self::KEY); - $this->valueField = $this->getTableConfig(self::VALUE); - $this->expireField = $this->getTableConfig(self::EXPIRE); + $this->dbConfig = $this->getConfig(self::DBCACHE, self::DBCONFIG); + $config = $this->getConfig(self::CACHETABLE); + $this->table = $this->getSubConfig($config, self::TABLENAME, '', 'pw_cache'); + $this->keyField = $this->getSubConfig($config, self::KEY, '', 'key'); + $this->valueField = $this->getSubConfig($config, self::VALUE, '', 'value'); + $this->expireField = $this->getSubConfig($config, self::EXPIRE, '', 'expire'); } /** - * @return mixed + * 析构函数 */ - private function getTableConfig($name = '', $subname = '') { - $tableConfig = $this->getConfig(self::CACHETABLE); - if (empty($name)) { - return $tableConfig; + public function __destruct() { + if (null !== $this->getConnection()) { + $this->deleteExpiredCache(); } - if (empty($subname)) { - return isset($tableConfig[$name]) ? $tableConfig[$name] : $tableConfig; + } + + /** + * 设置链接对象 + * @param WindConnection $connection + */ + public function setConnection($connection) { + if ($connection instanceof WindConnection) $this->connection = $connection; + } + + /** + * 获得链接对象 + * @return WindConnection + */ + private function getConnection() { + if (null == $this->connection) { + $this->connection = new WindConnection(); + $this->connection->setConfig($this->dbConfig); + $this->connection->init(); } - return isset($tableConfig[$name][$subname]) ? $tableConfig[$name][$subname] : $tableConfig[$name]; + return $this->connection; } - + /** * 存储数据 * @param string $key @@ -168,7 +189,7 @@ private function getTableConfig($name = '', $subname = '') { * @param IWindCacheDependency $denpendency * @return boolean */ - protected function store($key, $value, $expires = 0) { + private function store($key, $value, $expires = 0) { ($expires > 0) ? $expires += time() : $expire=0; $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires); $sql = 'INSERT INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db); @@ -183,51 +204,10 @@ protected function store($key, $value, $expires = 0) { * @param IWindCacheDependency $denpendency * @return boolean */ - protected function update($key, $value, $expires = 0) { + private function update($key, $value, $expires = 0) { ($expires > 0) ? $expires += time() : $expire=0; $db = array($this->valueField => $value, $this->expireField => $expires); $sql = "UPDATE " . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db) . ' WHERE `' . $this->keyField . '`=?'; return $this->getConnection()->createStatement($sql)->update(array($key), true); } - - public function __destruct() { - if (null !== $this->dbHandler) { - $this->deleteExpiredCache(); - } - } - - /** - * 返回表名 - * @return string - */ - private function getTableName() { - return $this->table; - } - - /** - * 获得链接对象 - * @return WindConnection - */ - private function getConnection() { - if (null == $this->connection) { - $this->connection = new WindConnection(); - $this->connection->setConfig($this->dbConfig); - $this->connection->init(); - } - return $this->connection; - } - - /** - * @return mixed - */ - private function getTableConfig($name = '', $subname = '') { - $tableConfig = $this->getConfig(self::CACHETABLE); - if (empty($name)) { - return $tableConfig; - } - if (empty($subname)) { - return isset($tableConfig[$name]) ? $tableConfig[$name] : $tableConfig; - } - return isset($tableConfig[$name][$subname]) ? $tableConfig[$name][$subname] : $tableConfig[$name]; - } } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 78903e12..9e69490f 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -21,7 +21,7 @@ class WindFileCache extends AbstractWindCache { * 缓存后缀 * @var string */ - protected $cacheFileSuffix = ''; + protected $cacheFileSuffix = 'txt'; /** * 缓存多级目录。最好不要超3层目录 @@ -29,6 +29,10 @@ class WindFileCache extends AbstractWindCache { */ protected $cacheDirectoryLevel = ''; + /* + * 配置项 + */ + const FILE = 'fileCache'; const CACHEDIR = 'cache-dir'; const SUFFIX = 'cache-suffix'; @@ -52,7 +56,7 @@ protected function getValue($key) { /* (non-PHPdoc) * @see AbstractWindCache::deleteValue() */ - protected function deleteValue($key) { + protected function deleteValue($cacheFile) { if (is_file($cacheFile)) return WindFile::delFile($cacheFile); return false; } @@ -74,7 +78,7 @@ protected function buildSecurityKey($key, $getDir = false) { $_tmp = $this->getCacheDir(); if (0 < $this->getCacheDirectoryLevel()) { for ($i = $this->getCacheDirectoryLevel(); $i > 0; --$i) { - if (($prefix = substr($key, $i+$i, 2)) ===false) continue; + if (false === ($prefix = substr($key, $i+$i, 2))) continue; $_tmp .= DIRECTORY_SEPARATOR . $prefix; } } @@ -172,9 +176,9 @@ public function __destruct() { */ public function setConfig($config) { parent::setConfig($config); - $this->setCacheDir($this->getConfig(self::CACHEDIR)); - $this->setCacheFileSuffix($this->getConfig(self::SUFFIX)); - $this->setCacheDirectoryLevel($this->getConfig(self::LEVEL)); + $this->setCacheDir($this->getConfig(self::FILE, self::CACHEDIR)); + $this->setCacheFileSuffix($this->getConfig(self::FILE, self::SUFFIX, 'txt')); + $this->setCacheDirectoryLevel($this->getConfig(self::FILE, self::LEVEL)); } } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php index 36955a16..6ad4ee49 100644 --- a/wind/component/cache/strategy/WindMemCache.php +++ b/wind/component/cache/strategy/WindMemCache.php @@ -23,6 +23,7 @@ class WindMemCache extends AbstractWindCache { protected $compress = 0; //配置信息 + const MEMCACHE = 'memcache'; /** * 是否对缓存进行压缩,如果缓存的值较大,可进行压缩 * @var int @@ -91,23 +92,8 @@ public function clear() { */ public function setConfig($config) { parent::setConfig($config); - $this->setServers($this->getServersConfig()); - $this->compress = $this->$this->getConfig(self::COMPRESS, WIND_CONFIG_VALUE, 0); - } - - /** - * 取得缓存配置 - * @return array|mixed - */ - protected function getServersConfig($name = '', $subName = '') { - $servers = $this->getConfig(self::SERVERCONFIG); - if (empty($name)) { - return $servers; - } - if (empty($subName)) { - return isset($servers[$name]) ? $servers[$name] : $servers; - } - return isset($servers[$name][$subName]) ? $servers[$name][$subName] : $servers[$name]; + $this->setServers($this->getConfig(self::MEMCACHE, self::SERVERCONFIG)); + $this->compress = $this->getSubConfig($this->getConfig(self::MEMCACHE), self::COMPRESS, '', 0); } /** diff --git a/wind/component/cache/strategy/WindWinCache.php b/wind/component/cache/strategy/WindWinCache.php index 0177c630..71a03cce 100644 --- a/wind/component/cache/strategy/WindWinCache.php +++ b/wind/component/cache/strategy/WindWinCache.php @@ -1,44 +1,46 @@ - 2011-07-21 * @link http://www.phpwind.com * @copyright Copyright © 2003-2110 phpwind.com * @license - */ -Wind::import('WIND:component.cache.AbstractWindCache'); - -class WindWinCache extends AbstractWindCache { - - public function __construct(){ - if (!function_exists('wincache_ucache_get')) { - throw new WindException('The wincache extension must be loaded !'); - } - } + */ +Wind::import('WIND:component.cache.AbstractWindCache'); + +class WindWinCache extends AbstractWindCache { + + public function __construct() { + if (!function_exists('wincache_ucache_get')) { + throw new WindException('The wincache extension must be loaded !'); + } + } + /* * @see AbstractWindCache#setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return wincache_ucache_set($key, $value, $expire); - } + */ + protected function setValue($key, $value, $expire = 0) { + return wincache_ucache_set($key, $value, $expire); + } + /* * @see AbstractWindCache#getValue() - */ - protected function getValue($key) { - return wincache_ucache_get($key); - } - + */ + protected function getValue($key) { + return wincache_ucache_get($key); + } + /* * @see AbstractWindCache#deleteValue() - */ - protected function deleteValue($key) { - return wincache_ucache_delete($key); - } - + */ + protected function deleteValue($key) { + return wincache_ucache_delete($key); + } + /* * @see AbstractWindCache#clear() - */ - public function clear() { - return wincache_ucache_clear(); - } - + */ + public function clear() { + return wincache_ucache_clear(); + } + } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindXCache.php b/wind/component/cache/strategy/WindXCache.php index 1e3f16e0..989b89ae 100644 --- a/wind/component/cache/strategy/WindXCache.php +++ b/wind/component/cache/strategy/WindXCache.php @@ -1,49 +1,51 @@ - 2011-7-19 * @link http://www.phpwind.com * @copyright Copyright © 2003-2110 phpwind.com * @license * @package - */ -Wind::import('WIND:component.cache.AbstractWindCache'); - -class WindXCache extends AbstractWindCache { - - public function __construct(){ - if (!function_exists('xcache_get')) { - throw new WindException('The xcache extension must be loaded !'); - } - } + */ +Wind::import('WIND:component.cache.AbstractWindCache'); + +class WindXCache extends AbstractWindCache { + + public function __construct() { + if (!function_exists('xcache_get')) { + throw new WindException('The xcache extension must be loaded !'); + } + } + /* * @see AbstractWindCache#setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return xcache_set($key, $value, $expire); - } + */ + protected function setValue($key, $value, $expire = 0) { + return xcache_set($key, $value, $expire); + } + /* * @see AbstractWindCache#getValue() - */ - protected function getValue($key) { - return xcache_get($key); - } - + */ + protected function getValue($key) { + return xcache_get($key); + } + /* * @see AbstractWindCache#deleteValue() - */ - protected function deleteValue($key) { - return xcache_unset($key); - } - + */ + protected function deleteValue($key) { + return xcache_unset($key); + } + /* * @see AbstractWindCache#clear() - */ - public function clear() { - $max = xcache_count(XC_TYPE_VAR); - for ($i = 0; $i < $max; $i++) { - xcache_clear_cache(XC_TYPE_VAR, $i); - } - return true; - } - + */ + public function clear() { + $max = xcache_count(XC_TYPE_VAR); + for ($i = 0; $i < $max; $i++) { + xcache_clear_cache(XC_TYPE_VAR, $i); + } + return true; + } + } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindZendCache.php b/wind/component/cache/strategy/WindZendCache.php index e6081bcf..4172455a 100644 --- a/wind/component/cache/strategy/WindZendCache.php +++ b/wind/component/cache/strategy/WindZendCache.php @@ -42,5 +42,5 @@ protected function deleteValue($key) { public function clear() { return zend_shm_cache_clear(); } - + } \ No newline at end of file From 38bf703d7eb19d970613de8e335911724f8b5d98 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 22 Jul 2011 03:17:02 +0000 Subject: [PATCH 0141/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2201 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/dependency/WindCacheDependency.php | 2 +- wind/component/cache/strategy/WindDbCache.php | 2 +- wind/component/cache/strategy/WindEacceleratorCache.php | 4 ++-- wind/component/cache/strategy/WindFileCache.php | 4 ++-- wind/component/cache/strategy/WindMemCache.php | 4 ++-- wind/component/cache/strategy/WindWinCache.php | 4 ++-- wind/component/cache/strategy/WindXCache.php | 4 ++-- wind/component/cache/strategy/WindZendCache.php | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/wind/component/cache/dependency/WindCacheDependency.php b/wind/component/cache/dependency/WindCacheDependency.php index 2f6aa893..39b0f117 100644 --- a/wind/component/cache/dependency/WindCacheDependency.php +++ b/wind/component/cache/dependency/WindCacheDependency.php @@ -7,7 +7,7 @@ * @package */ Wind::import('WIND:component.cache.IWindCacheDependency'); -class WindCacheDependency implements IWindCacheDependency { +abstract class WindCacheDependency implements IWindCacheDependency { /** * @var mixed 缓存依赖控制者 */ diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index a2cd0c70..e1f45482 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -84,7 +84,7 @@ protected function addValue($key, $value, $expire = 0) { */ protected function getValue($key) { $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; - $data = $this->getConnection()->createStatement($sql)->getOne(array($key), time())); + $data = $this->getConnection()->createStatement($sql)->getOne(array($key), time()); return $data[$this->valueField]; } diff --git a/wind/component/cache/strategy/WindEacceleratorCache.php b/wind/component/cache/strategy/WindEacceleratorCache.php index c2cedbce..7efef569 100644 --- a/wind/component/cache/strategy/WindEacceleratorCache.php +++ b/wind/component/cache/strategy/WindEacceleratorCache.php @@ -20,9 +20,9 @@ public function __construct() { } /* - * @see AbstractWindCache#set() + * @see AbstractWindCache#addValue() */ - protected function setValue($key, $value, $expire = 0) { + protected function addValue($key, $value, $expire = 0) { return eaccelerator_put($key, $value, $expire); } diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 9e69490f..e496459a 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -40,9 +40,9 @@ class WindFileCache extends AbstractWindCache { const LEVEL = 'cache-level'; /* (non-PHPdoc) - * @see AbstractWindCache::setValue() + * @see AbstractWindCache::addValue() */ - protected function setValue($key, $value, $expire = 0) { + protected function addValue($key, $value, $expire = 0) { return $this->writeData($key, $value, $expire); } diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php index 6ad4ee49..131e0c3f 100644 --- a/wind/component/cache/strategy/WindMemCache.php +++ b/wind/component/cache/strategy/WindMemCache.php @@ -60,9 +60,9 @@ public function __construct() { } /* - * @see AbstractWindCache::setValue() + * @see AbstractWindCache::addValue() */ - protected function setValue($key, $value, $expire = 0) { + protected function addValue($key, $value, $expire = 0) { return $this->memcache->set($key, $value, $this->compress, (int) $expire); } diff --git a/wind/component/cache/strategy/WindWinCache.php b/wind/component/cache/strategy/WindWinCache.php index 71a03cce..3fc5354d 100644 --- a/wind/component/cache/strategy/WindWinCache.php +++ b/wind/component/cache/strategy/WindWinCache.php @@ -16,9 +16,9 @@ public function __construct() { } /* - * @see AbstractWindCache#setValue() + * @see AbstractWindCache#addValue() */ - protected function setValue($key, $value, $expire = 0) { + protected function addValue($key, $value, $expire = 0) { return wincache_ucache_set($key, $value, $expire); } diff --git a/wind/component/cache/strategy/WindXCache.php b/wind/component/cache/strategy/WindXCache.php index 989b89ae..eb2283ea 100644 --- a/wind/component/cache/strategy/WindXCache.php +++ b/wind/component/cache/strategy/WindXCache.php @@ -17,9 +17,9 @@ public function __construct() { } /* - * @see AbstractWindCache#setValue() + * @see AbstractWindCache#addValue() */ - protected function setValue($key, $value, $expire = 0) { + protected function addValue($key, $value, $expire = 0) { return xcache_set($key, $value, $expire); } diff --git a/wind/component/cache/strategy/WindZendCache.php b/wind/component/cache/strategy/WindZendCache.php index 4172455a..90f34e40 100644 --- a/wind/component/cache/strategy/WindZendCache.php +++ b/wind/component/cache/strategy/WindZendCache.php @@ -16,9 +16,9 @@ public function __construct() { } /* (non-PHPdoc) - * @see AbstractWindCache::setValue() + * @see AbstractWindCache::addValue() */ - protected function setValue($key, $value, $expire = 0) { + protected function addValue($key, $value, $expire = 0) { return zend_shm_cache_store($key, $value, $expire); } From d79005d8ed28a779482cbd8e0d9694ba8f922d51 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 22 Jul 2011 06:39:05 +0000 Subject: [PATCH 0142/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2202 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindApcCache.php | 4 ++-- wind/component/cache/strategy/WindDbCache.php | 4 ++-- wind/component/cache/strategy/WindEacceleratorCache.php | 4 ++-- wind/component/cache/strategy/WindFileCache.php | 4 ++-- wind/component/cache/strategy/WindMemCache.php | 4 ++-- wind/component/cache/strategy/WindWinCache.php | 4 ++-- wind/component/cache/strategy/WindXCache.php | 4 ++-- wind/component/cache/strategy/WindZendCache.php | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/wind/component/cache/strategy/WindApcCache.php b/wind/component/cache/strategy/WindApcCache.php index 2961e3be..22d934a9 100644 --- a/wind/component/cache/strategy/WindApcCache.php +++ b/wind/component/cache/strategy/WindApcCache.php @@ -16,9 +16,9 @@ public function __construct(){ } /* - * @see AbstractWindCache#addValue() + * @see AbstractWindCache#setValue() */ - protected function addValue($key, $value, $expires = 0) { + protected function setValue($key, $value, $expires = 0) { return apc_store($key, $value, $expires); } diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index e1f45482..52a53e57 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -67,9 +67,9 @@ public function __construct(WindConnection $connection = null, $config = array() } /* - * @see AbstractWindCache#addValue() + * @see AbstractWindCache#setValue() */ - protected function addValue($key, $value, $expire = 0) { + protected function setValue($key, $value, $expire = 0) { (mt_rand(100, 1000000) % 100 == 0) && $this->deleteExpiredCache(); $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =?' ; $data = $this->getConnection()->createStatement($sql)->getOne(array($key)); diff --git a/wind/component/cache/strategy/WindEacceleratorCache.php b/wind/component/cache/strategy/WindEacceleratorCache.php index 7efef569..cfdb6d28 100644 --- a/wind/component/cache/strategy/WindEacceleratorCache.php +++ b/wind/component/cache/strategy/WindEacceleratorCache.php @@ -20,9 +20,9 @@ public function __construct() { } /* - * @see AbstractWindCache#addValue() + * @see AbstractWindCache#setValue() */ - protected function addValue($key, $value, $expire = 0) { + protected function setValue($key, $value, $expire = 0) { return eaccelerator_put($key, $value, $expire); } diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index e496459a..9e69490f 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -40,9 +40,9 @@ class WindFileCache extends AbstractWindCache { const LEVEL = 'cache-level'; /* (non-PHPdoc) - * @see AbstractWindCache::addValue() + * @see AbstractWindCache::setValue() */ - protected function addValue($key, $value, $expire = 0) { + protected function setValue($key, $value, $expire = 0) { return $this->writeData($key, $value, $expire); } diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php index 131e0c3f..6ad4ee49 100644 --- a/wind/component/cache/strategy/WindMemCache.php +++ b/wind/component/cache/strategy/WindMemCache.php @@ -60,9 +60,9 @@ public function __construct() { } /* - * @see AbstractWindCache::addValue() + * @see AbstractWindCache::setValue() */ - protected function addValue($key, $value, $expire = 0) { + protected function setValue($key, $value, $expire = 0) { return $this->memcache->set($key, $value, $this->compress, (int) $expire); } diff --git a/wind/component/cache/strategy/WindWinCache.php b/wind/component/cache/strategy/WindWinCache.php index 3fc5354d..71a03cce 100644 --- a/wind/component/cache/strategy/WindWinCache.php +++ b/wind/component/cache/strategy/WindWinCache.php @@ -16,9 +16,9 @@ public function __construct() { } /* - * @see AbstractWindCache#addValue() + * @see AbstractWindCache#setValue() */ - protected function addValue($key, $value, $expire = 0) { + protected function setValue($key, $value, $expire = 0) { return wincache_ucache_set($key, $value, $expire); } diff --git a/wind/component/cache/strategy/WindXCache.php b/wind/component/cache/strategy/WindXCache.php index eb2283ea..989b89ae 100644 --- a/wind/component/cache/strategy/WindXCache.php +++ b/wind/component/cache/strategy/WindXCache.php @@ -17,9 +17,9 @@ public function __construct() { } /* - * @see AbstractWindCache#addValue() + * @see AbstractWindCache#setValue() */ - protected function addValue($key, $value, $expire = 0) { + protected function setValue($key, $value, $expire = 0) { return xcache_set($key, $value, $expire); } diff --git a/wind/component/cache/strategy/WindZendCache.php b/wind/component/cache/strategy/WindZendCache.php index 90f34e40..4172455a 100644 --- a/wind/component/cache/strategy/WindZendCache.php +++ b/wind/component/cache/strategy/WindZendCache.php @@ -16,9 +16,9 @@ public function __construct() { } /* (non-PHPdoc) - * @see AbstractWindCache::addValue() + * @see AbstractWindCache::setValue() */ - protected function addValue($key, $value, $expire = 0) { + protected function setValue($key, $value, $expire = 0) { return zend_shm_cache_store($key, $value, $expire); } From e8bf7ccc5fbd56851292ee6a4d0378b04a2f2ca6 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 22 Jul 2011 06:39:13 +0000 Subject: [PATCH 0143/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2203 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index 798d3034..1df60829 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -76,7 +76,7 @@ public function set($key, $value, $expires = 0, IWindCacheDependency $denpendenc $data[self::DEPENDENCY] = serialize($denpendency); $data[self::DEPENDENCYCLASS] = get_class($denpendency); } - return $this->addValue($this->buildSecurityKey($key), serialize($data), $expires); + return $this->setValue($this->buildSecurityKey($key), serialize($data), $expires); } /** @@ -87,7 +87,7 @@ public function set($key, $value, $expires = 0, IWindCacheDependency $denpendenc * @param int $expires * @throws WindException */ - protected abstract function addValue($key, $value, $expires = 0); + protected abstract function setValue($key, $value, $expires = 0); /** * 获取指定缓存 @@ -243,7 +243,6 @@ public function setConfig($config) { $this->setExpire($this->getCofnig(self::EXPIRE, '', 0)); } - /** * 获得缓存表相关配置 * From 295989e31d8eaf4b51b530238755b2ce39f471b3 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 22 Jul 2011 06:40:47 +0000 Subject: [PATCH 0144/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2204 18ba2127-5a84-46d4-baec-3457e417f034 --- .../cache/dependency/WindSqlCacheDependency.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wind/component/cache/dependency/WindSqlCacheDependency.php b/wind/component/cache/dependency/WindSqlCacheDependency.php index 6593916a..dba5b837 100644 --- a/wind/component/cache/dependency/WindSqlCacheDependency.php +++ b/wind/component/cache/dependency/WindSqlCacheDependency.php @@ -15,5 +15,12 @@ * @package */ class WindSqlCacheDependency extends WindCacheDependency{ - + /** + * (non-PHPdoc) + * @see WindCacheDependency::notifyDependencyChanged() + */ + protected function notifyDependencyChanged() { + // TODO Auto-generated method stub + + } } \ No newline at end of file From d23be2eb1dfb98e1bdd250d4e13bff6fca765e28 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 22 Jul 2011 07:43:09 +0000 Subject: [PATCH 0145/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2205 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 25 ++--- wind/_compile/components_config.xml | 5 +- wind/component/viewer/WindView.php | 8 +- wind/core/WindModule.php | 59 +++++------ wind/core/config/WindConfig.php | 135 -------------------------- wind/core/config/WindSystemConfig.php | 126 +++++++++++++----------- wind/core/web/WindFrontController.php | 2 +- 7 files changed, 115 insertions(+), 245 deletions(-) delete mode 100644 wind/core/config/WindConfig.php diff --git a/wind/Wind.php b/wind/Wind.php index 2d12f72a..555fcc89 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -417,18 +417,19 @@ private static function _loadBaseLib() { } Wind::init(); /* 组件定义 */ -!defined('COMPONENT_WEBAPP') && define('COMPONENT_WEBAPP', 'windWebApp'); -!defined('COMPONENT_ERRORHANDLER') && define('COMPONENT_ERRORHANDLER', 'errorHandler'); -!defined('COMPONENT_LOGGER') && define('COMPONENT_LOGGER', 'windLogger'); -!defined('COMPONENT_FORWARD') && define('COMPONENT_FORWARD', 'forward'); -!defined('COMPONENT_ROUTER') && define('COMPONENT_ROUTER', 'urlBasedRouter'); -!defined('COMPONENT_URLHELPER') && define('COMPONENT_URLHELPER', 'urlHelper'); -!defined('COMPONENT_VIEW') && define('COMPONENT_VIEW', 'windView'); -!defined('COMPONENT_VIEWRESOLVER') && define('COMPONENT_VIEWRESOLVER', 'viewResolver'); -!defined('COMPONENT_TEMPLATE') && define('COMPONENT_TEMPLATE', 'template'); -!defined('COMPONENT_ERRORMESSAGE') && define('COMPONENT_ERRORMESSAGE', 'errorMessage'); -!defined('COMPONENT_DB') && define('COMPONENT_DB', 'db'); -!defined('COMPONENT_DISPATCHER') && define('COMPONENT_DISPATCHER', 'dispatcher'); +define('COMPONENT_WEBAPP', 'windWebApp'); +define('COMPONENT_ERRORHANDLER', 'errorHandler'); +define('COMPONENT_LOGGER', 'windLogger'); +define('COMPONENT_FORWARD', 'forward'); +define('COMPONENT_ROUTER', 'urlBasedRouter'); +define('COMPONENT_URLHELPER', 'urlHelper'); +define('COMPONENT_VIEW', 'windView'); +define('COMPONENT_VIEWRESOLVER', 'viewResolver'); +define('COMPONENT_TEMPLATE', 'template'); +define('COMPONENT_ERRORMESSAGE', 'errorMessage'); +define('COMPONENT_DB', 'db'); +define('COMPONENT_DISPATCHER', 'dispatcher'); +define('COMPONENT_CONFIGPARSER', 'configParser'); //TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 //********************约定变量*********************************** define('WIND_M_ERROR', 'windError'); diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index c8e418a6..f1360e27 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -53,7 +53,7 @@ - + @@ -74,5 +74,8 @@ + + diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index b87874ca..13306c46 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -137,10 +137,10 @@ private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) * @return */ public function init() { - $this->setTemplateDir($this->getConfig(self::TEMPLATE_DIR, WIND_CONFIG_VALUE)); - $this->setCompileDir($this->getConfig(self::COMPILE_DIR, WIND_CONFIG_VALUE)); - $this->setTemplateExt($this->getConfig(self::TEMPLATE_EXT, WIND_CONFIG_VALUE)); - $this->setIsCache($this->getConfig(self::IS_CACHE), WIND_CONFIG_VALUE); + $this->setTemplateDir($this->getConfig(self::TEMPLATE_DIR, 'value')); + $this->setCompileDir($this->getConfig(self::COMPILE_DIR, 'value')); + $this->setTemplateExt($this->getConfig(self::TEMPLATE_EXT, 'value')); + $this->setIsCache($this->getConfig(self::IS_CACHE, 'value')); } /** diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 9455e50d..73e9a0f2 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -9,15 +9,9 @@ */ class WindModule { /** - * @var WindConfig - */ - private $_config = null; - /** - * 该对象的数组形态 - * * @var array */ - private $_array = array(); + private $_config = array(); /** * 是否进行类型验证 * @@ -116,17 +110,14 @@ public function __clone() { * @return array */ public function toArray() { - if (empty($this->_array)) { - $reflection = new ReflectionClass(get_class($this)); - $properties = $reflection->getProperties(); - $_result = array(); - foreach ($properties as $property) { - $_propertyName = $property->name; - $_result[$_propertyName] = $this->$_propertyName; - } - $this->_array = $_result; + $reflection = new ReflectionClass(get_class($this)); + $properties = $reflection->getProperties(); + $_result = array(); + foreach ($properties as $property) { + $_propertyName = $property->name; + $_result[$_propertyName] = $this->$_propertyName; } - return $this->_array; + return $_result; } /** @@ -145,14 +136,16 @@ protected function validatePropertyName($propertyName, $value = null) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, + 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, + 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { @@ -171,32 +164,32 @@ protected function validatePropertyName($propertyName, $value = null) { * * @param string $configName 键名 * @param string $subConfigName 二级键名 - * @param array $default 默认值 + * @param string $default 默认值 + * @param array $config * @return string|array */ - public function getConfig($configName = '', $subConfigName = '', $default = '') { - if ($this->_config === null) { - Wind::log('[core.WindModule.getConfig] config is not exist.', WindLogger::LEVEL_INFO, 'wind.core'); - return $default; - } - return $this->_config->getConfig($configName, $subConfigName, array(), $default); + public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { + if (!$config) $config = $this->_config; + if ($configName === '') return $config; + if (!isset($config[$configName])) return $default; + if ($subConfigName === '' || !isset($config[$configName][$subConfigName])) $config[$configName]; + return $config[$configName][$subConfigName]; } /** * Config配置,如果配置信息已经存在,则会合并配置 * * @param string|array|windConfig $config + * @return */ public function setConfig($config) { if (!$config) return; if (is_string($config)) { - Wind::import('WIND:core.config.parser.WindConfigParser'); - $config = new WindConfig($config, new WindConfigParser(), get_class($this), WIND_CONFIG_CACHE); - } elseif (is_array($config)) - $config = new WindConfig($config); - - if ($this->_config !== null) - $this->_config->setConfig($config->getConfig(), true); + $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); + $config = $configParser->parse($config, get_class($this), WIND_CONFIG_CACHE); + } + if (!$this->_config) + $this->_config = array_merge($this->_config, $config); else $this->_config = $config; } diff --git a/wind/core/config/WindConfig.php b/wind/core/config/WindConfig.php deleted file mode 100644 index 20280bcf..00000000 --- a/wind/core/config/WindConfig.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindConfig { - /* 配置解析信息 */ - protected $configParser = null; - protected $cacheName; - protected $append; - protected $config = array(); - - /** - * @param string $config | 配置文件路径信息 - * @param string $configParser | 配置解析器 - * @param string $cacheName | 配置文件缓存文件名称 - * @param WindConfigParser $configParser | 配置解析器 - */ - public function __construct($config, $configParser = null, $cacheName = '', $append = false) { - $this->setConfigParser($configParser); - $this->setCacheName($cacheName); - $this->setAppend($append); - $this->initConfig($config); - } - - /** - * 根据配置名取得相应的配置 - * - * @param string $configName - * @param string $subConfigName - * @return string - */ - public function getConfig($configName = '', $subConfigName = '', $config = array(), $default = null) { - if (!$config) $config = $this->config; - if ($configName === '') return $config; - $_config = $default; - if (isset($config[$configName])) { - $_config = $config[$configName]; - } - if ($subConfigName === '') return $_config; - $_subConfig = $default; - if (is_array($_config) && isset($_config[$subConfigName])) { - $_subConfig = $_config[$subConfigName]; - } - return $_subConfig; - } - - /** - * 初始化配置文件对象,如果参数是非数据格式, - * 则该方法会尝试调用注册进来的配置解析器进行配置解析 - * 如果没有注册过任何配置解析器,则抛出异常 - * - * @param array $config - */ - protected function initConfig($config) { - if (!$config) return; - if (!is_array($config)) { - $config = $this->parseConfig($config, $this->getCacheName(), $this->getAppend()); - } - $this->setConfig($config); - } - - /** - * 解析配置信息,返回解析后的配置结果 - * @param string $config | 配置文件源路径 - * @param string $cacheName | 缓存文件名称 | key值 - * @param string $append | 配置缓存是否追加到该缓存文件下面 - * @return array - */ - protected function parseConfig($config, $cacheName, $append) { - if ($this->getConfigParser() === null) { - throw new WindException('configParser is null.'); - } - return $this->getConfigParser()->parse($config, $cacheName, $append); - } - - /** - * @param $config the $config to set - * @author Qiong Wu - */ - public function setConfig($config, $merage = false) { - if ($merage) - $this->config = array_merge($this->config, (array) $config); - else - $this->config = $config; - } - - /** - * @return WindConfigParser $configParser - */ - public function getConfigParser() { - return $this->configParser; - } - - /** - * @param WindConfigParser $configParser - * @author Qiong Wu - */ - public function setConfigParser($configParser) { - if ($this->configParser || $configParser == null) return; - $this->configParser = $configParser; - } - - /** - * @return the $cacheName - */ - public function getCacheName() { - return $this->cacheName; - } - - /** - * @return the $append - */ - public function getAppend() { - return $this->append; - } - - /** - * @param $cacheName the $cacheName to set - * @author Qiong Wu - */ - public function setCacheName($cacheName) { - $this->cacheName = $cacheName; - } - - /** - * @param $append the $append to set - * @author Qiong Wu - */ - public function setAppend($append) { - $this->append = $append; - } -} \ No newline at end of file diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index 68fed652..cd0e4fda 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -6,69 +6,60 @@ * @version $Id$ * @package */ -class WindSystemConfig extends WindConfig { - /* 通用配置 */ - const CLASS_PATH = 'class'; - const PATH = 'path'; - const VALUE = 'value'; - - /* app 相关配置 */ - const WEB_APPS = 'web-apps'; - const WEB_APP_ROOT_PATH = 'root-path'; - const WEB_APP_FACTORY_CLASS_DEFINITION = 'class-definition'; - const WEB_APP_FILTER = 'filters'; - const WEB_APP_ROUTER = 'router'; - const WEB_APP_MODULE = 'modules'; - const WEB_APP_TEMPLATE = 'template'; +class WindSystemConfig extends WindModule { + private $rootPath = ''; + private $appName = ''; + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + if (!$config) return; + if (is_string($config)) { + $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); + $config = $configParser->parse($config, $this->appName . '_config'); + } + if (isset($config[$this->appName])) + $this->_config = $config[$this->appName]; + else + $this->_config = $config; + } /** * @param string $config - * @param WindConfigParser $configParser * @param string $appName */ - public function __construct($config, $configParser, $appName) { - $cacheName = $appName . '_config'; - parent::__construct($config, $configParser, $cacheName); - $_config = $this->getConfig(self::WEB_APPS, $appName); - $this->setConfig($_config); + public function __construct($config, $appName) { + $this->appName = $appName; + $this->setConfig($config, $appName); } /** * @return the $appName */ public function getAppName() { - return Wind::getAppName(); + return $this->appName; } /** - * 返回当前应用的启动脚本位置 - */ - public function getAppClass() { - return $this->getConfig(self::CLASS_PATH, '', array(), COMPONENT_WEBAPP); - } - - /** * 返回应用路径信息 - * - * @return string + * + * @return string */ public function getRootPath() { - $_tmp = '_rootPath'; - if (!isset($this->$_tmp)) { - $rootPath = $this->getConfig(self::WEB_APP_ROOT_PATH); + if (!$this->rootPath) { + $rootPath = $this->getConfig('root-path'); if (!$rootPath) $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); - $this->$_tmp = $rootPath; + $this->rootPath = $rootPath; } - return $this->$_tmp; + return $this->rootPath; } /** - * 返回filterChain的类型 - * - * @return array + * 返回当前应用的启动脚本位置 */ - public function getFilterClass() { - return $this->getFilters(self::CLASS_PATH); + public function getAppClass() { + return $this->getConfig('class', '', COMPONENT_WEBAPP); } /** @@ -78,24 +69,41 @@ public function getFilterClass() { * @param string $name * @return array|string */ - public function getFilters($name = '') { - return $this->getConfig(self::WEB_APP_FILTER, $name); + public function getFilters() { + return $this->getConfig('filters'); } /** - * 返回路由类型定义 - * @return string + * 返回filterChain的类型 + * + * @return array */ - public function getRouterClass() { - return $this->getRouter(WIND_CONFIG_CLASS); + public function getFilterClass() { + return $this->getConfig('filters', 'class'); } /** * @param string $name * @return array|string */ - public function getRouter($name = '') { - return $this->getConfig(self::WEB_APP_ROUTER, $name, array(), COMPONENT_ROUTER); + public function getRouter() { + return $this->getConfig('router'); + } + + /** + * 返回当前路由的配置信息 + * @return array + */ + public function getRouterConfig() { + return $this->getConfig('router', 'config'); + } + + /** + * 返回路由类型定义 + * @return string + */ + public function getRouterClass() { + return $this->getConfig('router', 'class', COMPONENT_ROUTER); } /** @@ -123,7 +131,7 @@ public function getRouter($name = '') { * @return array|string */ public function getModules($name = '') { - return $this->getConfig(self::WEB_APP_MODULE, $name); + return $this->getConfig('modules', $name); } /** @@ -132,8 +140,8 @@ public function getModules($name = '') { * @param string $default */ public function getModuleViewClassByModuleName($name, $default = '') { - $module = $this->getModules($name); - return $this->getConfig('view', WIND_CONFIG_CLASS, $module, $default); + $module = $this->getConfig('modules', $name); + return $this->getConfig('view', 'class', $default, $module); } /** @@ -142,8 +150,8 @@ public function getModuleViewClassByModuleName($name, $default = '') { * @param string $default */ public function getModuleViewConfigByModuleName($name, $default = '') { - $module = $this->getModules($name); - return $this->getConfig('view', WIND_CONFIG_CONFIG, $module, $default); + $module = $this->getConfig('modules', $name); + return $this->getConfig('view', 'config', $default, $module); } /** @@ -153,8 +161,8 @@ public function getModuleViewConfigByModuleName($name, $default = '') { * @return string */ public function getModuleErrorHandlerByModuleName($name, $default = '') { - $module = $this->getModules($name); - return $this->getConfig('error-handler', WIND_CONFIG_CLASS, $module, $default); + $module = $this->getConfig('modules', $name); + return $this->getConfig('error-handler', 'class', $default, $module); } /** @@ -163,8 +171,8 @@ public function getModuleErrorHandlerByModuleName($name, $default = '') { * @return string */ public function getModuleControllerPathByModuleName($name, $default = '') { - $module = $this->getModules($name); - return $this->getConfig(WIND_CONFIG_CLASSPATH, '', $module, $default); + $module = $this->getConfig('modules', $name); + return $this->getConfig('path', '', $default, $module); } /** @@ -173,8 +181,8 @@ public function getModuleControllerPathByModuleName($name, $default = '') { * @return string */ public function getModuleControllerSuffixByModuleName($name, $default = '') { - $module = $this->getModules($name); - return $this->getConfig('controller-suffix', WIND_CONFIG_VALUE, $module, $default); + $module = $this->getConfig('modules', $name); + return $this->getConfig('controller-suffix', '', $default, $module); } } \ No newline at end of file diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 91087b9f..a2a6e08f 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -114,7 +114,7 @@ protected function initWindFactory() { * @param string $config */ protected function initWindConfig($appName, $config) { - $this->windSystemConfig = new WindSystemConfig($config, new WindConfigParser(), $appName); + $this->windSystemConfig = new WindSystemConfig($config, $appName); Wind::register($this->windSystemConfig->getRootPath(), $appName, true); if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( From 013be7ba3692c7de97f89a426f06ff7e31c4a2c7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 22 Jul 2011 08:06:27 +0000 Subject: [PATCH 0146/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2206 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindEnableValidateModule.php | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/wind/core/WindEnableValidateModule.php b/wind/core/WindEnableValidateModule.php index 6bb20cff..37fea1fc 100644 --- a/wind/core/WindEnableValidateModule.php +++ b/wind/core/WindEnableValidateModule.php @@ -23,9 +23,7 @@ public function getErrors() { } public function getErrorControllerAndAction() { - return array( - $this->errorController, - $this->errorAction); + return array($this->errorController, $this->errorAction); } /** @@ -60,9 +58,7 @@ private function validateArray(&$input) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); - if (call_user_func_array(array( - $this->getValidator(), - $rule['validator']), $arg) !== false) continue; + if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; @@ -83,23 +79,17 @@ private function validateObject(&$input) { $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); - $_input = in_array($getMethod, $methods) ? call_user_func(array( - $input, - $getMethod)) : ''; + $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); - if (call_user_func_array(array( - $this->getValidator(), - $rule['validator']), $arg) !== false) continue; + if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); - in_array($setMethod, $methods) && call_user_func_array(array( - $input, - $setMethod), array( - $rule['default'])); + in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), + array($rule['default'])); } } From fa475827d80c75c4e6abc976df3b2e81aee6b2bc Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 25 Jul 2011 01:56:16 +0000 Subject: [PATCH 0147/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2207 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 4 ++-- wind/component/cache/strategy/WindDbCache.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index 1df60829..e3be9b37 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -95,7 +95,7 @@ protected abstract function setValue($key, $value, $expires = 0); * @return mixed */ public function get($key) { - return $this->formatData($this->getValue($this->buildSecurityKey($key))); + return $this->formatData($key, $this->getValue($this->buildSecurityKey($key))); } /** @@ -156,7 +156,7 @@ public abstract function clear(); * @param string $value * @return array */ - protected function formatData($value) { + protected function formatData($key, $value) { $data = unserialize($value); if (!is_array($data)) return null; if ($this->hasChanged($key, $data)) return null; diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index 52a53e57..a83eb422 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -99,7 +99,7 @@ public function batchGet(array $keys) { $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys) . ' AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; $data = $this->getConnection()->createStatement($sql)->queryAll(array(time())); foreach ($data as $tmp) { - $result[] = $this->formatData($tmp[$this->valueField]); + $result[] = $this->formatData(array_search($tmp[$this->keyField], $keys), $tmp[$this->valueField]); } return $result; } From 7ac74f852d585d93ecb2292db32defdda3ec3ef0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 03:02:33 +0000 Subject: [PATCH 0148/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2208 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/config/WindSystemConfig.php | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index cd0e4fda..fbda8c5a 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -10,13 +10,23 @@ class WindSystemConfig extends WindModule { private $rootPath = ''; private $appName = ''; + /** + * @param string $config + * @param string $appName + * @param WindFactory $factory + */ + public function __construct($config, $appName, $factory) { + $this->appName = $appName; + $this->setConfig($config, $factory); + } + /* (non-PHPdoc) * @see WindModule::setConfig() */ - public function setConfig($config) { + public function setConfig($config, $factory = null) { if (!$config) return; if (is_string($config)) { - $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); + $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); $config = $configParser->parse($config, $this->appName . '_config'); } if (isset($config[$this->appName])) @@ -25,15 +35,6 @@ public function setConfig($config) { $this->_config = $config; } - /** - * @param string $config - * @param string $appName - */ - public function __construct($config, $appName) { - $this->appName = $appName; - $this->setConfig($config, $appName); - } - /** * @return the $appName */ From 1422d395604de6aeba9361f827907bb2d93c5acd Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 03:02:40 +0000 Subject: [PATCH 0149/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2209 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindFrontController.php | 48 +++++---------------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index a2a6e08f..986641c4 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -11,14 +11,6 @@ * @package */ class WindFrontController { - /** - * 全局配置对象类型定义,建议WindSystemConfig配置类作为全局配置容器 - */ - const WIND_SYSTEM_CONFIG = 'WIND:core.config.WindSystemConfig'; - /** - * 全局工厂类型定义,建议WindComponentFactory工厂类作为全局工厂 - */ - const WIND_SYSTEM_FACTORY = 'WIND:core.factory.WindFactory'; /** * 框架系统配置信息资源地址,只接受php格式配置 */ @@ -48,8 +40,7 @@ public function __construct($appName, $config = '') { try { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(); - $this->initWindConfig($appName, $config); - $this->initWindFactory(); + $this->init($appName, $config); } catch (Exception $exception) { throw new Exception('System failed to initialize.' . $exception->getMessage()); } @@ -86,11 +77,6 @@ protected function getFilterChain() { $filterChainPath = $this->windSystemConfig->getFilterClass(); $filters = $this->windSystemConfig->getFilters(); if (empty($filters) || empty($filterChainPath)) return null; - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log( - "[core.WindFrontController.getFilterChain] an filter chain defined.(" . $filterChainPath . "," . - count($filters) . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); - } return $this->windFactory->createInstance($filterChainPath, array($filters)); } @@ -98,38 +84,20 @@ protected function getFilterChain() { * 初始全局工厂类 * @return */ - protected function initWindFactory() { + protected function init($appName, $config) { $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); - $factoryClass = Wind::import(self::WIND_SYSTEM_FACTORY); - $this->windFactory = new $factoryClass(@include ($configPath)); - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.web.WindFrontController.initWindFactory] system factory:' . self::WIND_SYSTEM_FACTORY, - WindLogger::LEVEL_DEBUG, 'wind.core'); - } + $this->windFactory = new WindFactory(@include ($configPath)); + $this->windSystemConfig = new WindSystemConfig($config, $appName, $this->windFactory); + Wind::register($this->windSystemConfig->getRootPath(), $this->windSystemConfig->getAppName(), true); } /** - * 初始化系统配置 - * @param string $appName - * @param string $config - */ - protected function initWindConfig($appName, $config) { - $this->windSystemConfig = new WindSystemConfig($config, $appName); - Wind::register($this->windSystemConfig->getRootPath(), $appName, true); - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log( - '[core.web.WindFrontController.initWindConfig] rootPath:' . $this->windSystemConfig->getRootPath() . - ' appName:' . $this->windSystemConfig->getAppName(), WindLogger::LEVEL_DEBUG, 'wind.core'); - } - } - - /* (non-PHPdoc) - * @see AbstractWindServer::beforeProcess() + * 预处理Process方法 */ protected function beforeProcess() {} - /* (non-PHPdoc) - * @see AbstractWindServer::afterProcess() + /** + * 后处理Process方法 */ protected function afterProcess() { $this->response->sendResponse(); From 3d7000594ac20584911e305d0b629c65b6de87a2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 05:51:08 +0000 Subject: [PATCH 0150/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2210 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 45 +- wind/_compile/components_config.xml | 2 +- wind/core/WindModule.php | 36 +- wind/core/config/WindSystemConfig.php | 6 +- wind/core/factory/WindClassDefinition.php | 482 ---------------------- wind/core/factory/WindFactory.php | 174 ++++++-- wind/core/web/WindWebApplication.php | 14 +- 7 files changed, 200 insertions(+), 559 deletions(-) delete mode 100644 wind/core/factory/WindClassDefinition.php diff --git a/wind/Wind.php b/wind/Wind.php index 555fcc89..591a309b 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -56,7 +56,8 @@ public static function run($appName = 'default', $config = '') { * @return string */ public static function getAppName() { - if (!isset(self::$_currentApp[0])) return ''; + if (!isset(self::$_currentApp[0])) + return ''; return self::$_currentApp[0][0]; } @@ -100,8 +101,10 @@ public static function runWithCompile($appName = 'default', $config = '') { * @return string|null */ public static function import($filePath, $recursivePackage = false) { - if (!$filePath) return; - if (isset(self::$_imports[$filePath])) return self::$_imports[$filePath]; + if (!$filePath) + return; + if (isset(self::$_imports[$filePath])) + return self::$_imports[$filePath]; if (($pos = strrpos($filePath, '.')) !== false) $fileName = substr($filePath, $pos + 1); elseif (($pos1 = strrpos($filePath, ':')) !== false) @@ -112,7 +115,8 @@ public static function import($filePath, $recursivePackage = false) { if ($isPackage) { $filePath = substr($filePath, 0, $pos); $dirPath = self::getRealDir($filePath); - if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); + if (!$dh = opendir($dirPath)) + throw new Exception('the file ' . $dirPath . ' open failed!'); while (($file = readdir($dh)) !== false) { if (is_dir($dirPath . D_S . $file)) { if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { @@ -146,15 +150,18 @@ public static function import($filePath, $recursivePackage = false) { * @return */ public static function register($path, $alias = '', $includePath = false, $reset = false) { - if (!$path) return; + if (!$path) + return; $alias = strtolower($alias); if (!empty($alias)) { - if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = $path; + if (!isset(self::$_namespace[$alias]) || $reset) + self::$_namespace[$alias] = $path; } if ($includePath) { if (empty(self::$_includePaths)) { self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); - if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset(self::$_includePaths[$pos]); + if (($pos = array_search('.', self::$_includePaths, true)) !== false) + unset(self::$_includePaths[$pos]); } array_unshift(self::$_includePaths, $path); if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { @@ -170,7 +177,8 @@ public static function register($path, $alias = '', $includePath = false, $reset * @return null */ public static function autoLoad($className, $path = '') { - if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; + if (isset(self::$_classes[$className])) + $path = self::$_classes[$className]; if ($path === '') { throw new Exception('auto load ' . $className . ' failed.'); } @@ -207,7 +215,8 @@ public static function getRootPath($namespace) { public static function getRealPath($filePath, $suffix = '') { if (($pos = strpos($filePath, ':')) !== false) { $namespace = self::getRootPath(substr($filePath, 0, $pos)); - if (!$namespace) return $filePath; + if (!$namespace) + return $filePath; $filePath = $namespace . D_S . str_replace('.', D_S, substr($filePath, $pos + 1)); } !$suffix && $suffix = self::$_extensions; @@ -221,9 +230,11 @@ public static function getRealPath($filePath, $suffix = '') { * @return string|array('isPackage','fileName','extension','realPath') */ public static function getRealDir($dirPath) { - if (($pos = strpos($dirPath, ':')) === false) return $dirPath; + if (($pos = strpos($dirPath, ':')) === false) + return $dirPath; $namespace = self::getRootPath(substr($dirPath, 0, $pos)); - if (!$namespace) return $dirPath; + if (!$namespace) + return $dirPath; $dirPath = str_replace('.', D_S, substr($dirPath, $pos + 1)); return $namespace . D_S . $dirPath; } @@ -298,9 +309,11 @@ public static function clear() { * @return */ protected static function resetApp() { - if (!isset(self::$_currentApp[0])) return; + if (!isset(self::$_currentApp[0])) + return; $_current = self::$_currentApp[0]; - if ($_current[1] === '') return; + if ($_current[1] === '') + return; foreach (self::$_currentApp as $key => $value) { if ($value[0] == $_current[1]) { array_unshift(self::$_currentApp, $value); @@ -347,7 +360,8 @@ private static function _checkEnvironment() { throw new Exception('[wind._checkEnvironment] php version is lower, php ' . PHPVERSION . ' or later.', E_WARNING); } - if (!defined('COMPILE_PATH')) throw new Exception('compile path undefined.'); + if (!defined('COMPILE_PATH')) + throw new Exception('compile path undefined.'); function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); } @@ -369,7 +383,8 @@ private static function _setImport($className, $classPath) { * @return */ private static function _registerAutoloader() { - if (!self::$_isAutoLoad) return; + if (!self::$_isAutoLoad) + return; if (function_exists('spl_autoload_register')) spl_autoload_register('Wind::autoLoad'); else diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index f1360e27..0c918e91 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -1,6 +1,6 @@ - diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 73e9a0f2..0df24ce4 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -70,17 +70,17 @@ public function __call($methodName, $args) { if ($_prefix == '_set') { $this->$_propertyName = $args[0]; } elseif ($_prefix == '_get') { - if (!$this->$_propertyName && isset($this->delayAttributes[$_propertyName])) { - $_instance = null; + if ($this->$_propertyName) + return $this->$_propertyName; + if (isset($this->delayAttributes[$_propertyName])) { + $_value = null; $_property = $this->delayAttributes[$_propertyName]; - if (isset($_property[WindClassDefinition::REF])) { - $_ref = $_property[WindClassDefinition::REF]; - if ($this->getSystemFactory()->checkAlias($_ref)) - $_instance = $this->getSystemFactory()->getInstance($_ref); - else - $_instance = $this->getSystemFactory()->createInstance($_ref); + if (isset($_property['value'])) { + $_value = $_property['value']; + } elseif (isset($_property['ref'])) { + $_value = $this->getSystemFactory()->getInstance($_property['ref']); } - $this->$_propertyName = $_instance; + $this->$_propertyName = $_value; } return $this->$_propertyName; } @@ -149,7 +149,8 @@ protected function validatePropertyName($propertyName, $value = null) { return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { - if ($value instanceof $_writeTableProperties[$propertyName]) return true; + if ($value instanceof $_writeTableProperties[$propertyName]) + return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. @@ -169,10 +170,14 @@ protected function validatePropertyName($propertyName, $value = null) { * @return string|array */ public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { - if (!$config) $config = $this->_config; - if ($configName === '') return $config; - if (!isset($config[$configName])) return $default; - if ($subConfigName === '' || !isset($config[$configName][$subConfigName])) $config[$configName]; + if (!$config) + $config = $this->_config; + if ($configName === '') + return $config; + if (!isset($config[$configName])) + return $default; + if ($subConfigName === '' || !isset($config[$configName][$subConfigName])) + $config[$configName]; return $config[$configName][$subConfigName]; } @@ -183,7 +188,8 @@ public function getConfig($configName = '', $subConfigName = '', $default = '', * @return */ public function setConfig($config) { - if (!$config) return; + if (!$config) + return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); $config = $configParser->parse($config, get_class($this), WIND_CONFIG_CACHE); diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index fbda8c5a..a782c3d9 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -24,7 +24,8 @@ public function __construct($config, $appName, $factory) { * @see WindModule::setConfig() */ public function setConfig($config, $factory = null) { - if (!$config) return; + if (!$config) + return; if (is_string($config)) { $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); $config = $configParser->parse($config, $this->appName . '_config'); @@ -50,7 +51,8 @@ public function getAppName() { public function getRootPath() { if (!$this->rootPath) { $rootPath = $this->getConfig('root-path'); - if (!$rootPath) $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); + if (!$rootPath) + $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); $this->rootPath = $rootPath; } return $this->rootPath; diff --git a/wind/core/factory/WindClassDefinition.php b/wind/core/factory/WindClassDefinition.php deleted file mode 100644 index 6c59b4b7..00000000 --- a/wind/core/factory/WindClassDefinition.php +++ /dev/null @@ -1,482 +0,0 @@ - - * - * 配置文件格式: - * - * - * - * - * - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindClassDefinition { - /* 配置信息定义 */ - const NAME = 'name'; - const PATH = 'path'; - const FACTORY_METHOD = 'factory-method'; - const INIT_METHOD = 'init-method'; - const SCOPE = 'scope'; - const PROPERTIES = 'properties'; - const CONSTRUCTOR_ARG = 'constructor-arg'; - const REF = 'ref'; - const VALUE = 'value'; - const DELAY = 'delay'; - const PROXY = 'proxy'; - const CONFIG = 'config'; - const RESOURCE = 'resource'; - /* 支持的类命名空间 */ - const SCOPE_SINGLETON = 'singleton'; - const SCOPE_PROTOTYPE = 'prototype'; - const SCOPE_REQUEST = 'request'; - /** - * 类代理类型 - * - * @var string - */ - protected $proxyClass = 'WIND:core.factory.proxy.WindClassProxy'; - /** - * 配置信息 - * - * @var string|array - */ - protected $config; - /** - * 类代理信息 - * - * @var boolean|string - */ - protected $proxy; - /** - * 类名称 - * - * @var string - */ - protected $className; - /** - * 类别名 - * - * @var string - */ - protected $alias; - /** - * 类路径 - * - * @var string - */ - protected $path; - /** - * 类的存储空间 - * - * singleton/prototype/request/session - * @var string - */ - protected $scope; - /** - * 类自定义的初始化方法 - * - * @var string - */ - protected $factoryMethod; - /** - * 类设置属性之后的调用处理操作 - * - * @var string - */ - protected $initMethod; - /** - * 构造参数定义 - * - * @var array - */ - protected $constructArgs = array(); - /** - * 类属性定义 - * - * @var array - */ - protected $properties = array(); - /** - * 类定义 - * - * @var array - */ - protected $classDefinition; - /** - * @var instance - */ - private $instance = null; - - /** - * 根据类定义信息,初始化类对象 - * - * @param array $classDefinition - */ - public function __construct($classDefinition = array()) { - $this->init($classDefinition); - } - - /** - * 通过对象工厂创建单例对象 - * 如果用户配置有factory-method项,则调用该组件的该方法生成实例 - * 如果用户配置的该项方法不存在,则正常调用 - * - * @modified xiaoxia.xu - * @param IWindFactory $factory - * @return instance|Ambigous |NULL - */ - public function getInstance($factory, $args = array()) { - if ($instance = $this->executeFactoryMethod($args)) return $instance; - switch ($this->scope) { - case 'prototype': - return $this->createInstanceWithPrototype($factory, $args); - default: - return $this->createInstanceWithSingleton($factory, $args); - } - } - - /** - * 以原型方式创建类实例 - * @param IWindFactory $factory - * @param array $args - * @return NULL|object - */ - protected function createInstanceWithPrototype($factory, $args) { - return $this->createInstance($factory, $args); - } - - /** - * @param WindFactory $factory - * @param array $args - * @return NULL|object - */ - protected function createInstanceWithSingleton($factory, $args) { - $_instance = $this->createInstance($factory, $args); - $factory->setSingled($this->getAlias(), $_instance); - return $_instance; - } - - /** - * @modified xiaoxia.xu - * @param AbstractWindFactory $factory - * @param array $args - */ - protected function createInstance($factory, $args) { - $args = $this->buildConstructArgs($factory, $args); - $instance = $factory->createInstance($this->getClassName(), $args); - if ($instance instanceof WindModule) { - $this->buildConfig($instance, $factory); - $this->buildProperties($instance, $factory); - $this->executeInitMethod($instance); - $instance = $this->setProxyForClass($instance, $factory); - } - return $instance; - } - - /** - * 为类对象设置配置 - * - * @param WindModule $instance - * @param WindFactory $factory - * @return - */ - protected function buildConfig($instance, $factory) { - if (!$config = $this->getConfig()) return; - if (isset($config[self::RESOURCE])) { - $config = $config[self::RESOURCE]; - } - $instance->setConfig($config); - } - - /** - * 为类设置代理 - * - * @param WindModule $instance - * @param WindFactory $factory - * @return WindClassProxy - */ - protected function setProxyForClass($instance, $factory) { - if (!($proxy = $this->getProxy())) return $instance; - if ($proxy === 'false' || $proxy === false) return $instance; - $proxy = Wind::import($this->proxyClass); - return $factory->createInstance($proxy, array($instance)); - } - - /** - * 执行用户配置的初始化操作 - * - * @author xiaoxia.xu - * @param object $instance - * @return - */ - private function executeInitMethod($instance) { - try { - if (!($initMethod = $this->getInitMethod())) return; - return call_user_func_array(array($instance, $initMethod), array()); - } catch (Exception $e) { - throw new WindException( - '[core.factory.WindClassDefinition.executeInitMethod] (' . $this->getClassName() . '->' . $initMethod . - '()) "' . $e->getMessage() . '"', WindException::ERROR_CLASS_METHOD_NOT_EXIST); - } - } - - /** - * 构造构造函数参数对象 - * - * @param WindFactory $factory - * @throws WindException - */ - protected function buildConstructArgs($factory, $args) { - if ($args) return $args; - $subDefinitions = $this->getConstructArgs(); - $_tmp = array(); - foreach ($subDefinitions as $key => $subDefinition) { - if (isset($subDefinition[self::VALUE])) { - $_tmp[$key] = $subDefinition[self::VALUE]; - } elseif (isset($subDefinition[self::REF])) - $_tmp[$key] = $factory->getInstance($subDefinition[self::REF]); - } - return $_tmp; - } - - /** - * 将类实例的依赖注入到类实例中 - * - * @param WindModule $instance | 类实例 - * @param WindFactory $factory | 抽象的类工厂 - */ - protected function buildProperties($instance, $factory) { - if (!$subDefinitions = $this->getPropertys()) return; - foreach ($subDefinitions as $key => $subDefinition) { - $_value = ''; - if (isset($subDefinition[self::VALUE])) $_value = $subDefinition[self::VALUE]; - if ($_value) { - $_setter = 'set' . ucfirst(trim($key, '_')); - call_user_func_array(array($instance, $_setter), array($_value)); - } - } - $instance->setDelayAttributes($subDefinitions); - } - - /** - * 执行调用工厂方法 - * - * @param array $args - * @throws WindException - * @return NULL|mixed - */ - protected function executeFactoryMethod($args) { - try { - if (!($factoryMethod = $this->getFactoryMethod())) return null; - return call_user_func_array(array($this->getClassName(), $factoryMethod), $args); - } catch (Exception $e) { - throw new WindException( - '[core.factory.WindClassDefinition.executeFactoryMethod] (' . $this->getClassName() . '->' . - $factoryMethod . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); - } - } - - /** - * 初始化类定义 - * - * @param array $classDefinition - */ - protected function init($classDefinition) { - try { - foreach ($classDefinition as $key => $value) { - if (strpos($key, '-') !== false) { - list($_s1, $_s2) = explode('-', $key); - $_s1 = ucfirst($_s1); - $_s2 = ucfirst($_s2); - $_setter = 'set' . $_s1 . $_s2; - } else - $_setter = 'set' . ucfirst($key); - call_user_func_array(array($this, $_setter), array($value)); - } - $this->setClassDefinition($classDefinition); - } catch (Exception $e) { - throw new WindException("[core.factory.WindClassDefinition.init]" . $e->getMessage(), - WindException::ERROR_SYSTEM_ERROR); - } - } - - /** - * @return the $className - */ - public function getClassName() { - if (!$this->className) { - $this->className = Wind::import($this->getPath()); - } - return $this->className; - } - - /** - * @return the $alias - */ - public function getAlias() { - return $this->alias; - } - - /** - * @return the $path - */ - public function getPath() { - return $this->path; - } - - /** - * @return the $scope - */ - public function getScope() { - return $this->scope; - } - - /** - * @param string $className the $className to set - * @author Qiong Wu - */ - public function setClassName($className) { - $this->className = $className; - } - - /** - * @param string $alias the $alias to set - * @author Qiong Wu - */ - public function setAlias($alias) { - $this->alias = $alias; - } - - /** - * @param string $path the $path to set - * @author Qiong Wu - */ - public function setPath($path) { - $this->path = $path; - } - - /** - * @param string $scope the $scope to set - * @author Qiong Wu - */ - public function setScope($scope) { - $this->scope = strtolower($scope); - } - - /** - * @return the $constructArgs - */ - public function getConstructArgs() { - return $this->constructArgs; - } - - /** - * @return the $propertys - */ - public function getPropertys() { - return $this->properties; - } - - /** - * @return the $classDefinition - */ - public function getClassDefinition() { - return $this->classDefinition; - } - - /** - * @param array $constructArgs the $constructArgs to set - * @author Qiong Wu - */ - public function setConstructArgs($constructArgs) { - if (is_array($constructArgs) && !empty($constructArgs)) $this->constructArgs += $constructArgs; - } - - /** - * @param array $propertys the $propertys to set - * @author Qiong Wu - */ - public function setProperties($properties) { - if (!is_array($properties)) return; - $this->properties = array_merge($this->properties, $properties); - } - - /** - * @param array $classDefinition the $classDefinition to set - * @author Qiong Wu - */ - public function setClassDefinition($classDefinition) { - $this->classDefinition = $classDefinition; - } - - /** - * return the $factoryMethod - * - * @author xiaoxia.xu - * @return the $factoryMethod - */ - public function getFactoryMethod() { - return $this->factoryMethod; - } - - /** - * return the $initMethod - * - * @author xiaoxia.xu - * @return the $initMethod - */ - public function getInitMethod() { - return $this->initMethod; - } - - /** - * the $factoryMethod to set - * - * @author xiaoxia.xu - * @param string $factoryMethod - */ - public function setFactoryMethod($factoryMethod) { - $this->factoryMethod = $factoryMethod; - } - - /** - * the $initMethod to set - * - * @author xiaoxia.xu - * @param string $initMethod - */ - public function setInitMethod($initMethod) { - $this->initMethod = $initMethod; - } - - /** - * @return the $proxy - */ - public function getProxy() { - return $this->proxy; - } - - /** - * @param boolean $proxy - */ - public function setProxy($proxy) { - $this->proxy = $proxy; - } - - /** - * @return the $config - */ - public function getConfig() { - return $this->config; - } - - /** - * @param string $config - */ - public function setConfig($config) { - $this->config = $config; - } - -} \ No newline at end of file diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 3288451d..48db585c 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -11,6 +11,7 @@ * @package */ class WindFactory implements IWindFactory { + const WIND_PROXY = 'WIND:core.factory.proxy.WindClassProxy'; /** * 类定义集合 * @@ -32,18 +33,138 @@ class WindFactory implements IWindFactory { * @param string $configFile */ public function __construct($classDefinitions = array()) { - $this->loadClassDefinitions($classDefinitions); + $this->classDefinitions = $classDefinitions; } /* (non-PHPdoc) * @see AbstractWindFactory::getInstance() */ - public function getInstance($alias) { - if (isset($this->instances[$alias])) return $this->instances[$alias]; - if (!$classDefinition = $this->getClassDefinitionByAlias($alias)) return null; - $args = func_get_args(); - unset($args[0]); - return $classDefinition->getInstance($this, $args); + public function getInstance($alias, $args = array()) { + if (isset($this->instances[$alias])) + return $this->instances[$alias]; + if (!($definition = $this->checkAlias($alias))) + return null; + $this->buildDefinition($definition); + $_subDefinitions = $definition['constructorArg']; + foreach ($_subDefinitions as $_subDefinition) { + if (isset($_subDefinition['value'])) { + $args[] = $_subDefinition['value']; + } elseif (isset($_subDefinition['ref'])) + $args[] = $this->getInstance($_subDefinition['ref']); + } + $instance = $this->createInstance($definition['className'], $args); + if ($definition['config']) + $this->buildConfig($definition['config'], $instance); + if ($definition['properties']) + $this->buildProperties($definition['properties'], $instance); + if ($definition['initMethod']) + $this->executeInitMethod($definition['initMethod'], $instance); + if ($definition['proxy']) + $instance = $this->setProxyForClass($definition['proxy'], $instance); + + $this->setScope($alias, $definition['scope'], $instance); + return $instance; + } + + /** + * @param string $alias + * @param string $scope + * @param object $instance + */ + protected function setScope($alias, $scope, $instance) { + switch ($scope) { + case 'prototype': + break; + case 'application': + $this->instances[$alias] = $instance; + break; + default: + $this->instances[$alias] = $instance; + break; + + } + } + + /** + * 为类对象设置配置 + * + * @param WindModule $instance + * @param WindFactory $factory + * @return + */ + protected function buildConfig($config, $instance) { + if (isset($config['resource'])) + $config = $config['resource']; + $instance->setConfig($config); + } + + /** + * 执行用户配置的初始化操作 + * + * @param string $initMethod + * @param object $instance + * @return + */ + protected function executeInitMethod($initMethod, $instance) { + try { + return call_user_func_array(array($instance, $initMethod), array()); + } catch (Exception $e) { + throw new WindException( + '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); + } + } + + /** + * 为类设置代理 + * + * @param string $definition + * @param WindModule $instance + * @return WindClassProxy + */ + protected function setProxyForClass($proxy, $instance) { + if ($proxy === 'false' || $proxy === false) + return $instance; + $proxy = Wind::import(self::WIND_PROXY); + return $this->createInstance($proxy, array($instance)); + } + + /** + * 将类实例的依赖注入到类实例中 + * + * @param string $properties + * @param WindModule $instance + */ + protected function buildProperties($properties, $instance) { + if (isset($properties['delay']) && ($properties['delay'] === 'false' || $properties['delay'] === false)) { + unset($properties['delay']); + foreach ($properties as $key => $subDefinition) { + $_value = ''; + if (isset($subDefinition['value'])) + $_value = $subDefinition['value']; + elseif (isset($subDefinition['ref'])) + $_value = $this->getInstance($subDefinition['ref']); + if ($_value) { + $_setter = 'set' . ucfirst(trim($key, '_')); + call_user_func_array(array($instance, $_setter), array($_value)); + } + } + } + $instance->setDelayAttributes($properties); + } + + /** + * 验证类定义的正确性 + * + * @param array definition + * @return boolean + */ + private function buildDefinition(&$definition) { + $_definition = array('path' => '', 'className' => '', 'factoryMethod' => '', 'initMethod' => '', + 'scope' => 'application', 'proxy' => false, 'properties' => array(), 'config' => array(), 'constructorArg' => array()); + $definition = array_merge($_definition, $definition); + $definition['className'] = Wind::import($definition['path']); + return true; } /* (non-PHPdoc) @@ -51,7 +172,8 @@ public function getInstance($alias) { */ public function getPrototype($alias) { $instance = $this->getInstance($alias); - if ($instance === null) return null; + if ($instance === null) + return null; return clone $instance; } @@ -90,8 +212,10 @@ public function setSingled($classAlias, $instance) { * @return WindClassDefinition */ protected function getClassDefinitionByAlias($classAlias) { - if (!($definition = $this->classDefinitions[$classAlias])) return null; - if ($definition instanceof WindClassDefinition) return $definition; + if (!($definition = $this->classDefinitions[$classAlias])) + return null; + if ($definition instanceof WindClassDefinition) + return $definition; $classDefinition = self::createInstance('WindClassDefinition', array($definition)); $classDefinition->setAlias($classAlias); $this->addClassDefinitions($classDefinition); @@ -101,17 +225,12 @@ protected function getClassDefinitionByAlias($classAlias) { /** * 动态添加类定义对象 * - * @param WindClassDefinition|array $classDefinition + * @param string $alias + * @param array $classDefinition * @return */ - public function addClassDefinitions($classDefinition) { - if ($classDefinition instanceof WindClassDefinition) { - $alias = $classDefinition->getAlias(); - $this->classDefinitions[$alias] = $classDefinition; - } elseif (is_array($classDefinition)) { - foreach ($classDefinition as $value) - $this->addClassDefinitions($value); - } + public function addClassDefinitions($alias, $classDefinition) { + $this->classDefinitions[$alias] = $classDefinition; } /** @@ -121,22 +240,7 @@ public function addClassDefinitions($classDefinition) { * @return boolean */ public function checkAlias($alias) { - return isset($this->classDefinitions[$alias]); - } - - /** - * 加载类定义信息 - * - * @param array $classDefinitions - * @throws WindException - * @return - */ - protected function loadClassDefinitions($classDefinitions) { - if (is_array($classDefinitions)) - $this->classDefinitions = $classDefinitions; - else - throw new WindException('[core.factory.WindFactory.loadClassDefinitions]', - WindException::ERROR_PARAMETER_TYPE_ERROR); + return isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : false; } } \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index ad93b167..8fa8dac6 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -62,15 +62,11 @@ protected function getHandler() { 'wind.core'); } if (!$this->getSystemFactory()->checkAlias($handler)) { - $definition = new WindClassDefinition(); - $definition->setPath($handler); - $definition->setScope(WindClassDefinition::SCOPE_SINGLETON); - $definition->setAlias($handler); - $definition->setProxy('true'); - $definition->setProperties( - array('errorMessage' => array('ref' => COMPONENT_ERRORMESSAGE), - 'forward' => array('ref' => COMPONENT_FORWARD), 'urlHelper' => array('ref' => COMPONENT_URLHELPER))); - $this->getSystemFactory()->addClassDefinitions($definition); + $this->getSystemFactory()->addClassDefinitions($handler, + array('path' => $handler, 'scope' => 'singleton', 'proxy' => true, + 'properties' => array('errorMessage' => array('ref' => COMPONENT_ERRORMESSAGE), + 'forward' => array('ref' => COMPONENT_FORWARD), + 'urlHelper' => array('ref' => COMPONENT_URLHELPER)))); } return $this->getSystemFactory()->getInstance($handler); } From f5c7d8b056b6b9afb7c0c0e070b88ffe5870dc51 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 25 Jul 2011 06:11:18 +0000 Subject: [PATCH 0151/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2211 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 4 +- ...cy.php => AbstractWindCacheDependency.php} | 50 ++++--- wind/component/cache/IWindCacheDependency.php | 38 ------ wind/component/cache/WindCache.php | 129 ++++++++++++++++++ .../dependency/WindDbCacheDependency.php | 44 ++++++ .../dependency/WindFileCacheDependency.php | 27 ++++ .../dependency/WindSqlCacheDependency.php | 26 ---- wind/component/cache/strategy/WindDbCache.php | 1 + .../cache/strategy/WindFileCache.php | 1 + 9 files changed, 232 insertions(+), 88 deletions(-) rename wind/component/cache/{dependency/WindCacheDependency.php => AbstractWindCacheDependency.php} (52%) delete mode 100644 wind/component/cache/IWindCacheDependency.php create mode 100644 wind/component/cache/WindCache.php create mode 100644 wind/component/cache/dependency/WindDbCacheDependency.php create mode 100644 wind/component/cache/dependency/WindFileCacheDependency.php delete mode 100644 wind/component/cache/dependency/WindSqlCacheDependency.php diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index e3be9b37..727994ab 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -69,7 +69,7 @@ abstract class AbstractWindCache extends WindModule { * @param IWindCacheDependency $denpendency 缓存依赖 * @return boolean */ - public function set($key, $value, $expires = 0, IWindCacheDependency $denpendency = null) { + public function set($key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { $data = array(self::DATA => $value, self::EXPIRE => $expires, self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); if (null != $denpendency) { $denpendency->injectDependent(); @@ -172,7 +172,7 @@ protected function formatData($key, $value) { protected function hasChanged($key, array $data) { if (null === $data[self::DEPENDENCY] && '' === $data[self::DEPENDENCYCLASS]) return false; $dependency = unserialize($data[self::DEPENDENCY]); - if (($dependency instanceof IWindCacheDependency) && $dependency->hasChanged()) { + if (($dependency instanceof AbstractWindCacheDependency) && $dependency->hasChanged()) { $this->delete($key); return true; } diff --git a/wind/component/cache/dependency/WindCacheDependency.php b/wind/component/cache/AbstractWindCacheDependency.php similarity index 52% rename from wind/component/cache/dependency/WindCacheDependency.php rename to wind/component/cache/AbstractWindCacheDependency.php index 39b0f117..e49fef55 100644 --- a/wind/component/cache/dependency/WindCacheDependency.php +++ b/wind/component/cache/AbstractWindCacheDependency.php @@ -6,52 +6,58 @@ * @version $Id$ * @package */ -Wind::import('WIND:component.cache.IWindCacheDependency'); -abstract class WindCacheDependency implements IWindCacheDependency { - /** - * @var mixed 缓存依赖控制者 - */ - protected $dependent = ''; +abstract class AbstractWindCacheDependency { + /** + * 依赖的依据 + * + * @var mixed + */ protected $data = ''; /** * @var string 依赖项的上次更改时间 */ protected $lastModified; - /** - * @var IWindCache 缓存创建者 - */ - protected $cache = null; - public function __construct($dependent = null) { - $this->dependent = $dependent; - } - - /* - * @see wind/component/cache/base/IWindCacheDependency#injectDependent() + /** + * 初始化设置,设置依赖 */ public function injectDependent() { $this->lastModified = time(); + $this->data = $this->notifyDependencyChanged(); } - /* - * @see wind/component/cache/base/IWindCacheDependency#hasChanged() + /** + * 检查是否有变更 + * + * @return boolean */ public function hasChanged() { return $this->data != $this->notifyDependencyChanged(); } + + /** + * 获得依赖数据 + * + * @return mixed + */ + public function getDenpendencyData() { + return $this->data; + } - /* - * @see wind/component/cache/base/IWindCacheDependency#getLastModified() + /** + * 获得最后更新时间 + * @return int */ public function getLastModified() { return $this->lastModified; } /** - * 是否有变化 - * @return NULL + * 是否有变化 + * + * @return mixed 新的值 */ protected abstract function notifyDependencyChanged(); diff --git a/wind/component/cache/IWindCacheDependency.php b/wind/component/cache/IWindCacheDependency.php deleted file mode 100644 index 6e489703..00000000 --- a/wind/component/cache/IWindCacheDependency.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ - -/** - * 缓存依赖 - * 在依赖对象和被依赖对象对象之间建立一种有效的关联,当被依赖对象发生改变时,依赖对象就在缓存中被清楚 - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -interface IWindCacheDependency { - - /** - * 注入依赖 - * @param mixed - */ - public function injectDependent(); - - /** - * 是否已更新 - * @return boolean - */ - public function hasChanged(); - - /** - * 获取依赖项的上次更改时间 - * @return int - */ - public function getLastModified(); -} \ No newline at end of file diff --git a/wind/component/cache/WindCache.php b/wind/component/cache/WindCache.php new file mode 100644 index 00000000..43511fc8 --- /dev/null +++ b/wind/component/cache/WindCache.php @@ -0,0 +1,129 @@ + 2011-07-21 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +class WindCache { + + private static $caches = array(); + + const DB = 'db'; + const APC = 'apc'; + const FILE = 'file'; + const EAC = 'eaccelerator'; + const MEMCACHE = 'mem'; + const WINCACHE = 'win'; + const XCACHE = 'XCache'; + const ZEND = 'ZendCache'; + + /** + * 保存数据 + * + * @param string $type 缓存类型 + * @param string $key + * @param mixed $value + * @param int $expires + * @param AbstractWindCacheDependency $denpendency + * @return mixed + */ + public static function set($type, $key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { + $cache = self::getCache($type); + return $cache->set($key, $value, $expires, $denpendency); + } + + /** + * 获取数据 + * + * @param string $type 缓存类型 + * @param string $key + * @return mixed + */ + public static function get($type, $key) { + $cache = self::getCache($type); + return $cache->get($key); + } + + /** + * 删除缓存数据 + * + * @param string $type 缓存类型 + * @param string $key 获取缓存数据的标识,即键 + * @return mixed + */ + public static function delete($type, $key) { + $cache = self::getCache($type); + return $cache->delete($key); + } + + /** + * 批量获取数据 + * + * @param string $type + * @param string $keys + * @return array + */ + public static function batchGet($type, array $keys) { + $cache = self::getCache($type); + return $cache->batchGet($keys); + } + + /** + * 通过key批量删除缓存数据 + * + * @param string $type + * @param array $keys + * @return boolean + */ + public static function batchDelete($type, array $keys) { + $cache = self::getCache($type); + return $cache->batchDelete($keys); + } + + /** + * 通过key批量删除缓存数据 + * + * @param string $type + * @return boolean + */ + public static function clear($type = '') { + if ($type) { + $cache = self::getCache($type); + return $cache->clear(); + } + foreach(self::caches as $key => $cache) { + $cache->clear(); + } + return true; + } + + + /** + * 获得缓存类型 + * + * @param string $type + * @return AbstractWindCache + */ + private static function getCache($type) { + $type = self::getCacheMap($type); + if (!$type) throw new WindException('The cache strategy \'' . $type . '\' is not exists!'); + if (isset(self::$caches[$type])) return self::$caches[$type]; + $class = Wind::import('WIND:component.cache.strategy.' . $type); + self::$caches[$type] = new $class(); + return self::$caches[$type]; + } + + /** + * 对应类型对应的缓存 + * + * @param string $type + */ + private static function getCacheMap($type) { + $types = array(self::DB => 'WindDbCache', self::APC => 'WindApcCache', self::FILE => 'WindFileCache', + self::EAC => 'WindEacceleratorCache', self::MEMCACHE => 'WindMemCache', self::WINCACHE => 'WindWinCache', + self::XCACHE => 'WindXCache', self::ZEND => 'WindZendCache'); + return isset($types[$type]) ? $types[$type] : null; + } +} \ No newline at end of file diff --git a/wind/component/cache/dependency/WindDbCacheDependency.php b/wind/component/cache/dependency/WindDbCacheDependency.php new file mode 100644 index 00000000..50ccabdb --- /dev/null +++ b/wind/component/cache/dependency/WindDbCacheDependency.php @@ -0,0 +1,44 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +Wind::import('WIND:component.cache.dependency.AbstractWindCacheDependency'); +class WindDbCacheDependency extends AbstractWindCacheDependency{ + private $sql = ''; + private $config = ''; + private $connection = null; + + public function __construct($sql, $config = '') { + $sql && $this->sql = $sql; + $config && $this->config = $this->config; + } + + /* + * (non-PHPdoc) + * @see WindCacheDependency::notifyDependencyChanged() + */ + protected function notifyDependencyChanged() { + if (!$this->sql) return null; + return $this->getConnection()->query($this->sql)->fetchAll(); + } + + /** + * 获得链接对象 + * //TODO DB链接对象~获取全局统一。。 + */ + private function getConnection() { + if ($this->connection != null ) return $this->connection; + if ($this->config) { + $this->connection = new WindConnection(); + $this->connection->setConfig($this->dbConfig); + $this->connection->init(); + return $this->connection; + } + } + + +} \ No newline at end of file diff --git a/wind/component/cache/dependency/WindFileCacheDependency.php b/wind/component/cache/dependency/WindFileCacheDependency.php new file mode 100644 index 00000000..c72a3719 --- /dev/null +++ b/wind/component/cache/dependency/WindFileCacheDependency.php @@ -0,0 +1,27 @@ + 2011-7-25 + * @link http://www.cnblogs.com/xiaoyaoxia/ + * @copyright Copyright © 2011-2012 xiaoxiao + * @license + * @package + */ +Wind::import('WIND:component.cache.AbstractWindCacheDependency'); +class WindFileCacheDependency extends AbstractWindCacheDependency { + private $fileName = ''; + + public function __construct($fileName = null) { + $this->fileName = $fileName; + } + + /* + * (non-PHPdoc) + * @see AbstractWindCacheDependency::notifyDependencyChanged() + */ + protected function notifyDependencyChanged() { + clearstatcache();//删除文件信息的缓存 + if ($this->fileName) { + return @filemtime($this->fileName); + } + } +} \ No newline at end of file diff --git a/wind/component/cache/dependency/WindSqlCacheDependency.php b/wind/component/cache/dependency/WindSqlCacheDependency.php deleted file mode 100644 index dba5b837..00000000 --- a/wind/component/cache/dependency/WindSqlCacheDependency.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -Wind::import('WIND:component.cache.dependency.WindCacheDependency'); -/** - * 监视特定的数据库表,以便在该表发生更改时,自动从 Cache 中删除与该表关联的项。数据库表发生更改时,将自动删除缓存项 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSqlCacheDependency extends WindCacheDependency{ - /** - * (non-PHPdoc) - * @see WindCacheDependency::notifyDependencyChanged() - */ - protected function notifyDependencyChanged() { - // TODO Auto-generated method stub - - } -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index a83eb422..c23dd274 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -171,6 +171,7 @@ public function setConnection($connection) { /** * 获得链接对象 * @return WindConnection + * //TODO DB链接对象~获取全局统一。。 */ private function getConnection() { if (null == $this->connection) { diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 9e69490f..00220cf2 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -109,6 +109,7 @@ private function writeData($file, $data, $mtime = 0) { */ private function readData($file) { if (false === is_file($file)) return null; + clearstatcache(); $mtime = filemtime($file); if (0 === $mtime || ($mtime && $mtime > time())) return WindFile::read($file); From a967b1ea1c7d0de67f326ff3726b50e1e3fffb2c Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 08:01:04 +0000 Subject: [PATCH 0152/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2212 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 16 ++----- wind/_compile/compile.php | 3 +- wind/core/WindEnableValidateModule.php | 1 - wind/core/WindModule.php | 8 ++-- wind/core/exception/WindActionException.php | 1 - wind/core/exception/WindFinalException.php | 2 - wind/core/filter/WindFilter.php | 8 ---- wind/core/filter/WindFilterChain.php | 8 ---- wind/core/request/WindHttpRequest.php | 1 - wind/core/web/WindErrorMessage.php | 2 +- wind/core/web/WindWebApplication.php | 8 ++-- wind/core/web/controller/WindController.php | 13 +++--- wind/core/web/filter/WindLoggerFilter.php | 42 ------------------- wind/core/web/filter/WindUrlFilter.php | 3 -- wind/core/web/listener/WindFormListener.php | 2 - wind/core/web/listener/WindLoggerListener.php | 4 +- .../web/listener/WindValidateListener.php | 3 -- 17 files changed, 23 insertions(+), 102 deletions(-) delete mode 100644 wind/core/web/filter/WindLoggerFilter.php diff --git a/wind/Wind.php b/wind/Wind.php index 591a309b..eb579f93 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -1,17 +1,16 @@ * @author Qiong Wu @@ -448,10 +447,3 @@ private static function _loadBaseLib() { //TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 //********************约定变量*********************************** define('WIND_M_ERROR', 'windError'); -define('WIND_CONFIG_CACHE', '_wind_config'); -//**********配置*******通用常量定义*************************************** -define('WIND_CONFIG_CONFIG', 'config'); -define('WIND_CONFIG_CLASS', 'class'); -define('WIND_CONFIG_CLASSPATH', 'path'); -define('WIND_CONFIG_RESOURCE', 'resource'); -define('WIND_CONFIG_VALUE', 'value'); \ No newline at end of file diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php index 96826f31..bd75e6f4 100644 --- a/wind/_compile/compile.php +++ b/wind/_compile/compile.php @@ -4,6 +4,7 @@ * @author wuq **/ define('_COMPILE_PATH', WIND_PATH . '_compile' . D_S); +define('_COMPILE_LIBRARY_PATH', WIND_PATH . 'wind_basic.php'); Wind::clear(); Wind::import('COM:log.WindLogger'); Wind::import('WIND:core.*', true); @@ -21,7 +22,7 @@ $fileList[$_key] = array($key, $value); $content[$value] = parseFilePath($key); } -$pack->packFromFileList($fileList, COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); +$pack->packFromFileList($fileList, _COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); /* import信息写入编译文件 */ WindFile::write(_COMPILE_PATH . 'wind_imports.php', '_validator === null) { $_className = Wind::import($this->_validatorClass); - Wind::import('WIND:core.factory.WindFactory'); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 0df24ce4..2dbff82b 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -136,16 +136,14 @@ protected function validatePropertyName($propertyName, $value = null) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, - 'wind.core'); + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, - 'wind.core'); + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { @@ -192,7 +190,7 @@ public function setConfig($config) { return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($config, get_class($this), WIND_CONFIG_CACHE); + $config = $configParser->parse($config, get_class($this), 'cache_wind_config'); } if (!$this->_config) $this->_config = array_merge($this->_config, $config); diff --git a/wind/core/exception/WindActionException.php b/wind/core/exception/WindActionException.php index 2fc39032..027cc34f 100644 --- a/wind/core/exception/WindActionException.php +++ b/wind/core/exception/WindActionException.php @@ -1,5 +1,4 @@ 2010-11-4 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.filter.WindHandlerInterceptor'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author xiaoxia xu diff --git a/wind/core/filter/WindFilterChain.php b/wind/core/filter/WindFilterChain.php index 37197037..989519b1 100644 --- a/wind/core/filter/WindFilterChain.php +++ b/wind/core/filter/WindFilterChain.php @@ -1,12 +1,4 @@ 2010-11-9 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -Wind::import('WIND:core.filter.WindHandlerInterceptorChain'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php index 3c690685..0b85eddc 100644 --- a/wind/core/request/WindHttpRequest.php +++ b/wind/core/request/WindHttpRequest.php @@ -503,7 +503,6 @@ public function getAcceptLanguage() { */ public function getResponse() { if ($this->_response === null) { - Wind::import('WIND:core.response.WindHttpResponse'); $this->_response = new WindHttpResponse(); if ($this->getIsAjaxRequest()) { $this->_response->addHeader('Content-type', 'text/xml;charset=utf-8'); diff --git a/wind/core/web/WindErrorMessage.php b/wind/core/web/WindErrorMessage.php index 926fd216..4142c233 100644 --- a/wind/core/web/WindErrorMessage.php +++ b/wind/core/web/WindErrorMessage.php @@ -11,7 +11,7 @@ class WindErrorMessage extends WindModule implements IWindErrorMessage { /** * @var string */ - private $errorController = WIND_M_ERROR; + private $errorController = 'windError'; /** * @param string $message diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 8fa8dac6..cdf5b580 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -33,8 +33,7 @@ public function processRequest() { } catch (WindDbException $dbException) { $this->sendErrorMessage($dbException->getMessage()); } catch (WindViewException $viewException) { - //TODO - throw new Exception($viewException->getMessage()); + $this->sendErrorMessage($viewException->getMessage()); } } @@ -79,10 +78,11 @@ protected function getHandler() { */ protected function sendErrorMessage($actionException) { $_tmp = is_object($actionException) ? $actionException->getError() : $actionException; - if (is_string($_tmp)) $_tmp = new WindErrorMessage($_tmp); + if (is_string($_tmp)) + $_tmp = new WindErrorMessage($_tmp); $forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD); $forward->forwardAnotherAction($_tmp->getErrorAction(), $_tmp->getErrorController()); - $this->getRequest()->setAttribute('error', $_tmp->getError()); + $this->getRequest()->setAttribute($_tmp->getError(), 'error'); $this->doDispatch($forward); } diff --git a/wind/core/web/controller/WindController.php b/wind/core/web/controller/WindController.php index dadf53bb..3ccdf69e 100644 --- a/wind/core/web/controller/WindController.php +++ b/wind/core/web/controller/WindController.php @@ -54,13 +54,16 @@ protected function setDefaultTemplateName($handlerAdapter) { */ protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); - if ($action !== 'run') $action = $this->resolvedActionName($action); + if ($action !== 'run') + $action = $this->resolvedActionName($action); try { - if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', - WindException::ERROR_CLASS_METHOD_NOT_EXIST); + if ($action == 'doAction') + throw new WindException('[core.web.WindController.resolvedActionMethod]', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); $method = new ReflectionMethod($this, $action); - if ($method->isAbstract() || !$method->isPublic()) throw new WindException( - '[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); + if ($method->isAbstract() || !$method->isPublic()) + throw new WindException('[core.web.WindController.resolvedActionMethod]', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); return $action; } catch (Exception $exception) { throw new WindException( diff --git a/wind/core/web/filter/WindLoggerFilter.php b/wind/core/web/filter/WindLoggerFilter.php deleted file mode 100644 index 0ed016d7..00000000 --- a/wind/core/web/filter/WindLoggerFilter.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindLoggerFilter extends WindFilter { - - /* (non-PHPdoc) - * @see WindFilter::preHandle() - */ - public function preHandle($request = null, $response = null) { - if (!IS_DEBUG) return; - $this->initWindLogger($request); - $this->logger->info('-------------------------------request start!!!!--------------------------------'); - } - - /* (non-PHPdoc) - * @see WindFilter::postHandle() - */ - public function postHandle($request = null, $response = null) { - if (!IS_DEBUG) return; - $this->logger->info('---------------------------------request end!!!!---------------------------------'); - if ($this->logger instanceof WindLogger) $this->logger->flush(); - } - - /** - * @param WindHttpRequest $request - */ - private function initWindLogger($request) { - $windFactory = $request->getAttribute(WindFrontController::WIND_FACTORY); - $this->logger = $windFactory->getInstance(COMPONENT_LOGGER); - } - -} - -?> \ No newline at end of file diff --git a/wind/core/web/filter/WindUrlFilter.php b/wind/core/web/filter/WindUrlFilter.php index d8a44710..f745c674 100644 --- a/wind/core/web/filter/WindUrlFilter.php +++ b/wind/core/web/filter/WindUrlFilter.php @@ -1,7 +1,4 @@ diff --git a/wind/core/web/listener/WindLoggerListener.php b/wind/core/web/listener/WindLoggerListener.php index ef285b14..824b6a9e 100644 --- a/wind/core/web/listener/WindLoggerListener.php +++ b/wind/core/web/listener/WindLoggerListener.php @@ -1,7 +1,5 @@ @@ -74,7 +72,6 @@ public function preHandle() { private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); - Wind::import('WIND:core.factory.WindFactory'); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } From 5b2eaa5a1052ab7d34e2dd3161c72dbfafc9e893 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 25 Jul 2011 08:05:16 +0000 Subject: [PATCH 0153/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D=EF=BC=8Cconfig?= =?UTF-8?q?=E4=B8=8D=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2213 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/config/WindSystemConfig.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index a782c3d9..38516cd2 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -30,10 +30,10 @@ public function setConfig($config, $factory = null) { $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); $config = $configParser->parse($config, $this->appName . '_config'); } - if (isset($config[$this->appName])) - $this->_config = $config[$this->appName]; + if (isset($config['web-apps'][$this->appName])) + $this->_config = $config['web-apps'][$this->appName]; else - $this->_config = $config; + $this->_config = $config['web-apps']; } /** @@ -185,7 +185,15 @@ public function getModuleControllerPathByModuleName($name, $default = '') { */ public function getModuleControllerSuffixByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('controller-suffix', '', $default, $module); + return $this->getConfig('controller-suffix', 'value', $default, $module); + } + + /** + * 获得缓存数据 + * @param string $type + */ + public function getCacheConfig($type = '') { + return $this->getConfig('cache', $type); } } \ No newline at end of file From 4de3ca67cc67467d39738a2374a1a57cf46460eb Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 25 Jul 2011 08:05:37 +0000 Subject: [PATCH 0154/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D=EF=BC=8Cconfig?= =?UTF-8?q?=E4=B8=8D=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2214 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindModule.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 2dbff82b..abf8d8ea 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -11,7 +11,7 @@ class WindModule { /** * @var array */ - private $_config = array(); + protected $_config = array(); /** * 是否进行类型验证 * @@ -168,14 +168,10 @@ protected function validatePropertyName($propertyName, $value = null) { * @return string|array */ public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { - if (!$config) - $config = $this->_config; - if ($configName === '') - return $config; - if (!isset($config[$configName])) - return $default; - if ($subConfigName === '' || !isset($config[$configName][$subConfigName])) - $config[$configName]; + if (!$config) $config = $this->_config; + if ($configName === '') return $config; + if (!isset($config[$configName])) return $default; + if ($subConfigName === '' || !isset($config[$configName][$subConfigName])) return $config[$configName]; return $config[$configName][$subConfigName]; } From e37fe378dddaa196d7c4f29916222534082b9121 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 09:04:42 +0000 Subject: [PATCH 0155/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2215 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/config/WindSystemConfig.php | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index 38516cd2..de99bf89 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -30,10 +30,10 @@ public function setConfig($config, $factory = null) { $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); $config = $configParser->parse($config, $this->appName . '_config'); } - if (isset($config['web-apps'][$this->appName])) - $this->_config = $config['web-apps'][$this->appName]; - else - $this->_config = $config['web-apps']; + if (isset($config[$this->appName])) { + $this->_config = $config[$this->appName]; + } else + $this->_config = $config; } /** @@ -175,7 +175,7 @@ public function getModuleErrorHandlerByModuleName($name, $default = '') { */ public function getModuleControllerPathByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('path', '', $default, $module); + return $this->getConfig('controller-path', 'value', $default, $module); } /** @@ -187,13 +187,5 @@ public function getModuleControllerSuffixByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); return $this->getConfig('controller-suffix', 'value', $default, $module); } - - /** - * 获得缓存数据 - * @param string $type - */ - public function getCacheConfig($type = '') { - return $this->getConfig('cache', $type); - } } \ No newline at end of file From 08b251dbc389b50d36f71cf89270fe9b4da31b37 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 09:04:50 +0000 Subject: [PATCH 0156/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2216 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindModule.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index abf8d8ea..4d1991e2 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -136,14 +136,16 @@ protected function validatePropertyName($propertyName, $value = null) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, + 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, + 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { @@ -168,10 +170,14 @@ protected function validatePropertyName($propertyName, $value = null) { * @return string|array */ public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { - if (!$config) $config = $this->_config; - if ($configName === '') return $config; - if (!isset($config[$configName])) return $default; - if ($subConfigName === '' || !isset($config[$configName][$subConfigName])) return $config[$configName]; + if (empty($config)) + $config = $this->_config; + if ($configName === '') + return $config; + if (!isset($config[$configName])) + return $default; + if ($subConfigName === '' || !isset($config[$configName][$subConfigName])) + return $config[$configName]; return $config[$configName][$subConfigName]; } @@ -188,9 +194,9 @@ public function setConfig($config) { $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); $config = $configParser->parse($config, get_class($this), 'cache_wind_config'); } - if (!$this->_config) + if (!$this->_config) { $this->_config = array_merge($this->_config, $config); - else + } else $this->_config = $config; } From 395d9ec1a37ce72ddda0c1be53e1e37846e36cc7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 09:05:02 +0000 Subject: [PATCH 0157/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2217 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/router/AbstractWindRouter.php | 5 +++-- wind/core/web/WindErrorMessage.php | 15 ++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/wind/core/router/AbstractWindRouter.php b/wind/core/router/AbstractWindRouter.php index d482d82d..29b90dca 100644 --- a/wind/core/router/AbstractWindRouter.php +++ b/wind/core/router/AbstractWindRouter.php @@ -63,7 +63,7 @@ public function doParse() { $this->reParse = false; } $_moduleName = $this->getModule(); - if (!strcasecmp($this->getController(), WIND_M_ERROR)) { + if (!strcasecmp($this->getController(), 'windError')) { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( '[core.roter.AbstractWindRouter.doParse] action hander: default error action :' . @@ -81,7 +81,8 @@ public function doParse() { self::CONTROLLER_DEFAULT_PATH); } $_path .= '.' . ucfirst($this->controller) . $_suffix; - if (strpos($_path, ':') === false) $_path = Wind::getAppName() . ':' . $_path; + if (strpos($_path, ':') === false) + $_path = Wind::getAppName() . ':' . $_path; if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.router.AbstractWindRouter.doParse] action handler: ' . $_path, WindLogger::LEVEL_DEBUG, 'wind.core'); diff --git a/wind/core/web/WindErrorMessage.php b/wind/core/web/WindErrorMessage.php index 4142c233..39f54154 100644 --- a/wind/core/web/WindErrorMessage.php +++ b/wind/core/web/WindErrorMessage.php @@ -26,7 +26,8 @@ public function __construct($message = '', $errorAction = '', $errorController = * @see IWindErrorMessage::sendError() */ public function sendError() { - if (empty($this->error)) return; + if (empty($this->error)) + return; throw new WindActionException($this); } @@ -51,13 +52,15 @@ public function getError($key = '') { * @see IWindErrorMessage::addError() */ public function addError($error, $key = '') { - if (!$error) return; + if (!$error) + return; if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); - if (is_array($error)) $this->error += $error; + if (is_array($error)) + $this->error += $error; } else $this->error[$key] = $error; } @@ -80,13 +83,15 @@ public function getErrorController() { * @param field_type $errorAction */ public function setErrorAction($errorAction) { - if ($errorAction) $this->errorAction = $errorAction; + if ($errorAction) + $this->errorAction = $errorAction; } /** * @param field_type $errorController */ public function setErrorController($errorController) { - if ($errorController) $this->errorController = $errorController; + if ($errorController) + $this->errorController = $errorController; } } \ No newline at end of file From 967818a07ff109339edd3df89bcbd7db9941a5fc Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 09:05:11 +0000 Subject: [PATCH 0158/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2218 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index eb579f93..136ea1b5 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -242,7 +242,8 @@ public static function getRealDir($dirPath) { * 初始化框架 */ public static function init() { - self::_checkEnvironment(); + if (IS_DEBUG) + self::_checkEnvironment(); self::_setDefaultSystemNamespace(); self::_registerAutoloader(); self::_loadBaseLib(); From f4df478fe51a3f7337d81bd77dd941498d0bd19e Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 09:05:33 +0000 Subject: [PATCH 0159/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2219 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/config/WindSystemConfig.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index de99bf89..2ba4ec04 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -188,4 +188,12 @@ public function getModuleControllerSuffixByModuleName($name, $default = '') { return $this->getConfig('controller-suffix', 'value', $default, $module); } + /** + * 获得缓存数据 + * @param string $type + */ + public function getCacheConfig($type = '') { + return $this->getConfig('cache', $type); + } + } \ No newline at end of file From 0b662c18413da1601164563e568dd3a78aaea4d2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 09:05:49 +0000 Subject: [PATCH 0160/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2220 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 0c918e91..33d7bc35 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -53,7 +53,7 @@ - + From 045407ca1c6ccdd93147537628b0b1807402d252 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 25 Jul 2011 09:06:14 +0000 Subject: [PATCH 0161/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2221 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/wind_config.xml | 94 +++++++++++++---------------- 1 file changed, 42 insertions(+), 52 deletions(-) diff --git a/docs/configtemplate/wind_config.xml b/docs/configtemplate/wind_config.xml index 5860357d..a0e2adfc 100644 --- a/docs/configtemplate/wind_config.xml +++ b/docs/configtemplate/wind_config.xml @@ -1,56 +1,46 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 5d3cc1da011df8b7f60a4d3e370c4869d84a9ded Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 26 Jul 2011 02:53:48 +0000 Subject: [PATCH 0162/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2222 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 19 +----- wind/component/cache/WindCache.php | 49 ++++++++------- wind/component/cache/strategy/WindDbCache.php | 61 +++++++++++++------ .../cache/strategy/WindFileCache.php | 48 ++++++++++----- .../component/cache/strategy/WindMemCache.php | 6 +- 5 files changed, 107 insertions(+), 76 deletions(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index 727994ab..dcb1cadc 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -59,7 +59,7 @@ abstract class AbstractWindCache extends WindModule { * 配置文件中缓存键的前缀名称的定义 * @var string */ - const KEYPREFIX = 'prefix'; + const KEYPREFIX = 'keyPrefix'; /** * 设置缓存,如果key不存在,设置缓存,否则,替换已有key的缓存。 @@ -240,21 +240,6 @@ public function setConfig($config) { parent::setConfig($config); $this->setSecurityCode($this->getConfig(self::SECURITYCODE, '', '')); $this->setKeyPrefix($this->getConfig(self::KEYPREFIX, '', '')); - $this->setExpire($this->getCofnig(self::EXPIRE, '', 0)); - } - - /** - * 获得缓存表相关配置 - * - * @param array $config - * @param string $name - * @param string $subname - * @param string $default - * @return string - */ - protected function getSubConfig($config, $name, $subname = '', $default = '') { - $result = (isset($config[$name])) ? $config[$name] : $default; - if (!$subname || !isset($result[$subname])) return $result; - return isset($result[$subname]) ? $result[$subname] : $default; + $this->setExpire($this->getConfig(self::EXPIRE, '', 0)); } } \ No newline at end of file diff --git a/wind/component/cache/WindCache.php b/wind/component/cache/WindCache.php index 43511fc8..4f2ea155 100644 --- a/wind/component/cache/WindCache.php +++ b/wind/component/cache/WindCache.php @@ -6,9 +6,9 @@ * @license */ -class WindCache { +class WindCache extends WindModule { - private static $caches = array(); + private $caches = array(); const DB = 'db'; const APC = 'apc'; @@ -29,8 +29,8 @@ class WindCache { * @param AbstractWindCacheDependency $denpendency * @return mixed */ - public static function set($type, $key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { - $cache = self::getCache($type); + public function set($type, $key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { + $cache = $this->getCache($type); return $cache->set($key, $value, $expires, $denpendency); } @@ -41,8 +41,8 @@ public static function set($type, $key, $value, $expires = 0, AbstractWindCacheD * @param string $key * @return mixed */ - public static function get($type, $key) { - $cache = self::getCache($type); + public function get($type, $key) { + $cache = $this->getCache($type); return $cache->get($key); } @@ -53,8 +53,8 @@ public static function get($type, $key) { * @param string $key 获取缓存数据的标识,即键 * @return mixed */ - public static function delete($type, $key) { - $cache = self::getCache($type); + public function delete($type, $key) { + $cache = $this->getCache($type); return $cache->delete($key); } @@ -65,8 +65,8 @@ public static function delete($type, $key) { * @param string $keys * @return array */ - public static function batchGet($type, array $keys) { - $cache = self::getCache($type); + public function batchGet($type, array $keys) { + $cache = $this->getCache($type); return $cache->batchGet($keys); } @@ -77,8 +77,8 @@ public static function batchGet($type, array $keys) { * @param array $keys * @return boolean */ - public static function batchDelete($type, array $keys) { - $cache = self::getCache($type); + public function batchDelete($type, array $keys) { + $cache = $this->getCache($type); return $cache->batchDelete($keys); } @@ -88,12 +88,12 @@ public static function batchDelete($type, array $keys) { * @param string $type * @return boolean */ - public static function clear($type = '') { + public function clear($type = '') { if ($type) { - $cache = self::getCache($type); + $cache = $this->getCache($type); return $cache->clear(); } - foreach(self::caches as $key => $cache) { + foreach($this->caches as $key => $cache) { $cache->clear(); } return true; @@ -106,13 +106,16 @@ public static function clear($type = '') { * @param string $type * @return AbstractWindCache */ - private static function getCache($type) { - $type = self::getCacheMap($type); - if (!$type) throw new WindException('The cache strategy \'' . $type . '\' is not exists!'); - if (isset(self::$caches[$type])) return self::$caches[$type]; - $class = Wind::import('WIND:component.cache.strategy.' . $type); - self::$caches[$type] = new $class(); - return self::$caches[$type]; + public function getCache($type) { + $className = $this->getCacheMap($type); + if (!$className) throw new WindException('The cache strategy \'' . $type . '\' is not exists!'); + if (isset($this->caches[$className])) return $this->caches[$className]; + Wind::import('WIND:component.cache.strategy.' . $className); + $cache = new $className(); + $config = $this->getSystemConfig()->getCacheConfig($type); + if ($config) $cache->setConfig($config); + $this->caches[$className] = $cache; + return $cache; } /** @@ -120,7 +123,7 @@ private static function getCache($type) { * * @param string $type */ - private static function getCacheMap($type) { + private function getCacheMap($type) { $types = array(self::DB => 'WindDbCache', self::APC => 'WindApcCache', self::FILE => 'WindFileCache', self::EAC => 'WindEacceleratorCache', self::MEMCACHE => 'WindMemCache', self::WINCACHE => 'WindWinCache', self::XCACHE => 'WindXCache', self::ZEND => 'WindZendCache'); diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index c23dd274..8672aa82 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -12,13 +12,13 @@ class WindDbCache extends AbstractWindCache { * 分布式管理 * @var AbstractWindDbAdapter */ - private $dbHandler; + private $connection; /** * 链接配置信息 * @var array */ - private $dbconfig; + private $dbConfig; /** * 缓存表 @@ -43,23 +43,30 @@ class WindDbCache extends AbstractWindCache { * @var string */ private $expireField = 'expire'; + + /** + * 缓存表过期时间字段 + * @var string + */ + private $connectionConfig = 'default'; /* * 配置项常量定义 */ - const DBCACHE = 'dbCache'; + const DBCACHE = 'config'; const DBCONFIG = 'dbconfig'; - const CACHETABLE = 'cache-table'; + const CACHETABLE = 'cacheTables'; - const TABLENAME = 'table-name'; + const TABLENAME = 'tableName'; - const KEY = 'field-key'; + const KEY = 'fieldKey'; - const VALUE = 'field-value'; + const VALUE = 'fieldValue'; - const EXPIRE = 'field-expire'; + const EXPIRE = 'fieldExpire'; + const CONNECTION = 'connection'; public function __construct(WindConnection $connection = null, $config = array()) { $connection && $this->setConnection($connection); @@ -84,7 +91,7 @@ protected function setValue($key, $value, $expire = 0) { */ protected function getValue($key) { $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; - $data = $this->getConnection()->createStatement($sql)->getOne(array($key), time()); + $data = $this->getConnection()->createStatement($sql)->getOne(array($key, time())); return $data[$this->valueField]; } @@ -134,7 +141,7 @@ public function clear() { * 删除过期数据 */ public function deleteExpiredCache() { - $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->expireField . '`>0 AND `' . $this->expireField . '`<'.time(); + $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->expireField . '`>0 AND `' . $this->expireField . '` <'.time(); return $this->getConnection()->execute($sql); } @@ -143,12 +150,20 @@ public function deleteExpiredCache() { */ public function setConfig($config) { parent::setConfig($config); - $this->dbConfig = $this->getConfig(self::DBCACHE, self::DBCONFIG); $config = $this->getConfig(self::CACHETABLE); - $this->table = $this->getSubConfig($config, self::TABLENAME, '', 'pw_cache'); - $this->keyField = $this->getSubConfig($config, self::KEY, '', 'key'); - $this->valueField = $this->getSubConfig($config, self::VALUE, '', 'value'); - $this->expireField = $this->getSubConfig($config, self::EXPIRE, '', 'expire'); + $this->table = $this->getConfig(self::TABLENAME, '', 'pw_cache', $config); + $this->keyField = $this->getConfig(self::KEY, '', 'key', $config); + $this->valueField = $this->getConfig(self::VALUE, '', 'value', $config); + $this->expireField = $this->getConfig(self::EXPIRE, '', 'expire', $config); + $this->connectionConfig = $this->getConfig(self::CONNECTION, '', 'default', $config); + } + + /** + * 返回表名 + * @return string + */ + private function getTableName() { + return $this->table; } /** @@ -175,9 +190,19 @@ public function setConnection($connection) { */ private function getConnection() { if (null == $this->connection) { - $this->connection = new WindConnection(); - $this->connection->setConfig($this->dbConfig); - $this->connection->init(); + $alias = 'db_' . $this->connectionConfig; + if (!$this->getSystemFactory()->checkAlias($alias)) { + $config = $this->getSystemConfig()->getDbConfig($this->connectionConfig); + $definition = array( + 'path' => $this->getConfig('class', '', 'COM:db.WindConnection', $config), + 'alias' => $alias, + 'config' => $config, + 'initMethod' => 'init', + 'scope' => 'application', + ); + $this->getSystemFactory()->addClassDefinitions($alias, $definition); + } + $this->connection = $this->getSystemFactory()->getInstance($alias); } return $this->connection; } diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 00220cf2..318a33c3 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -15,29 +15,34 @@ class WindFileCache extends AbstractWindCache { * 缓存目录 * @var string */ - protected $cacheDir; + private $cacheDir; /** * 缓存后缀 * @var string */ - protected $cacheFileSuffix = 'txt'; + private $cacheFileSuffix = 'txt'; /** * 缓存多级目录。最好不要超3层目录 * @var int */ - protected $cacheDirectoryLevel = ''; + private $cacheDirectoryLevel = ''; + + /** + * 保存操作的路径信息, 存储使用过的key路径 + * @var array + */ + private $cacheFileList = array(); /* * 配置项 */ - const FILE = 'fileCache'; - const CACHEDIR = 'cache-dir'; + const CACHEDIR = 'dir'; - const SUFFIX = 'cache-suffix'; + const SUFFIX = 'suffix'; - const LEVEL = 'cache-level'; + const LEVEL = 'dirLevel'; /* (non-PHPdoc) * @see AbstractWindCache::setValue() @@ -73,8 +78,9 @@ public function clear($isExpired = false) { * @param string $key * @return string */ - protected function buildSecurityKey($key, $getDir = false) { - $filename = parent::buildSecurityKey($key) . '.' . ltrim($this->getCacheFileSuffix(), '.'); + protected function buildSecurityKey($key) { + if (($dir = $this->checkCacheDir($key)) !== false) return $dir; + $filename = parent::buildSecurityKey($key) . '.' . trim($this->getCacheFileSuffix(), '.'); $_tmp = $this->getCacheDir(); if (0 < $this->getCacheDirectoryLevel()) { for ($i = $this->getCacheDirectoryLevel(); $i > 0; --$i) { @@ -83,7 +89,18 @@ protected function buildSecurityKey($key, $getDir = false) { } } if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); - return $getDir ? $_tmp : $_tmp . $filename; + $this->cacheFileList[$key] = $_tmp . D_S . $filename; + return $_tmp . D_S . $filename; + } + + /** + * 采用最近最少使用原则算法 + * + * @param string $key + * @return string + */ + private function checkCacheDir($key) { + return isset($this->cacheFileList[$key]) ? $this->cacheFileList[$key] : false; } /** @@ -123,7 +140,9 @@ private function readData($file) { * @param string $dir */ public function setCacheDir($dir) { - $this->cacheDir = Wind::getRealPath($dir, true) . DIRECTORY_SEPARATOR; + $this->cacheFileList = array(); + $dir = (false === strpos($dir, ':')) ? Wind::getAppName() . ':' . $dir : $dir; + $this->cacheDir = !is_dir($dir) ? Wind::getRealDir($dir) : $dir; } /** @@ -139,6 +158,7 @@ private function getCacheDir() { * @param string $cacheFileSuffix */ public function setCacheFileSuffix($cacheFileSuffix) { + $this->cacheFileList = array(); $this->cacheFileSuffix = $cacheFileSuffix; } @@ -177,9 +197,9 @@ public function __destruct() { */ public function setConfig($config) { parent::setConfig($config); - $this->setCacheDir($this->getConfig(self::FILE, self::CACHEDIR)); - $this->setCacheFileSuffix($this->getConfig(self::FILE, self::SUFFIX, 'txt')); - $this->setCacheDirectoryLevel($this->getConfig(self::FILE, self::LEVEL)); + $this->setCacheDir($this->getConfig(self::CACHEDIR)); + $this->setCacheFileSuffix($this->getConfig(self::SUFFIX, '', 'txt')); + $this->setCacheDirectoryLevel($this->getConfig(self::LEVEL)); } } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php index 6ad4ee49..1ff18e1a 100644 --- a/wind/component/cache/strategy/WindMemCache.php +++ b/wind/component/cache/strategy/WindMemCache.php @@ -22,8 +22,6 @@ class WindMemCache extends AbstractWindCache { */ protected $compress = 0; - //配置信息 - const MEMCACHE = 'memcache'; /** * 是否对缓存进行压缩,如果缓存的值较大,可进行压缩 * @var int @@ -92,8 +90,8 @@ public function clear() { */ public function setConfig($config) { parent::setConfig($config); - $this->setServers($this->getConfig(self::MEMCACHE, self::SERVERCONFIG)); - $this->compress = $this->getSubConfig($this->getConfig(self::MEMCACHE), self::COMPRESS, '', 0); + $this->compress = $this->getConfig(self::COMPRESS, '', '0'); + $this->setServers($this->getConfig(self::SERVERCONFIG)); } /** From 05fb2f8d823a93a93e39626531a4ca0d59c86cc6 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 26 Jul 2011 03:06:53 +0000 Subject: [PATCH 0163/1065] =?UTF-8?q?DAO=E9=93=BE=E6=8E=A5=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2223 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDao.php | 35 +++++++++------------------ wind/component/dao/WindDaoFactory.php | 29 ++++++++++------------ 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php index 21ff5929..ed9bbb02 100644 --- a/wind/component/dao/WindDao.php +++ b/wind/component/dao/WindDao.php @@ -8,22 +8,11 @@ * @package */ class WindDao extends WindModule { - /** - * db链接类型定义 - * - * @var string - */ - protected $dbClass = 'COM:db.WindConnection'; - /** - * db配置路径定义 - * - * @var string - */ /** * 链接配置文件或是配置数组 * @var string|array */ - protected $dbConfig = ''; + protected $configName = ''; /** * cache类型定义 * @@ -37,7 +26,7 @@ class WindDao extends WindModule { */ protected $cacheConfig = ''; - private $connection = null; + protected $connection = null; private $cacheHandler = null; /** @@ -53,7 +42,12 @@ public function getCacheMethods() { * @return WindConnection */ public function getConnection() { - return $this->_getConnection(); + $connection = $this->_getConnection(); + if ($connection instanceof WindConnection) { + return $connection; + } + if ($connection instanceof WindConnectionManager) + return $connection->getConnection(); } /** @@ -64,17 +58,10 @@ public function getCacheHandler() { } /** - * @return the $dbClass - */ - public function getDbClass() { - return $this->dbClass; - } - - /** - * @return the $dbConfig + * @return the $configName */ - public function getDbConfig() { - return $this->dbConfig; + public function getConfigName() { + return $this->configName; } /** diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index 50e1d905..058b1082 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -97,23 +97,20 @@ private function registerCacheListener($daoInstance) { * @param WindDao $daoObject */ protected function createDbConnection($daoObject) { - if (!($_className = $daoObject->getDbClass())) return; - $_classConfig = $daoObject->getDbConfig(); - $_alias = $_className . '_' . md5((is_string($_classConfig) ? $_classConfig : serialize($_classConfig))); - if (!$this->getSystemFactory()->checkAlias($_alias)) { - $definition = new WindClassDefinition(); - $definition->setPath($_className); - $definition->setAlias($_alias); - $definition->setInitMethod('init'); - $definition->setScope(WindClassDefinition::SCOPE_SINGLETON); - if (is_array($_classConfig)) - $definition->setConfig($_classConfig); - else - $definition->setConfig(array(WindClassDefinition::RESOURCE => $_classConfig)); - - $this->getSystemFactory()->addClassDefinitions($definition); + $configName = $daoObject->getConfigName() ? $daoObject->getConfigName() : 'default'; + $alias = 'db_' . $configName; + if (!$this->getSystemFactory()->checkAlias($alias)) { + $config = $this->getSystemConfig()->getDbConfig($configName); + $definition = array( + 'path' => $this->getConfig('class', '', 'COM:db.WindConnection', $config), + 'alias' => $alias, + 'config' => $config, + 'initMethod' => 'init', + 'scope' => 'application', + ); + $this->getSystemFactory()->addClassDefinitions($alias, $definition); } - $daoObject->setDelayAttributes(array('connection' => array(WindClassDefinition::REF => $_alias))); + $daoObject->setDelayAttributes(array('connection' => array('ref' => $alias))); } /** From 2ded17711c278691abf6de9a8aa307cab66f1147 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 26 Jul 2011 03:07:57 +0000 Subject: [PATCH 0164/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2224 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/config/WindSystemConfig.php | 40 ++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php index 2ba4ec04..cd0fe287 100644 --- a/wind/core/config/WindSystemConfig.php +++ b/wind/core/config/WindSystemConfig.php @@ -189,11 +189,49 @@ public function getModuleControllerSuffixByModuleName($name, $default = '') { } /** - * 获得缓存数据 + * 获得缓存配置 * @param string $type */ public function getCacheConfig($type = '') { + $config = $this->getConfig('cache'); + if (isset($config['resource'])) { + $config = $this->parseResource($config['resource']); + $this->_config['cache'] = $config; + } return $this->getConfig('cache', $type); } + + /** + * 获得DB配置 + * @param string $type + */ + public function getDbConfig($type = '') { + $config = $this->getConfig('db'); + if (isset($config['resource'])) { + $config = $this->parseResource($config['resource']); + $this->_config['db'] = $config; + } + return $this->getConfig('db', $type); + } + + /** + * 解析resource的配置 + * + * @param string $resource + * @return array + */ + private function parseResource($resource) { + $fileName = $resource; + $ext = 'php'; + if (($extPois = strpos($resource, '.')) !== false) { + $fileName = substr($resource, 0, $extPois); + $ext = substr($resource, $extPois + 1); + } + $fileName = (false === strpos($resource, ':')) ? Wind::getAppName() . ':' . $fileName : $fileName; + $filePath = !is_file($resource) ? Wind::getRealPath($fileName, $ext) : $resource; + $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); + $config = $configParser->parse($filePath); + return $config; + } } \ No newline at end of file From 8caaa579d472be447f41530ca7f94e60398ad113 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 08:53:06 +0000 Subject: [PATCH 0165/1065] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20bug=E4=BF=AE=E5=A4=8D,=20=E9=94=99=E8=AF=AF=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2225 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 6 +- .../viewer/errorPage/default_error.htm | 17 +++ wind/core/request/WindHttpRequest.php | 3 +- wind/core/response/WindHttpResponse.php | 41 ++++--- wind/core/web/WindErrorHandler.php | 101 +++++++++--------- wind/core/web/WindWebApplication.php | 2 + wind/core/web/controller/WindController.php | 4 +- .../web/controller/WindSimpleController.php | 3 + 8 files changed, 107 insertions(+), 70 deletions(-) create mode 100644 wind/component/viewer/errorPage/default_error.htm diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 33d7bc35..c049afb9 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -54,7 +54,8 @@ - + +
@@ -77,5 +78,8 @@ + + + diff --git a/wind/component/viewer/errorPage/default_error.htm b/wind/component/viewer/errorPage/default_error.htm new file mode 100644 index 00000000..78dd07e6 --- /dev/null +++ b/wind/component/viewer/errorPage/default_error.htm @@ -0,0 +1,17 @@ + + + + +{@G_PAGE:title} +{@G_PAGE:head} + + +

{$errorHeader}

+

#{$key}. {$error}
+ +

Click here go back!

+

+ + \ No newline at end of file diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php index 0b85eddc..cbc18c41 100644 --- a/wind/core/request/WindHttpRequest.php +++ b/wind/core/request/WindHttpRequest.php @@ -507,8 +507,9 @@ public function getResponse() { if ($this->getIsAjaxRequest()) { $this->_response->addHeader('Content-type', 'text/xml;charset=utf-8'); $this->_response->setIsAjax(true); - } else + } else{ $this->_response->addHeader('Content-type', 'text/html;charset=utf-8'); + } } return $this->_response; } diff --git a/wind/core/response/WindHttpResponse.php b/wind/core/response/WindHttpResponse.php index 977fb52a..34133fc0 100644 --- a/wind/core/response/WindHttpResponse.php +++ b/wind/core/response/WindHttpResponse.php @@ -302,7 +302,8 @@ class WindHttpResponse implements IWindResponse { * @param string $value 响应头的字段取值 */ public function setHeader($name, $value, $replace = false) { - if (!$name || !$value) return; + if (!$name || !$value) + return; $name = $this->_normalizeHeader($name); foreach ($this->_headers as $key => $one) { ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, @@ -317,7 +318,8 @@ public function setHeader($name, $value, $replace = false) { * @param string $value 响应头的字段取值 */ public function addHeader($name, $value, $replace = false) { - if ($name == '' || $value == '') return; + if ($name == '' || $value == '') + return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } @@ -329,19 +331,21 @@ public function addHeader($name, $value, $replace = false) { * @param string $message */ public function setStatus($status, $message = '') { - if (!is_int($status) || $status < 100 || $status > 505) return; + if (!is_int($status) || $status < 100 || $status > 505) + return; $this->_status = (int) $status; } /** - * 设置相应内容 + * 设置响应内容 * * @param string $content * @param string $name */ public function setBody($content, $name = null) { - if (!$content) return; + if (!$content) + return; !$name && $name = 'default'; array_unshift($this->_bodyIndex, $name); $this->_body[$name] = $content; @@ -363,9 +367,11 @@ public function addCookie(Cookie $cookie) { * @param string $message */ public function sendError($status = self::SC_NOT_FOUND, $message = '') { - if (!is_int($status) || $status < 400 || $status > 505) return; + if (!is_int($status) || $status < 400 || $status > 505) + return; $this->setBody($message); $this->setStatus($status); + $this->sendResponse(); } /** @@ -374,7 +380,8 @@ public function sendError($status = self::SC_NOT_FOUND, $message = '') { * @param string $location */ public function sendRedirect($location, $status = 302) { - if (!is_int($status) || $status < 300 || $status > 399) return; + if (!is_int($status) || $status < 300 || $status > 399) + return; $this->addHeader('Location', $location, true); $this->setStatus($status); @@ -389,13 +396,15 @@ public function sendRedirect($location, $status = 302) { public function sendResponse() { $this->sendHeaders(); $this->sendBody(); + exit(); } /** * 发送响应头部信息 */ public function sendHeaders() { - if ($this->isSendedHeader()) return; + if ($this->isSendedHeader()) + return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } @@ -436,8 +445,8 @@ public function getBody($name = false) { */ public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); - if ($throw && $sended) throw new WindException( - __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); + if ($throw && $sended) + throw new WindException(__CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } @@ -496,8 +505,10 @@ public function setIsAjax($_isAjax) { * @return array */ public function getData($key1 = '', $key2 = '') { - if (!$key1) return $this->_data; - if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; + if (!$key1) + return $this->_data; + if (!$key2) + return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } @@ -509,8 +520,10 @@ public function setData($data, $key = '') { $this->_data[$key] = $data; return; } - if (is_object($data)) $data = get_object_vars($data); - if (is_array($data)) $this->_data += $data; + if (is_object($data)) + $data = get_object_vars($data); + if (is_array($data)) + $this->_data += $data; } } \ No newline at end of file diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php index bab45cde..964f1761 100644 --- a/wind/core/web/WindErrorHandler.php +++ b/wind/core/web/WindErrorHandler.php @@ -15,9 +15,9 @@ class WindErrorHandler extends WindController { public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); if ($this->request->getUrlReferer()) - $this->urlReferer = $this->request->getUrlReferer(); + $this->urlReferer = $this->getRequest()->getUrlReferer(); else - $this->urlReferer = $this->request->getBaseUrl(); + $this->urlReferer = $this->getRequest()->getBaseUrl(); return true; } @@ -25,17 +25,12 @@ public function beforeAction($handlerAdapter) { * @see WindAction::run() */ public function run() { - $_tmp = "User Message:\r\n"; - $i = 0; - foreach ($this->error as $key => $value) { - $i++; - $_tmp .= "#$i " . $value . "\r\n"; - } - echo "

User Message: (" . count($this->error) . ")

"; - echo "

" . nl2br($_tmp) . "

"; - echo "Click to go back."; - Wind::log('User Error:', $_tmp); - exit(); + $this->setOutput("User Error Message: " . $this->error[0], "errorHeader"); + $this->setOutput('', "errorTrace"); + $this->setOutput($this->urlReferer, "baseUrl"); + $this->setOutput($this->error, "errors"); + $this->setTemplate('default_error'); + $this->setTemplatePath('COM:viewer.errorPage'); } /** @@ -46,25 +41,48 @@ public function run() { */ final public function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { - $errfile = $this->getFile($errfile); - $_tmp = "$errstr ($errfile:$errline)\r\nStack trace:\r\n"; - $_trace = debug_backtrace(); - foreach ($_trace as $key => $value) { - if (!isset($value['file'])) continue; - if (!isset($value['line'])) $value['line'] = 0; - if (!isset($value['function'])) continue; - $_tmp .= "#$key {$value['file']}({$value['line']}): "; - if (isset($value['object']) && is_object($value['object'])) $_tmp .= get_class($value['object']) . '->'; - $_tmp .= "{$value['function']}()\r\n"; - } + $header = $message = $trace = ''; + $header = $errstr; if (IS_DEBUG) { - echo "

" . $this->errnoMap($errno) . " $errstr

"; - echo "

" . nl2br($_tmp) . "

"; - } else - echo "

" . $this->errnoMap($errno) . " $errstr

"; - Wind::log($this->errnoMap($errno) . $errstr, $_tmp); - exit(); + $message = $errstr . '(' . $errfile . ' : ' . $errline . ')'; + $_trace = debug_backtrace(); + foreach ($_trace as $key => $value) { + if (!isset($value['file']) || !isset($value['line']) || !isset($value['function'])) + continue; + $trace .= "#$key {$value['file']}({$value['line']}): "; + if (isset($value['object']) && is_object($value['object'])) + $trace .= get_class($value['object']) . '->'; + $trace .= "{$value['function']}()\r\n"; + } + } + $this->buildMessage($header, $message, $trace); + } + } + + /** + * 异常处理句柄 + * @param Exception $exception + */ + final public function exceptionHandle($exception) { + $header = $message = $trace = ''; + $header = $exception->getMessage(); + if (IS_DEBUG) { + $message = $exception->getMessage() . '(' . $exception->getFile() . ' : ' . $exception->getLine() . ')'; + $trace = $exception->getTraceAsString(); } + $this->buildMessage($header, $message, $trace); + } + + /** + * @param string $header + * @param string $message + * @param string $trace + */ + public function buildMessage($header, $message = '', $trace = '') { + $_tmp = "

$header

"; + $_tmp .= "

$message

"; + $_tmp .= "
$trace
"; + $this->getResponse()->sendError(500, $_tmp); } /** @@ -119,25 +137,4 @@ private function errnoMap($errno) { return $_tmp; } - /** - * 异常处理句柄 - */ - final public function exceptionHandle($exception) { - $_tmp = $exception->getMessage() . ' (' . $this->getFile($exception->getFile()) . ':' . $exception->getLine() . - ')'; - if (IS_DEBUG) { - echo '

' . get_class($exception) . '

'; - echo "

$_tmp

"; - echo '
' . $exception->getTraceAsString() . '
'; - } else { - echo '

' . get_class($exception) . '

'; - echo '

' . $exception->getMessage() . '

'; - } - Wind::log("$_tmp:" . $exception->getTraceAsString()); - exit(); - } - - private function getFile($filePath) { - return $filePath; - } - } \ No newline at end of file +} \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index cdf5b580..9c3e5780 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -31,8 +31,10 @@ public function processRequest() { } catch (WindActionException $actionException) { $this->sendErrorMessage($actionException); } catch (WindDbException $dbException) { + //TODO $this->sendErrorMessage($dbException->getMessage()); } catch (WindViewException $viewException) { + //TODO $this->sendErrorMessage($viewException->getMessage()); } } diff --git a/wind/core/web/controller/WindController.php b/wind/core/web/controller/WindController.php index 3ccdf69e..aaeaf094 100644 --- a/wind/core/web/controller/WindController.php +++ b/wind/core/web/controller/WindController.php @@ -44,9 +44,9 @@ final public function preAction($handlerAdapter) { /* (non-PHPdoc) * @see WindAction::setDefaultTemplateName() */ - protected function setDefaultTemplateName($handlerAdapter) { + protected function setDefaultTemplateName($handlerAdapter) { /* $_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); - $this->setTemplate($_temp); + $this->setTemplate($_temp);*/ } /* (non-PHPdoc) diff --git a/wind/core/web/controller/WindSimpleController.php b/wind/core/web/controller/WindSimpleController.php index 179099e9..fa07c217 100644 --- a/wind/core/web/controller/WindSimpleController.php +++ b/wind/core/web/controller/WindSimpleController.php @@ -1,6 +1,7 @@ * @author Qiong Wu * @version $Id$ @@ -192,6 +193,7 @@ protected function showMessage($message = '', $key = '', $errorAction = '', $err /** * 设置默认的模板名称 + * * @param WindUrlBasedRouter $handlerAdapter * @return */ @@ -199,6 +201,7 @@ protected function setDefaultTemplateName($handlerAdapter) {} /** * 定义了一种解析策略,使其通过解析请求信息来获得调用的方法。 + * * @param WindUrlBasedRouter $handlerAdapter * @return */ From b69b42e1316d7b949a1876bdd89b044f06bbb0b9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:04:12 +0000 Subject: [PATCH 0166/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2226 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/filter/WindFilter.php | 24 + wind/component/filter/WindFilterChain.php | 64 ++ .../filter/WindHandlerInterceptor.php | 50 ++ .../filter/WindHandlerInterceptorChain.php | 76 ++ wind/component/http/request/IWindRequest.php | 25 + .../http/request/WindHttpRequest.php | 647 ++++++++++++++++++ .../component/http/response/IWindResponse.php | 11 + .../http/response/WindHttpResponse.php | 529 ++++++++++++++ wind/component/parser/IWindConfigParser.php | 26 + wind/component/parser/WindConfigParser.php | 209 ++++++ wind/component/router/AbstractWindRouter.php | 173 +++++ wind/component/router/WindUrlBasedRouter.php | 62 ++ 12 files changed, 1896 insertions(+) create mode 100644 wind/component/filter/WindFilter.php create mode 100644 wind/component/filter/WindFilterChain.php create mode 100644 wind/component/filter/WindHandlerInterceptor.php create mode 100644 wind/component/filter/WindHandlerInterceptorChain.php create mode 100644 wind/component/http/request/IWindRequest.php create mode 100644 wind/component/http/request/WindHttpRequest.php create mode 100644 wind/component/http/response/IWindResponse.php create mode 100644 wind/component/http/response/WindHttpResponse.php create mode 100644 wind/component/parser/IWindConfigParser.php create mode 100644 wind/component/parser/WindConfigParser.php create mode 100644 wind/component/router/AbstractWindRouter.php create mode 100644 wind/component/router/WindUrlBasedRouter.php diff --git a/wind/component/filter/WindFilter.php b/wind/component/filter/WindFilter.php new file mode 100644 index 00000000..d2b15fae --- /dev/null +++ b/wind/component/filter/WindFilter.php @@ -0,0 +1,24 @@ + + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindFilter extends WindHandlerInterceptor { + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + + } + +} \ No newline at end of file diff --git a/wind/component/filter/WindFilterChain.php b/wind/component/filter/WindFilterChain.php new file mode 100644 index 00000000..989519b1 --- /dev/null +++ b/wind/component/filter/WindFilterChain.php @@ -0,0 +1,64 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFilterChain extends WindHandlerInterceptorChain { + + /** + * @param array $filterConfig + */ + public function __construct($filterConfig) { + $this->_initFilters($filterConfig); + } + + /** + * @param string $filterName + */ + public function deleteFilter($alias) { + unset($this->_interceptors[$alias]); + } + + /** + * 在filter链中动态的添加一个filter + * 当befor为空时,添加到程序结尾处 + * 如果befor有值,则遍历数组,找到befor的位置,将新的过滤器添加到befor后面, + * 并将所有原befor位置后的过滤器往后移一位 + * + * @param string $filterName + * @param string $path + * @param string $beforFilter + */ + public function addFilter($filter, $beforFilter = '') { + if ($beforFilter === '') { + $this->addInterceptors(array(get_class($filter) => $filter)); + return true; + } + $_interceptors = array(); + foreach ($this->_interceptors as $key => $interceptor) { + if ($beforFilter === $key) break; + $_interceptors[$key] = $interceptor; + unset($this->_interceptors[$key]); + } + $_interceptors[get_class($filter)] = $filter; + $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; + } + + /** + * Enter description here ... + * @param array $filters + */ + private function _initFilters($filters = array()) { + $_temp = array(); + foreach ((array) $filters as $key => $filter) { + if (!is_array($filter)) continue; + $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); + if (!class_exists($filterClass)) continue; + $_temp[$key] = new $filterClass(); + } + $this->addInterceptors($_temp); + } + +} \ No newline at end of file diff --git a/wind/component/filter/WindHandlerInterceptor.php b/wind/component/filter/WindHandlerInterceptor.php new file mode 100644 index 00000000..c6ca0890 --- /dev/null +++ b/wind/component/filter/WindHandlerInterceptor.php @@ -0,0 +1,50 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHandlerInterceptor extends WindModule { + protected $result = null; + protected $interceptorChain = null; + + /** + * Enter description here ... + */ + public function preHandle() {} + + /** + * Enter description here ... + */ + public function postHandle() {} + + /** + * Enter description here ... + * @return mixed + */ + public function handle() { + $args = func_get_args(); + $this->result = call_user_func_array(array($this, 'preHandle'), $args); + if ($this->result !== null) { + return $this->result; + } + if (null !== ($handler = $this->interceptorChain->getHandler())) { + $this->result = call_user_func_array(array($handler, 'handle'), $args); + } else { + $this->result = $this->interceptorChain->execute(); + } + call_user_func_array(array($this, 'postHandle'), $args); + return $this->result; + } + + /** + * 设置过滤链对象 + * + * @param WindHandlerInterceptorChain $interceptorChain + */ + public function setHandlerInterceptorChain($interceptorChain) { + $this->interceptorChain = $interceptorChain; + } +} +?> \ No newline at end of file diff --git a/wind/component/filter/WindHandlerInterceptorChain.php b/wind/component/filter/WindHandlerInterceptorChain.php new file mode 100644 index 00000000..55ec188d --- /dev/null +++ b/wind/component/filter/WindHandlerInterceptorChain.php @@ -0,0 +1,76 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHandlerInterceptorChain extends WindModule { + protected $_interceptors = array(); + protected $_callBack = null; + protected $_args = array(); + private $_state = true; + + /** + * 设置回调方法 + * + * @param string|array $callBack + * @param array $args + * @return + */ + public function setCallBack($callBack, $args = array()) { + $this->_callBack = $callBack; + $this->_args = $args; + } + + /** + * 执行callback方法 + * + * @throws WindException + * @return void|mixed + */ + public function execute() { + if ($this->_callBack === null) return null; + if (is_string($this->_callBack) && !function_exists($this->_callBack)) { + throw new WindException('[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, + WindException::ERROR_FUNCTION_NOT_EXIST); + } + return call_user_func_array($this->_callBack, (array) $this->_args); + } + + /** + * 返回处理句柄 + * + * @return WindHandlerInterceptor + */ + public function getHandler() { + if ($this->_state) { + $this->addInterceptors(new WindHandlerInterceptor()); + $this->_state = false; + } + if (count($this->_interceptors) <= 0) return null; + $handler = array_shift($this->_interceptors); + if ($handler instanceof WindHandlerInterceptor) { + $handler->setHandlerInterceptorChain($this); + return $handler; + } + Wind::log( + '[core.filter.WindHandlerInterceptorChain.getHandler] the type of Interceptor ' . gettype($handler) . + ' is not supported.', WindLogger::LEVEL_DEBUG, 'wind.core'); + return $this->getHandler(); + } + + /** + * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 + * + * @param $interceptors + * @return + */ + public function addInterceptors($interceptors) { + if (is_array($interceptors)) + $this->_interceptors += $interceptors; + else + $this->_interceptors[] = $interceptors; + } +} +?> \ No newline at end of file diff --git a/wind/component/http/request/IWindRequest.php b/wind/component/http/request/IWindRequest.php new file mode 100644 index 00000000..aa657cbf --- /dev/null +++ b/wind/component/http/request/IWindRequest.php @@ -0,0 +1,25 @@ + 2010-11-3 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 处理请求抽象基类 + * 如http请求 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindRequest { + const INPUT_TYPE_GET = 'get'; + const INPUT_TYPE_POST = 'post'; + const INPUT_TYPE_COOKIE = 'cookie'; +} + + + + diff --git a/wind/component/http/request/WindHttpRequest.php b/wind/component/http/request/WindHttpRequest.php new file mode 100644 index 00000000..cbc18c41 --- /dev/null +++ b/wind/component/http/request/WindHttpRequest.php @@ -0,0 +1,647 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHttpRequest implements IWindRequest { + /** + * 访问的端口号 + * @var int + */ + private $_port = null; + /** + * 客户端IP + * @var string + */ + private $_clientIp = null; + /** + * 语言信息 + * @var string + */ + private $_language = null; + /** + * 路径信息 + * @var string + */ + private $_pathInfo = null; + /** + * @var string + */ + private $_scriptUrl = null; + /** + * @var string + */ + private $_requestUri = null; + /** + * 基础路径信息 + * @var string + */ + private $_baseUrl = null; + private $_hostInfo = null; + /** + * 请求参数信息 + * @var array + */ + private $_attribute = array(); + /** + * @var WindHttpResponse + */ + private $_response = null; + + public function __construct() { + $this->normalizeRequest(); + } + + protected function normalizeRequest() { + if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { + if (isset($_GET)) $_GET = $this->stripSlashes($_GET); + if (isset($_POST)) $_POST = $this->stripSlashes($_POST); + if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); + if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); + } + } + + public function stripSlashes(&$data) { + return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes($data); + } + + /** + * 设置属性数据 + * + * @param string|array|object $data + * @param string $key + * @return + */ + public function setAttribute($data, $key = '') { + if ($key) { + $this->_attribute[$key] = $data; + return; + } + if (is_object($data)) $data = get_object_vars($data); + if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); + } + + /** + * 根据名称获得服务器和执行环境信息 + * + * @param string|null $name + * @return string|object|array| + */ + public function getAttribute($key, $defaultValue = '') { + if (isset($this->_attribute[$key])) + return $this->_attribute[$key]; + else if (isset($_GET[$key])) + return $_GET[$key]; + else if (isset($_POST[$key])) + return $_POST[$key]; + else if (isset($_COOKIE[$key])) + return $_COOKIE[$key]; + else if (isset($_REQUEST[$key])) + return $_REQUEST[$key]; + else if (isset($_ENV[$key])) + return $_ENV[$key]; + else if (isset($_SERVER[$key])) + return $_SERVER[$key]; + else + return $defaultValue; + } + + /** + * 返回$_GET,$_POST的值,未设置则返回default + * @param string $name | attribute name + */ + public function getRequest($key = null, $defaultValue = null) { + if (!$key) return array_merge($_POST, $_GET); + if (isset($_GET[$key])) return $_GET[$key]; + if (isset($_POST[$key])) return $_POST[$key]; + return $defaultValue; + } + + /** + * 从query中取值 + * + * @param string $name + * @param string $default + * @return string|null + */ + public function getQuery($name = null, $defaultValue = null) { + return $this->getGet($name, $defaultValue); + } + + /** + * 获得post值 + * + * @param string $name + * @param string $defaultValue + * @return string|null + */ + public function getPost($name = null, $defaultValue = null) { + if ($name == null) return $_POST; + return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; + } + + /** + * 获得get值 + * + * @param string $name + * @param string $defaultValue + * @return string|null + */ + public function getGet($name = '', $defaultValue = null) { + if ($name == null) return $_GET; + return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; + } + + /** + * 返回cookie的值,如果$name=null则返回所有Cookie值 + * + * @param string $key + * @param string $defaultValue + * @return string|null|array + */ + public function getCookie($name = null, $defaultValue = null) { + if ($name == null) return $_COOKIE; + return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; + } + + /** + * 返回session的值,如果$name=null则返回所有Cookie值 + * + * @param string $key + * @param string $defaultValue + * @return string|null|array + */ + public function getSession($name = null, $defaultValue = null) { + if ($name == null) return $_SESSION; + return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; + } + + /** + * 返回Server的值,如果$name为空则返回所有Server的值 + * + * @param string $name + * @param string $defaultValue + * @return string|null|array + */ + public function getServer($name = null, $defaultValue = null) { + if ($name == null) return $_SERVER; + return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; + } + + /** + * 返回env中的值,如果$name为null则返回所有env的值 + * + * @param string|null $name + * @param string $defaultValue + * @return string|null|array + */ + public function getEnv($name = null, $defaultValue = null) { + if ($name == null) return $_ENV; + return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; + } + + /** + * 获取协议名称 + * + * @return string + */ + public function getScheme() { + return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; + } + + /** + * 返回请求页面时通信协议的名称和版本 + * @return string + */ + public function getProtocol() { + return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); + } + + /** + * 返回访问IP + * + * @return string|0.0.0.0 + */ + public function getClientIp() { + if (!$this->_clientIp) $this->_getClientIp(); + return $this->_clientIp; + } + + /** + * 获得请求的方法 + */ + public function getRequestMethod() { + return strtoupper($this->getServer('REQUEST_METHOD')); + } + + /** + * 获得请求类型 + * + * @return string + */ + public function getRequestType() { + return IWindRequest::REQUEST_TYPE_WEB; + } + + /** + * 返回该请求是否为ajax请求 + * @return Boolean + */ + public function getIsAjaxRequest() { + return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); + } + + /** + * Returns a boolean indicating whether this request was made using a + * secure channel, such as HTTPS. + * @return Boolean + */ + public function isSecure() { + return !strcasecmp($this->getServer('HTTPS'), 'on'); + } + + /** + * 返回请求是否为GET请求类型 + * @return boolean + */ + public function isGet() { + return !strcasecmp($this->getRequestMethod(), 'GET'); + } + + /** + * 返回请求是否为POST请求类型 + * @return boolean + */ + public function isPost() { + return !strcasecmp($this->getRequestMethod(), 'POST'); + } + + /** + * 返回请求是否为PUT请求类型 + * @return boolean + */ + public function isPut() { + return !strcasecmp($this->getRequestMethod(), 'PUT'); + } + + /** + * 返回请求是否为DELETE请求类型 + * @return boolean + */ + public function isDelete() { + return !strcasecmp($this->getRequestMethod(), 'Delete'); + } + + /** + * 初始化请求的资源标识符 + * 这里的uri是去除协议名、主机名的 + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_requestUri = /example/index.php?a=test + * + * @return string + */ + public function getRequestUri() { + if (!$this->_requestUri) $this->initRequestUri(); + return $this->_requestUri; + } + + /** + * 返回当前执行脚本的绝对路径 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_scriptUrl = /example/index.php + * + * @throws WindException + * @return string + */ + public function getScriptUrl() { + if (!$this->_scriptUrl) $this->_initScriptUrl(); + return $this->_scriptUrl; + } + + /** + * 返回执行脚本 + */ + public function getScript() { + if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; + return substr($this->getScriptUrl(), $pos + 1); + } + + /** + * 获取Http头信息 + * @param string $header 头部名称 + * @return string|null + */ + public function getHeader($header, $default = null) { + $temp = strtoupper(str_replace('-', '_', $header)); + if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; + if (($header = $this->getServer($temp)) != null) return $header; + if (function_exists('apache_request_headers')) { + $headers = apache_request_headers(); + if ($headers[$header]) return $headers[$header]; + } + return $default; + } + + /** + * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 + * + * @throws WindException + * @return string + */ + public function getPathInfo() { + if (!$this->_pathInfo) $this->_initPathInfo(); + return $this->_pathInfo; + } + + /** + * 获取基础URL,这里是去除了脚本文件以及访问参数信息的URL地址信息 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_baseUrl = example + * return absolute url address when absolute is true + * 'example' will be return when absolute is false + * 'http://www.phpwind.net/example' will be return when absolute is true + * 'http://www.phpwind.net:80/example' will be return when absolute is true + * 'http://www.phpwind.net:443/example' will be return when absolute is true + * + * @param boolean $absolute + * @return string + */ + public function getBaseUrl($absolute = false) { + if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); + return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; + } + + /** + * 获得主机信息,包含协议信息,主机名,访问端口信息 + * + * @return string + */ + public function getHostInfo() { + if ($this->_hostInfo === null) $this->_initHostInfo(); + return $this->_hostInfo; + } + + /** + * 返回当前运行脚本所在的服务器的主机名。 + * 如果脚本运行于虚拟主机中 + * 该名称是由那个虚拟主机所设置的值决定 + * + * @return string|'' + */ + public function getServerName() { + return $this->getServer('SERVER_NAME', ''); + } + + /** + * 返回服务端口号 + * https链接的默认端口号为443 + * http链接的默认端口号为80 + * + * @return int + */ + public function getServerPort() { + if (!$this->_port) { + $_default = $this->isSecure() ? 443 : 80; + $this->setServerPort($this->getServer('SERVER_PORT', $_default)); + } + return $this->_port; + } + + /** + * 设置服务端口号 + * https链接的默认端口号为443 + * http链接的默认端口号为80 + * + * @param int $port + */ + public function setServerPort($port) { + $this->_port = (int) $port; + } + + /** + * 返回浏览当前页面的用户的主机名 + * DNS 反向解析不依赖于用户的 REMOTE_ADDR + * + * @return string|null + */ + public function getRemoteHost() { + return $this->getServer('REMOTE_HOST'); + } + + /** + * 返回浏览器发送Referer请求头,可以让服务器了解和追踪发出本次请求的起源URL地址 + * + * @return string|null + */ + public function getUrlReferer() { + return $this->getServer('HTTP_REFERER'); + } + + /** + * 获得用户机器上连接到 Web 服务器所使用的端口号 + * + * @return number|null + */ + public function getRemotePort() { + return $this->getServer('REMOTE_PORT'); + } + + /** + * 返回User-Agent头字段用于指定浏览器或者其他客户端程序的类型和名字 + * 如果客户机是一种无线手持终端,就返回一个WML文件;如果发现客户端是一种普通浏览器, + * 则返回通常的HTML文件 + * + * @return string + */ + public function getUserAgent() { + return $this->getServer('HTTP_USER_AGENT', ''); + } + + /** + * 返回当前请求头中 Accept: 项的内容, + * Accept头字段用于指出客户端程序能够处理的MIME类型,例如 text/html,image/* + * + * @return string|'' + */ + public function getAcceptTypes() { + return $this->getServer('HTTP_ACCEPT', ''); + } + + /** + * 返回客户端程序可以能够进行解码的数据编码方式,这里的编码方式通常指某种压缩方式 + * + * @return string|'' + */ + public function getAcceptCharset() { + return $this->getServer('HTTP_ACCEPT_ENCODING', ''); + } + + /** + * 返回客户端程序期望服务器返回哪个国家的语言文档 + * Accept-Language: en-us,zh-cn + * + * @return string + */ + public function getAcceptLanguage() { + if (!$this->_language) { + $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); + $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; + } + return $this->_language; + } + + /** + * 获得返回信息 + * @return WindHttpResponse + */ + public function getResponse() { + if ($this->_response === null) { + $this->_response = new WindHttpResponse(); + if ($this->getIsAjaxRequest()) { + $this->_response->addHeader('Content-type', 'text/xml;charset=utf-8'); + $this->_response->setIsAjax(true); + } else{ + $this->_response->addHeader('Content-type', 'text/html;charset=utf-8'); + } + } + return $this->_response; + } + + /** + * 返回访问的IP地址 + * + * Example: + * $this->_clientIp = 127.0.0.1 + * + * @return string + */ + private function _getClientIp() { + if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { + $this->_clientIp = $ip; + } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { + $ip = strtok($_ip, ','); + do { + $ip = ip2long($ip); + if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || + (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || + (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { + $this->_clientIp = long2ip($ip); + return; + } + } while (($ip = strtok(','))); + } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { + $this->_clientIp = $ip; + } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { + $this->_clientIp = $ip; + } else { + $this->_clientIp = "0.0.0.0"; + } + } + + /** + * 初始化请求的资源标识符 + * 这里的uri是去除协议名、主机名的 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_requestUri = /example/index.php?a=test + * + * @throws WindException + */ + private function initRequestUri() { + if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { + $this->_requestUri = $requestUri; + } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { + $this->_requestUri = $requestUri; + if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace( + '/^\w+:\/\/[^\/]+/', '', $this->_requestUri); + } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { + $this->_requestUri = $requestUri; + if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; + } else + throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); + } + + /** + * 初始化当前执行脚本的绝对路径 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_scriptUrl = /example/index.php + * + * @throws WindException + * @return + */ + private function _initScriptUrl() { + if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException( + __CLASS__ . ' determine the entry script URL failed!!!'); + $scriptName = basename($scriptName); + if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && + basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { + $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; + } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && + ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && + strpos($_scriptName, $_documentRoot) === 0) { + $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } + + /** + * 获得主机信息,包含协议信息,主机名,访问端口信息 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_hostInfo = http://www.phpwind.net/ + * $this->_hostInfo = http://www.phpwind.net:80/ + * $this->_hostInfo = https://www.phpwind.net:443/ + * + * @throws WindException + * @return + */ + private function _initHostInfo() { + $http = $this->isSecure() ? 'https' : 'http'; + if (($httpHost = $this->getServer('HTTP_HOST')) != null) + $this->_hostInfo = $http . '://' . $httpHost; + elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { + $this->_hostInfo = $http . '://' . $httpHost; + if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } + + /** + * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 + * + * @throws WindException + * @return + */ + private function _initPathInfo() { + $requestUri = urldecode($this->getRequestUri()); + $scriptUrl = $this->getScriptUrl(); + $baseUrl = $this->getBaseUrl(); + if (strpos($requestUri, $scriptUrl) === 0) + $pathInfo = substr($requestUri, strlen($scriptUrl)); + elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) + $pathInfo = substr($requestUri, strlen($baseUrl)); + elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) + $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); + else + throw new WindException(''); + if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); + $this->_pathInfo = trim($pathInfo, '/'); + } + } \ No newline at end of file diff --git a/wind/component/http/response/IWindResponse.php b/wind/component/http/response/IWindResponse.php new file mode 100644 index 00000000..0c437993 --- /dev/null +++ b/wind/component/http/response/IWindResponse.php @@ -0,0 +1,11 @@ + 2010-11-7 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +interface IWindResponse { + +} \ No newline at end of file diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php new file mode 100644 index 00000000..34133fc0 --- /dev/null +++ b/wind/component/http/response/WindHttpResponse.php @@ -0,0 +1,529 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHttpResponse implements IWindResponse { + + private $_body = array(); + + private $_bodyIndex = array(); + + private $_headers = array(); + + private $_isRedirect = false; + + private $_status = ''; + + private $_isAjax = false; + + private $_data = array(); + + /* + * Server status codes; see RFC 2068. + * Status code (100) indicating the client can continue. + */ + const SC_CONTINUE = 100; + + /** + * Status code (101) indicating the server is switching protocols + * according to Upgrade header. + */ + const SC_SWITCHING_PROTOCOLS = 101; + + /** + * Status code (200) indicating the request succeeded normally. + */ + const SC_OK = 200; + + /** + * Status code (201) indicating the request succeeded and created + * a new resource on the server. + */ + const SC_CREATED = 201; + + /** + * Status code (202) indicating that a request was accepted for + * processing, but was not completed. + */ + const SC_ACCEPTED = 202; + + /** + * Status code (203) indicating that the meta information presented + * by the client did not originate from the server. + */ + const SC_NON_AUTHORITATIVE_INFORMATION = 203; + + /** + * Status code (204) indicating that the request succeeded but that + * there was no new information to return. + */ + const SC_NO_CONTENT = 204; + + /** + * Status code (205) indicating that the agent SHOULD reset + * the document view which caused the request to be sent. + */ + const SC_RESET_CONTENT = 205; + + /** + * Status code (206) indicating that the server has fulfilled + * the partial GET request for the resource. + */ + const SC_PARTIAL_CONTENT = 206; + + /** + * Status code (300) indicating that the requested resource + * corresponds to any one of a set of representations, each with + * its own specific location. + */ + const SC_MULTIPLE_CHOICES = 300; + + /** + * Status code (301) indicating that the resource has permanently + * moved to a new location, and that future references should use a + * new URI with their requests. + */ + const SC_MOVED_PERMANENTLY = 301; + + /** + * Status code (302) indicating that the resource has temporarily + * moved to another location, but that future references should + * still use the original URI to access the resource. + * + * This definition is being retained for backwards compatibility. + * SC_FOUND is now the preferred definition. + */ + const SC_MOVED_TEMPORARILY = 302; + + /** + * Status code (302) indicating that the resource reside + * temporarily under a different URI. Since the redirection might + * be altered on occasion, the client should continue to use the + * Request-URI for future requests.(HTTP/1.1) To represent the + * status code (302), it is recommended to use this variable. + */ + const SC_FOUND = 302; + + /** + * Status code (303) indicating that the response to the request + * can be found under a different URI. + */ + const SC_SEE_OTHER = 303; + + /** + * Status code (304) indicating that a conditional GET operation + * found that the resource was available and not modified. + */ + const SC_NOT_MODIFIED = 304; + + /** + * Status code (305) indicating that the requested resource + * MUST be accessed through the proxy given by the + * Location field. + */ + const SC_USE_PROXY = 305; + + /** + * Status code (307) indicating that the requested resource + * resides temporarily under a different URI. The temporary URI + * SHOULD be given by the Location + * field in the response. + */ + const SC_TEMPORARY_REDIRECT = 307; + + /** + * Status code (400) indicating the request sent by the client was + * syntactically incorrect. + */ + const SC_BAD_REQUEST = 400; + + /** + * Status code (401) indicating that the request requires HTTP + * authentication. + */ + const SC_UNAUTHORIZED = 401; + + /** + * Status code (402) reserved for future use. + */ + const SC_PAYMENT_REQUIRED = 402; + + /** + * Status code (403) indicating the server understood the request + * but refused to fulfill it. + */ + const SC_FORBIDDEN = 403; + + /** + * Status code (404) indicating that the requested resource is not + * available. + */ + const SC_NOT_FOUND = 404; + + /** + * Status code (405) indicating that the method specified in the + * Request-Line is not allowed for the resource + * identified by the Request-URI. + */ + const SC_METHOD_NOT_ALLOWED = 405; + + /** + * Status code (406) indicating that the resource identified by the + * request is only capable of generating response entities which have + * content characteristics not acceptable according to the accept + * headers sent in the request. + */ + const SC_NOT_ACCEPTABLE = 406; + + /** + * Status code (407) indicating that the client MUST first + * authenticate itself with the proxy. + */ + const SC_PROXY_AUTHENTICATION_REQUIRED = 407; + + /** + * Status code (408) indicating that the client did not produce a + * request within the time that the server was prepared to wait. + */ + const SC_REQUEST_TIMEOUT = 408; + + /** + * Status code (409) indicating that the request could not be + * completed due to a conflict with the current state of the + * resource. + */ + const SC_CONFLICT = 409; + + /** + * Status code (410) indicating that the resource is no longer + * available at the server and no forwarding address is known. + * This condition SHOULD be considered permanent. + */ + const SC_GONE = 410; + + /** + * Status code (411) indicating that the request cannot be handled + * without a defined Content-Length. + */ + const SC_LENGTH_REQUIRED = 411; + + /** + * Status code (412) indicating that the precondition given in one + * or more of the request-header fields evaluated to false when it + * was tested on the server. + */ + const SC_PRECONDITION_FAILED = 412; + + /** + * Status code (413) indicating that the server is refusing to process + * the request because the request entity is larger than the server is + * willing or able to process. + */ + const SC_REQUEST_ENTITY_TOO_LARGE = 413; + + /** + * Status code (414) indicating that the server is refusing to service + * the request because the Request-URI is longer + * than the server is willing to interpret. + */ + const SC_REQUEST_URI_TOO_LONG = 414; + + /** + * Status code (415) indicating that the server is refusing to service + * the request because the entity of the request is in a format not + * supported by the requested resource for the requested method. + */ + const SC_UNSUPPORTED_MEDIA_TYPE = 415; + + /** + * Status code (416) indicating that the server cannot serve the + * requested byte range. + */ + const SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + + /** + * Status code (417) indicating that the server could not meet the + * expectation given in the Expect request header. + */ + const SC_EXPECTATION_FAILED = 417; + + /** + * Status code (500) indicating an error inside the HTTP server + * which prevented it from fulfilling the request. + */ + const SC_INTERNAL_SERVER_ERROR = 500; + + /** + * Status code (501) indicating the HTTP server does not support + * the functionality needed to fulfill the request. + */ + const SC_NOT_IMPLEMENTED = 501; + + /** + * Status code (502) indicating that the HTTP server received an + * invalid response from a server it consulted when acting as a + * proxy or gateway. + */ + const SC_BAD_GATEWAY = 502; + + /** + * Status code (503) indicating that the HTTP server is + * temporarily overloaded, and unable to handle the request. + */ + const SC_SERVICE_UNAVAILABLE = 503; + + /** + * Status code (504) indicating that the server did not receive + * a timely response from the upstream server while acting as + * a gateway or proxy. + */ + const SC_GATEWAY_TIMEOUT = 504; + + /** + * Status code (505) indicating that the server does not support + * or refuses to support the HTTP protocol version that was used + * in the request message. + */ + const SC_HTTP_VERSION_NOT_SUPPORTED = 505; + + /** + * 设置响应头信息,如果已经设置过同名的响应头,该方法将用新的设置取代原来的头字段 + * + * @param string $name 响应头的名称 + * @param string $value 响应头的字段取值 + */ + public function setHeader($name, $value, $replace = false) { + if (!$name || !$value) + return; + $name = $this->_normalizeHeader($name); + foreach ($this->_headers as $key => $one) { + ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, + 'replace' => $replace); + } + } + + /** + * 设置响应头信息,如果已经设置过同名的响应头,该方法将增加一个同名的响应头 + * + * @param string $name 响应头的名称 + * @param string $value 响应头的字段取值 + */ + public function addHeader($name, $value, $replace = false) { + if ($name == '' || $value == '') + return; + $name = $this->_normalizeHeader($name); + $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); + } + + /** + * 设置响应头状态码 + * + * @param int $status + * @param string $message + */ + public function setStatus($status, $message = '') { + if (!is_int($status) || $status < 100 || $status > 505) + return; + + $this->_status = (int) $status; + } + + /** + * 设置响应内容 + * + * @param string $content + * @param string $name + */ + public function setBody($content, $name = null) { + if (!$content) + return; + !$name && $name = 'default'; + array_unshift($this->_bodyIndex, $name); + $this->_body[$name] = $content; + } + + /** + * 添加cookie信息 + * + * @param Cookie $cookie + */ + public function addCookie(Cookie $cookie) { + + } + + /** + * 发送一个错误的响应信息 + * + * @param int $status + * @param string $message + */ + public function sendError($status = self::SC_NOT_FOUND, $message = '') { + if (!is_int($status) || $status < 400 || $status > 505) + return; + $this->setBody($message); + $this->setStatus($status); + $this->sendResponse(); + } + + /** + * 重定向一个响应信息 + * + * @param string $location + */ + public function sendRedirect($location, $status = 302) { + if (!is_int($status) || $status < 300 || $status > 399) + return; + + $this->addHeader('Location', $location, true); + $this->setStatus($status); + $this->_isRedirect = true; + $this->sendHeaders(); + exit(); + } + + /** + * 发送响应信息 + */ + public function sendResponse() { + $this->sendHeaders(); + $this->sendBody(); + exit(); + } + + /** + * 发送响应头部信息 + */ + public function sendHeaders() { + if ($this->isSendedHeader()) + return; + foreach ($this->_headers as $header) { + header($header['name'] . ': ' . $header['value'], $header['replace']); + } + header('HTTP/1.1 ' . $this->_status); + } + + /** + * 发送响应内容 + */ + public function sendBody() { + /*if ($this->_isAjax) echo "_bodyIndex as $key) + echo $this->_body[$key]; + /*if ($this->_isAjax) echo "]]>";*/ + } + + /** + * 获取内容 + * + * @param string $spec 内容的名称 + * @return string|null + */ + public function getBody($name = false) { + if ($name === false) { + ob_start(); + $this->sendBody(); + return ob_get_clean(); + } elseif ($name === true) { + return $this->_body; + } elseif (is_string($name) && isset($this->_body[$name])) + return $this->_body[$name]; + + return null; + } + + /** + * 是否已经发送了响应头部 + */ + public function isSendedHeader($throw = false) { + $sended = headers_sent($file, $line); + if ($throw && $sended) + throw new WindException(__CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); + + return $sended; + } + + /** + * 获取响应头信息 + * + * @return array + */ + public function getHeaders() { + return $this->_headers; + } + + /** + * 清理响应体信息 + */ + public function clearBody() { + $this->_body = array(); + } + + /** + * 清除响应头信息 + */ + public function clearHeaders() { + $this->_headers = array(); + } + + /** + * 格式化响应头信息 + * + * @param string $name + * @return string + */ + private function _normalizeHeader($name) { + $filtered = str_replace(array('-', '_'), ' ', (string) $name); + $filtered = ucwords(strtolower($filtered)); + $filtered = str_replace(' ', '-', $filtered); + return $filtered; + } + + /** + * @return the $_isAjax + */ + public function getIsAjax() { + return $this->_isAjax; + } + + /** + * @param field_type $_isAjax + */ + public function setIsAjax($_isAjax) { + $this->_isAjax = $_isAjax; + } + + /** + * @return array + */ + public function getData($key1 = '', $key2 = '') { + if (!$key1) + return $this->_data; + if (!$key2) + return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; + return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; + } + + /** + * @param $data + */ + public function setData($data, $key = '') { + if ($key) { + $this->_data[$key] = $data; + return; + } + if (is_object($data)) + $data = get_object_vars($data); + if (is_array($data)) + $this->_data += $data; + } + +} \ No newline at end of file diff --git a/wind/component/parser/IWindConfigParser.php b/wind/component/parser/IWindConfigParser.php new file mode 100644 index 00000000..1bb9ad2a --- /dev/null +++ b/wind/component/parser/IWindConfigParser.php @@ -0,0 +1,26 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindConfigParser { + + /** + * 解析文件,保存缓存,返回解析结果 + * + * 1、缺省的配置文件,采用XML格式解析返回 + * 2、如果输入的配置文件格式没有提供支持,则抛出异常 + * 3、根据格式进行解析 + * 4、参数三$isApp 用来配置该解析式组件格式的解析还是应用配置的解析, + * 如果是应用解析需要进行merge操作,如果是组件解析则不用 + * + * @param string $name 解析后保存的文件名字 + * @param string $configPath 待解析文件的绝对路径 + * @param boolean $isApp 判断是应用解析还是组件配置解析 + * @return array 解析成功返回的数据 + */ + public function parse($configPath, $alias = '', $append = ''); + +} \ No newline at end of file diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php new file mode 100644 index 00000000..55bd70cd --- /dev/null +++ b/wind/component/parser/WindConfigParser.php @@ -0,0 +1,209 @@ + + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindConfigParser implements IWindConfigParser { + /** + * 配置文件支持的格式白名单 + */ + const CONFIG_XML = 'XML'; + const CONFIG_PHP = 'PHP'; + const CONFIG_INI = 'INI'; + const CONFIG_PROPERTIES = 'PROPERTIES'; + const WIND_ROOT = 'wind'; + /** + * 配置解析对象队列 + * @var array object $configParser + */ + private $configParsers = array(); + + /** + * 初始化 + * 设置解析数据输出的编码方式 + * @param String $outputEncoding + */ + public function __construct() {} + + /** + * 解析组件的配置文件 + * + * 如果用户没有传入别名,则每次都执行解析 + * 如果用户传入别名,判断是否传入了追加的文件名 + * 如果传入了追加的文件名,则判断该文件的内容中是否存在以别名为key的值 + * 如果有该值则返回该值,否则继续 + * 如果没有传入追加的文件名,则判断该别名命名的缓存文件是否存在 + * 如果存在则返回该文件内容,否则继续 + * 如果没有传入别名,则继续 + * + * 如果该缓存文件不存在,则判断如果不是以追加的方式,并且已经存在该缓存文件,则返回该缓存文件 + * 如果都不存在,则执行解析,并根据是否追加的条件,进行追加或是新建。 + * + * @param string $configPath 待解析的文件路径 + * @param string $alias 解析后保存的key名 + * @param string $append 采用最佳的方法追加到$appandName指定的文件中 + * @return array 解析结果 + */ + public function parse($configPath, $alias = '', $append = '') { + $config = array(); + $alias = trim($alias); + $append = !$append ? '' : trim($append); + $alias && $cacheFileName = ($append ? $this->buildCacheFilePath($append) : $this->buildCacheFilePath($alias)); + if ($alias) { + $config = $this->getCacheContent($cacheFileName); + if (isset($config[$alias]) && !$this->needCompiled()) { + return $config[$alias]; + } + } + if (!($configPath = trim($configPath))) throw new WindException('Please input the file path!'); + $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); + if (!$alias) return $result; + $config[$alias] = $result; + $this->saveConfigFile($cacheFileName, $config); + return $result; + } + + /** + * 获得缓存文件内容 + * + * @param string $file 缓存文件名 + * @return array 缓存文件内容 + */ + private function getCacheContent($file) { + $content = array(); + if (is_file($file)) $content = include ($file); + return is_array($content) ? $content : array(); + } + + /** + * 创建配置文件解析器 + * + * @access private + */ + private function createParser($type) { + switch ($type) { + case self::CONFIG_XML: + Wind::import("WIND:component.parser.WindXmlParser"); + return new WindXmlParser(); + break; + case self::CONFIG_INI: + Wind::import("WIND:component.parser.WindIniParser"); + return new WindIniParser(); + break; + case self::CONFIG_PROPERTIES: + Wind::import("WIND:component.parser.WindPropertiesParser"); + return new WindPropertiesParser(); + break; + default: + throw new WindException('init config parser error.'); + break; + } + } + + /** + * 执行解析并返回解析结果 + * 接收一个配置文件路径,根据路径信息初始化配置解析器,并解析该配置 + * 以数组格式返回配置解析结果 + * + * @param string $configFile 解析的文件路径 + * @return array 返回解析结果 + */ + private function doParser($configFile, $type) { + if (!$configFile) return array(); + if (!is_file($configFile)) throw new WindException('The file <' . $configFile . '> is not exists'); + if ($type == 'PHP') { + $config = include ($configFile); + return (isset($config['wind'])) ? $config['wind'] : $config; + } + if (!isset($this->configParsers[$type])) { + $this->configParsers[$type] = $this->createParser($type); + } + return $this->configParsers[$type]->parse($configFile); + } + + /** + * 返回是否需要执行解析 + * + * 如果是debug模式,则返回false, 进行每次都进行解析 + * 如果不是debug模式,则先判断是否设置了缓存模式 + * 如果没有设置缓存则返回false, 进行解析, + * 如果设置了缓存模式,则判断缓存文件是否存在 + * 如果该解析出来的文件不存在,则返回false, 执行解析 + * 否则返回true, 直接读取缓存 + * + * @param string $cacheFile 缓存文件路径 + * @return boolean false:需要进行解析, true:不需要进行解析,直接读取缓存文件 + */ + private function needCompiled() { + if (IS_DEBUG && is_dir(COMPILE_PATH)) return true; + return false; + } + + /** + * 获得文件的后缀,决定采用的是哪种配置格式, + * 如果传递的文件配置格式不在支持范围内,则抛出异常 + * + * @param string $configPath 配置文件路径 + * @return boolean : true 解析文件格式成功,解析失败则抛出异常 + */ + private function getConfigFormat($configPath) { + if ($configPath === '') return self::CONFIG_XML; + $format = strtoupper(trim(strrchr($configPath, '.'), '.')); + if (!in_array($format, $this->getConfigFormatList())) { + throw new WindException("The format of the config file doesn't sopported yet!"); + } + return $format; + } + + /** + * 保存成文件 + * + * @param string $filename 保存的文件名 + * @param array $data 需要保持的数据 + * @return boolean 保存成功则返回true,保存失败则返回false + */ + private function saveConfigFile($filename, $data) { + if (!$filename || !$data || !is_dir(COMPILE_PATH)) return false; + Wind::import('COM:utility.WindFile'); + return WindFile::savePhpData($filename, $data); + } + + /** + * 构造文件的路径 + * + * @param string $fileName 缓存文件的名字 + * @return string 返回缓存文件的$fileName的绝对路径 + */ + private function buildCacheFilePath($fileName) { + return rtrim(COMPILE_PATH, '/') . D_S . strtolower($fileName) . '.php'; + } + + /** + * 获得支持解析的配置文件格式的白名单 + * + * @return array 返回配置文件格式的白名单 + */ + private function getConfigFormatList() { + return array( + self::CONFIG_XML, + self::CONFIG_PHP, + self::CONFIG_INI, + self::CONFIG_PROPERTIES); + } + + /** + * 析构函数 + * + */ + public function __destruct() { + $this->configParser = array(); + } +} \ No newline at end of file diff --git a/wind/component/router/AbstractWindRouter.php b/wind/component/router/AbstractWindRouter.php new file mode 100644 index 00000000..29b90dca --- /dev/null +++ b/wind/component/router/AbstractWindRouter.php @@ -0,0 +1,173 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindRouter extends WindModule { + const DEFAULT_ERROR_HANDLER = 'WIND:core.web.WindErrorHandler'; + const CONTROLLER_DEFAULT_PATH = 'controller'; + const CONTROLLER_DEFAULT_SUFFIX = 'Controller'; + /** + * 默认的处理方法‘run’ + * + * @var string + */ + private $action = 'run'; + /** + * 默认的控制器‘index’ + * + * @var string + */ + private $controller = 'index'; + /** + * 默认的系统应用模块名为‘default’ + * + * @var string + */ + private $module = 'default'; + /** + * 系统应用模块寻址路径 + * + * @var string + */ + protected $modulePath = ''; + + private $reParse = true; + + /** + * 该方法定义了路由解析策略 + * @return string | actionHandler + */ + abstract public function parse(); + + /** + * 构建Url并返回 + * @return string + */ + abstract public function buildUrl(); + + /** + * 通过调用该方法返回,解析请求参数,并返回路由结果 + * + * @return + */ + public function doParse() { + if ($this->reParse) { + $this->parse(); + $this->reParse = false; + } + $_moduleName = $this->getModule(); + if (!strcasecmp($this->getController(), 'windError')) { + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log( + '[core.roter.AbstractWindRouter.doParse] action hander: default error action :' . + self::DEFAULT_ERROR_HANDLER, WindLogger::LEVEL_DEBUG, 'wind.core'); + } + return $this->getSystemConfig()->getModuleErrorHandlerByModuleName($_moduleName, + self::DEFAULT_ERROR_HANDLER); + } + $_suffix = $this->getSystemConfig()->getModuleControllerSuffixByModuleName($_moduleName, + self::CONTROLLER_DEFAULT_SUFFIX); + if ($this->modulePath) + $_path = $this->modulePath; + else { + $_path = $this->getSystemConfig()->getModuleControllerPathByModuleName($_moduleName, + self::CONTROLLER_DEFAULT_PATH); + } + $_path .= '.' . ucfirst($this->controller) . $_suffix; + if (strpos($_path, ':') === false) + $_path = Wind::getAppName() . ':' . $_path; + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log('[core.router.AbstractWindRouter.doParse] action handler: ' . $_path, WindLogger::LEVEL_DEBUG, + 'wind.core'); + } + $this->destroy(); + return $_path; + } + + /** + * @return + */ + protected function destroy() { + $this->modulePath = ''; + } + + /** + * 设置module信息, 支持格式: + * 'moduleName'; + * 'namespace:modulePath' + * + * @param string $module + * @return + */ + public function setModule($module) { + if (false !== ($pos = strpos($module, ':'))) { + $this->modulePath = $module; + } else { + $this->module = $module; + $this->modulePath = ''; + } + } + + /** + * 获得业务操作 + * + * @return string + */ + public function getAction() { + return $this->action; + } + + /** + * 获得业务对象 + * + * @return string + */ + public function getController() { + return $this->controller; + } + + /** + * 返回一组应用入口 + * + * @return string + */ + public function getModule() { + return $this->module; + } + + /** + * 设置action信息 + * + * @param string $action + * @return + */ + public function setAction($action) { + $this->action = $action; + } + + /** + * 设置controller信息 + * + * @param string $controller + * @return + */ + public function setController($controller) { + $this->controller = $controller; + } + + /** + * @param boolean $reParse + * @return + */ + public function reParse() { + $this->reParse = true; + } + +} \ No newline at end of file diff --git a/wind/component/router/WindUrlBasedRouter.php b/wind/component/router/WindUrlBasedRouter.php new file mode 100644 index 00000000..2256706d --- /dev/null +++ b/wind/component/router/WindUrlBasedRouter.php @@ -0,0 +1,62 @@ + + * @author Qiong Wu + * @version $Id$ + * @link WRouteParser + * @package + */ +class WindUrlBasedRouter extends AbstractWindRouter { + /* url 路由参数规则 */ + const URL_PARAM = 'url-param'; + const DEFAULT_VALUE = 'default-value'; + /* 后缀名参数规则 */ + const CONTROLLER_SUFFIX = 'controller-suffix'; + const ACTION_SUFFIX = 'action-suffix'; + /* 路由信息 */ + const URL_RULE_MODULE = 'module'; + const URL_RULE_CONTROLLER = 'controller'; + const URL_RULE_ACTION = 'action'; + + /* (non-PHPdoc) + * @see AbstractWindRouter::parse() + */ + public function parse() { + $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->getModule())); + $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->getController())); + $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->getAction())); + } + + /* (non-PHPdoc) + * @see AbstractWindRouter::buildUrl() + */ + public function buildUrl() { + $module = $this->getUrlParamValue(self::URL_RULE_MODULE); + $controller = $this->getUrlParamValue(self::URL_RULE_CONTROLLER); + $action = $this->getUrlParamValue(self::URL_RULE_ACTION); + $url = '?' . $module . '=' . $this->getModule(); + $url .= '&' . $controller . '=' . $this->getController(); + $url .= '&' . $action . '=' . $this->getAction(); + return $url; + } + + /** + * 返回路由的配置信息 + * + * @param urlParam + * @param defaultValue + * @return string + */ + private function getUrlParamValue($type, $defaultValue = '') { + if ($_param = $this->getConfig($type, self::URL_PARAM)) { + $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE, $defaultValue); + return $this->getRequest()->getRequest($_param, $defaultValue); + } + return $defaultValue; + } +} \ No newline at end of file From 36ff7bdf272f1ee6693bb1863f63f5195433fbc9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:04:48 +0000 Subject: [PATCH 0167/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2227 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindSystemConfig.php | 237 +++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 wind/core/WindSystemConfig.php diff --git a/wind/core/WindSystemConfig.php b/wind/core/WindSystemConfig.php new file mode 100644 index 00000000..cd0fe287 --- /dev/null +++ b/wind/core/WindSystemConfig.php @@ -0,0 +1,237 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindSystemConfig extends WindModule { + private $rootPath = ''; + private $appName = ''; + + /** + * @param string $config + * @param string $appName + * @param WindFactory $factory + */ + public function __construct($config, $appName, $factory) { + $this->appName = $appName; + $this->setConfig($config, $factory); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config, $factory = null) { + if (!$config) + return; + if (is_string($config)) { + $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); + $config = $configParser->parse($config, $this->appName . '_config'); + } + if (isset($config[$this->appName])) { + $this->_config = $config[$this->appName]; + } else + $this->_config = $config; + } + + /** + * @return the $appName + */ + public function getAppName() { + return $this->appName; + } + + /** + * 返回应用路径信息 + * + * @return string + */ + public function getRootPath() { + if (!$this->rootPath) { + $rootPath = $this->getConfig('root-path'); + if (!$rootPath) + $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); + $this->rootPath = $rootPath; + } + return $this->rootPath; + } + + /** + * 返回当前应用的启动脚本位置 + */ + public function getAppClass() { + return $this->getConfig('class', '', COMPONENT_WEBAPP); + } + + /** + * 返回配置定义中定义的过滤链列表 + * 如果定义$name则返回在filters定义标签内对应的属性值 + * + * @param string $name + * @return array|string + */ + public function getFilters() { + return $this->getConfig('filters'); + } + + /** + * 返回filterChain的类型 + * + * @return array + */ + public function getFilterClass() { + return $this->getConfig('filters', 'class'); + } + + /** + * @param string $name + * @return array|string + */ + public function getRouter() { + return $this->getConfig('router'); + } + + /** + * 返回当前路由的配置信息 + * @return array + */ + public function getRouterConfig() { + return $this->getConfig('router', 'config'); + } + + /** + * 返回路由类型定义 + * @return string + */ + public function getRouterClass() { + return $this->getConfig('router', 'class', COMPONENT_ROUTER); + } + + /** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * @param string $name + * @return array|string + */ + public function getModules($name = '') { + return $this->getConfig('modules', $name); + } + + /** + * 根据module名称返回module的视图处理类 + * @param string $name + * @param string $default + */ + public function getModuleViewClassByModuleName($name, $default = '') { + $module = $this->getConfig('modules', $name); + return $this->getConfig('view', 'class', $default, $module); + } + + /** + * 根据module名称返回module的视图配置信息 + * @param string $name + * @param string $default + */ + public function getModuleViewConfigByModuleName($name, $default = '') { + $module = $this->getConfig('modules', $name); + return $this->getConfig('view', 'config', $default, $module); + } + + /** + * 根据module名称返回错误的处理句柄 + * @param string $name + * @param string $default + * @return string + */ + public function getModuleErrorHandlerByModuleName($name, $default = '') { + $module = $this->getConfig('modules', $name); + return $this->getConfig('error-handler', 'class', $default, $module); + } + + /** + * 返回指定moduleName的controller路径信息 + * @param string $name + * @return string + */ + public function getModuleControllerPathByModuleName($name, $default = '') { + $module = $this->getConfig('modules', $name); + return $this->getConfig('controller-path', 'value', $default, $module); + } + + /** + * 返回指定moduleName的controller后缀 + * @param string $name + * @return string + */ + public function getModuleControllerSuffixByModuleName($name, $default = '') { + $module = $this->getConfig('modules', $name); + return $this->getConfig('controller-suffix', 'value', $default, $module); + } + + /** + * 获得缓存配置 + * @param string $type + */ + public function getCacheConfig($type = '') { + $config = $this->getConfig('cache'); + if (isset($config['resource'])) { + $config = $this->parseResource($config['resource']); + $this->_config['cache'] = $config; + } + return $this->getConfig('cache', $type); + } + + /** + * 获得DB配置 + * @param string $type + */ + public function getDbConfig($type = '') { + $config = $this->getConfig('db'); + if (isset($config['resource'])) { + $config = $this->parseResource($config['resource']); + $this->_config['db'] = $config; + } + return $this->getConfig('db', $type); + } + + /** + * 解析resource的配置 + * + * @param string $resource + * @return array + */ + private function parseResource($resource) { + $fileName = $resource; + $ext = 'php'; + if (($extPois = strpos($resource, '.')) !== false) { + $fileName = substr($resource, 0, $extPois); + $ext = substr($resource, $extPois + 1); + } + $fileName = (false === strpos($resource, ':')) ? Wind::getAppName() . ':' . $fileName : $fileName; + $filePath = !is_file($resource) ? Wind::getRealPath($fileName, $ext) : $resource; + $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); + $config = $configParser->parse($filePath); + return $config; + } + +} \ No newline at end of file From c34643629a1426fd132e7f07dd5635508c4b948a Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:07:12 +0000 Subject: [PATCH 0168/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2228 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/config/WindSystemConfig.php | 237 ------------------ wind/core/config/parser/IWindConfigParser.php | 27 -- wind/core/config/parser/WindConfigParser.php | 209 --------------- 3 files changed, 473 deletions(-) delete mode 100644 wind/core/config/WindSystemConfig.php delete mode 100644 wind/core/config/parser/IWindConfigParser.php delete mode 100644 wind/core/config/parser/WindConfigParser.php diff --git a/wind/core/config/WindSystemConfig.php b/wind/core/config/WindSystemConfig.php deleted file mode 100644 index cd0fe287..00000000 --- a/wind/core/config/WindSystemConfig.php +++ /dev/null @@ -1,237 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindSystemConfig extends WindModule { - private $rootPath = ''; - private $appName = ''; - - /** - * @param string $config - * @param string $appName - * @param WindFactory $factory - */ - public function __construct($config, $appName, $factory) { - $this->appName = $appName; - $this->setConfig($config, $factory); - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config, $factory = null) { - if (!$config) - return; - if (is_string($config)) { - $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($config, $this->appName . '_config'); - } - if (isset($config[$this->appName])) { - $this->_config = $config[$this->appName]; - } else - $this->_config = $config; - } - - /** - * @return the $appName - */ - public function getAppName() { - return $this->appName; - } - - /** - * 返回应用路径信息 - * - * @return string - */ - public function getRootPath() { - if (!$this->rootPath) { - $rootPath = $this->getConfig('root-path'); - if (!$rootPath) - $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); - $this->rootPath = $rootPath; - } - return $this->rootPath; - } - - /** - * 返回当前应用的启动脚本位置 - */ - public function getAppClass() { - return $this->getConfig('class', '', COMPONENT_WEBAPP); - } - - /** - * 返回配置定义中定义的过滤链列表 - * 如果定义$name则返回在filters定义标签内对应的属性值 - * - * @param string $name - * @return array|string - */ - public function getFilters() { - return $this->getConfig('filters'); - } - - /** - * 返回filterChain的类型 - * - * @return array - */ - public function getFilterClass() { - return $this->getConfig('filters', 'class'); - } - - /** - * @param string $name - * @return array|string - */ - public function getRouter() { - return $this->getConfig('router'); - } - - /** - * 返回当前路由的配置信息 - * @return array - */ - public function getRouterConfig() { - return $this->getConfig('router', 'config'); - } - - /** - * 返回路由类型定义 - * @return string - */ - public function getRouterClass() { - return $this->getConfig('router', 'class', COMPONENT_ROUTER); - } - - /** - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * @param string $name - * @return array|string - */ - public function getModules($name = '') { - return $this->getConfig('modules', $name); - } - - /** - * 根据module名称返回module的视图处理类 - * @param string $name - * @param string $default - */ - public function getModuleViewClassByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $this->getConfig('view', 'class', $default, $module); - } - - /** - * 根据module名称返回module的视图配置信息 - * @param string $name - * @param string $default - */ - public function getModuleViewConfigByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $this->getConfig('view', 'config', $default, $module); - } - - /** - * 根据module名称返回错误的处理句柄 - * @param string $name - * @param string $default - * @return string - */ - public function getModuleErrorHandlerByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $this->getConfig('error-handler', 'class', $default, $module); - } - - /** - * 返回指定moduleName的controller路径信息 - * @param string $name - * @return string - */ - public function getModuleControllerPathByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $this->getConfig('controller-path', 'value', $default, $module); - } - - /** - * 返回指定moduleName的controller后缀 - * @param string $name - * @return string - */ - public function getModuleControllerSuffixByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $this->getConfig('controller-suffix', 'value', $default, $module); - } - - /** - * 获得缓存配置 - * @param string $type - */ - public function getCacheConfig($type = '') { - $config = $this->getConfig('cache'); - if (isset($config['resource'])) { - $config = $this->parseResource($config['resource']); - $this->_config['cache'] = $config; - } - return $this->getConfig('cache', $type); - } - - /** - * 获得DB配置 - * @param string $type - */ - public function getDbConfig($type = '') { - $config = $this->getConfig('db'); - if (isset($config['resource'])) { - $config = $this->parseResource($config['resource']); - $this->_config['db'] = $config; - } - return $this->getConfig('db', $type); - } - - /** - * 解析resource的配置 - * - * @param string $resource - * @return array - */ - private function parseResource($resource) { - $fileName = $resource; - $ext = 'php'; - if (($extPois = strpos($resource, '.')) !== false) { - $fileName = substr($resource, 0, $extPois); - $ext = substr($resource, $extPois + 1); - } - $fileName = (false === strpos($resource, ':')) ? Wind::getAppName() . ':' . $fileName : $fileName; - $filePath = !is_file($resource) ? Wind::getRealPath($fileName, $ext) : $resource; - $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($filePath); - return $config; - } - -} \ No newline at end of file diff --git a/wind/core/config/parser/IWindConfigParser.php b/wind/core/config/parser/IWindConfigParser.php deleted file mode 100644 index bc42c3fb..00000000 --- a/wind/core/config/parser/IWindConfigParser.php +++ /dev/null @@ -1,27 +0,0 @@ - 2010-12-30 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -interface IWindConfigParser { - - /** - * 解析文件,保存缓存,返回解析结果 - * - * 1、缺省的配置文件,采用XML格式解析返回 - * 2、如果输入的配置文件格式没有提供支持,则抛出异常 - * 3、根据格式进行解析 - * 4、参数三$isApp 用来配置该解析式组件格式的解析还是应用配置的解析, - * 如果是应用解析需要进行merge操作,如果是组件解析则不用 - * - * @param string $name 解析后保存的文件名字 - * @param string $configPath 待解析文件的绝对路径 - * @param boolean $isApp 判断是应用解析还是组件配置解析 - * @return array 解析成功返回的数据 - */ - public function parse($configPath, $alias = '', $append = ''); - -} \ No newline at end of file diff --git a/wind/core/config/parser/WindConfigParser.php b/wind/core/config/parser/WindConfigParser.php deleted file mode 100644 index 55bd70cd..00000000 --- a/wind/core/config/parser/WindConfigParser.php +++ /dev/null @@ -1,209 +0,0 @@ - - * @author xiaoxia xu - * @version $Id$ - * @package - */ -class WindConfigParser implements IWindConfigParser { - /** - * 配置文件支持的格式白名单 - */ - const CONFIG_XML = 'XML'; - const CONFIG_PHP = 'PHP'; - const CONFIG_INI = 'INI'; - const CONFIG_PROPERTIES = 'PROPERTIES'; - const WIND_ROOT = 'wind'; - /** - * 配置解析对象队列 - * @var array object $configParser - */ - private $configParsers = array(); - - /** - * 初始化 - * 设置解析数据输出的编码方式 - * @param String $outputEncoding - */ - public function __construct() {} - - /** - * 解析组件的配置文件 - * - * 如果用户没有传入别名,则每次都执行解析 - * 如果用户传入别名,判断是否传入了追加的文件名 - * 如果传入了追加的文件名,则判断该文件的内容中是否存在以别名为key的值 - * 如果有该值则返回该值,否则继续 - * 如果没有传入追加的文件名,则判断该别名命名的缓存文件是否存在 - * 如果存在则返回该文件内容,否则继续 - * 如果没有传入别名,则继续 - * - * 如果该缓存文件不存在,则判断如果不是以追加的方式,并且已经存在该缓存文件,则返回该缓存文件 - * 如果都不存在,则执行解析,并根据是否追加的条件,进行追加或是新建。 - * - * @param string $configPath 待解析的文件路径 - * @param string $alias 解析后保存的key名 - * @param string $append 采用最佳的方法追加到$appandName指定的文件中 - * @return array 解析结果 - */ - public function parse($configPath, $alias = '', $append = '') { - $config = array(); - $alias = trim($alias); - $append = !$append ? '' : trim($append); - $alias && $cacheFileName = ($append ? $this->buildCacheFilePath($append) : $this->buildCacheFilePath($alias)); - if ($alias) { - $config = $this->getCacheContent($cacheFileName); - if (isset($config[$alias]) && !$this->needCompiled()) { - return $config[$alias]; - } - } - if (!($configPath = trim($configPath))) throw new WindException('Please input the file path!'); - $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); - if (!$alias) return $result; - $config[$alias] = $result; - $this->saveConfigFile($cacheFileName, $config); - return $result; - } - - /** - * 获得缓存文件内容 - * - * @param string $file 缓存文件名 - * @return array 缓存文件内容 - */ - private function getCacheContent($file) { - $content = array(); - if (is_file($file)) $content = include ($file); - return is_array($content) ? $content : array(); - } - - /** - * 创建配置文件解析器 - * - * @access private - */ - private function createParser($type) { - switch ($type) { - case self::CONFIG_XML: - Wind::import("WIND:component.parser.WindXmlParser"); - return new WindXmlParser(); - break; - case self::CONFIG_INI: - Wind::import("WIND:component.parser.WindIniParser"); - return new WindIniParser(); - break; - case self::CONFIG_PROPERTIES: - Wind::import("WIND:component.parser.WindPropertiesParser"); - return new WindPropertiesParser(); - break; - default: - throw new WindException('init config parser error.'); - break; - } - } - - /** - * 执行解析并返回解析结果 - * 接收一个配置文件路径,根据路径信息初始化配置解析器,并解析该配置 - * 以数组格式返回配置解析结果 - * - * @param string $configFile 解析的文件路径 - * @return array 返回解析结果 - */ - private function doParser($configFile, $type) { - if (!$configFile) return array(); - if (!is_file($configFile)) throw new WindException('The file <' . $configFile . '> is not exists'); - if ($type == 'PHP') { - $config = include ($configFile); - return (isset($config['wind'])) ? $config['wind'] : $config; - } - if (!isset($this->configParsers[$type])) { - $this->configParsers[$type] = $this->createParser($type); - } - return $this->configParsers[$type]->parse($configFile); - } - - /** - * 返回是否需要执行解析 - * - * 如果是debug模式,则返回false, 进行每次都进行解析 - * 如果不是debug模式,则先判断是否设置了缓存模式 - * 如果没有设置缓存则返回false, 进行解析, - * 如果设置了缓存模式,则判断缓存文件是否存在 - * 如果该解析出来的文件不存在,则返回false, 执行解析 - * 否则返回true, 直接读取缓存 - * - * @param string $cacheFile 缓存文件路径 - * @return boolean false:需要进行解析, true:不需要进行解析,直接读取缓存文件 - */ - private function needCompiled() { - if (IS_DEBUG && is_dir(COMPILE_PATH)) return true; - return false; - } - - /** - * 获得文件的后缀,决定采用的是哪种配置格式, - * 如果传递的文件配置格式不在支持范围内,则抛出异常 - * - * @param string $configPath 配置文件路径 - * @return boolean : true 解析文件格式成功,解析失败则抛出异常 - */ - private function getConfigFormat($configPath) { - if ($configPath === '') return self::CONFIG_XML; - $format = strtoupper(trim(strrchr($configPath, '.'), '.')); - if (!in_array($format, $this->getConfigFormatList())) { - throw new WindException("The format of the config file doesn't sopported yet!"); - } - return $format; - } - - /** - * 保存成文件 - * - * @param string $filename 保存的文件名 - * @param array $data 需要保持的数据 - * @return boolean 保存成功则返回true,保存失败则返回false - */ - private function saveConfigFile($filename, $data) { - if (!$filename || !$data || !is_dir(COMPILE_PATH)) return false; - Wind::import('COM:utility.WindFile'); - return WindFile::savePhpData($filename, $data); - } - - /** - * 构造文件的路径 - * - * @param string $fileName 缓存文件的名字 - * @return string 返回缓存文件的$fileName的绝对路径 - */ - private function buildCacheFilePath($fileName) { - return rtrim(COMPILE_PATH, '/') . D_S . strtolower($fileName) . '.php'; - } - - /** - * 获得支持解析的配置文件格式的白名单 - * - * @return array 返回配置文件格式的白名单 - */ - private function getConfigFormatList() { - return array( - self::CONFIG_XML, - self::CONFIG_PHP, - self::CONFIG_INI, - self::CONFIG_PROPERTIES); - } - - /** - * 析构函数 - * - */ - public function __destruct() { - $this->configParser = array(); - } -} \ No newline at end of file From 1a79c642e066334be3256e12f919acbc9a6b882b Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:07:32 +0000 Subject: [PATCH 0169/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2229 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/filter/WindFilter.php | 24 ------ wind/core/filter/WindFilterChain.php | 64 ---------------- wind/core/filter/WindHandlerInterceptor.php | 50 ------------ .../filter/WindHandlerInterceptorChain.php | 76 ------------------- 4 files changed, 214 deletions(-) delete mode 100644 wind/core/filter/WindFilter.php delete mode 100644 wind/core/filter/WindFilterChain.php delete mode 100644 wind/core/filter/WindHandlerInterceptor.php delete mode 100644 wind/core/filter/WindHandlerInterceptorChain.php diff --git a/wind/core/filter/WindFilter.php b/wind/core/filter/WindFilter.php deleted file mode 100644 index d2b15fae..00000000 --- a/wind/core/filter/WindFilter.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @author xiaoxia xu - * @version $Id$ - * @package - */ -class WindFilter extends WindHandlerInterceptor { - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - - } - -} \ No newline at end of file diff --git a/wind/core/filter/WindFilterChain.php b/wind/core/filter/WindFilterChain.php deleted file mode 100644 index 989519b1..00000000 --- a/wind/core/filter/WindFilterChain.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindFilterChain extends WindHandlerInterceptorChain { - - /** - * @param array $filterConfig - */ - public function __construct($filterConfig) { - $this->_initFilters($filterConfig); - } - - /** - * @param string $filterName - */ - public function deleteFilter($alias) { - unset($this->_interceptors[$alias]); - } - - /** - * 在filter链中动态的添加一个filter - * 当befor为空时,添加到程序结尾处 - * 如果befor有值,则遍历数组,找到befor的位置,将新的过滤器添加到befor后面, - * 并将所有原befor位置后的过滤器往后移一位 - * - * @param string $filterName - * @param string $path - * @param string $beforFilter - */ - public function addFilter($filter, $beforFilter = '') { - if ($beforFilter === '') { - $this->addInterceptors(array(get_class($filter) => $filter)); - return true; - } - $_interceptors = array(); - foreach ($this->_interceptors as $key => $interceptor) { - if ($beforFilter === $key) break; - $_interceptors[$key] = $interceptor; - unset($this->_interceptors[$key]); - } - $_interceptors[get_class($filter)] = $filter; - $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; - } - - /** - * Enter description here ... - * @param array $filters - */ - private function _initFilters($filters = array()) { - $_temp = array(); - foreach ((array) $filters as $key => $filter) { - if (!is_array($filter)) continue; - $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); - if (!class_exists($filterClass)) continue; - $_temp[$key] = new $filterClass(); - } - $this->addInterceptors($_temp); - } - -} \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptor.php b/wind/core/filter/WindHandlerInterceptor.php deleted file mode 100644 index c6ca0890..00000000 --- a/wind/core/filter/WindHandlerInterceptor.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHandlerInterceptor extends WindModule { - protected $result = null; - protected $interceptorChain = null; - - /** - * Enter description here ... - */ - public function preHandle() {} - - /** - * Enter description here ... - */ - public function postHandle() {} - - /** - * Enter description here ... - * @return mixed - */ - public function handle() { - $args = func_get_args(); - $this->result = call_user_func_array(array($this, 'preHandle'), $args); - if ($this->result !== null) { - return $this->result; - } - if (null !== ($handler = $this->interceptorChain->getHandler())) { - $this->result = call_user_func_array(array($handler, 'handle'), $args); - } else { - $this->result = $this->interceptorChain->execute(); - } - call_user_func_array(array($this, 'postHandle'), $args); - return $this->result; - } - - /** - * 设置过滤链对象 - * - * @param WindHandlerInterceptorChain $interceptorChain - */ - public function setHandlerInterceptorChain($interceptorChain) { - $this->interceptorChain = $interceptorChain; - } -} -?> \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptorChain.php b/wind/core/filter/WindHandlerInterceptorChain.php deleted file mode 100644 index 55ec188d..00000000 --- a/wind/core/filter/WindHandlerInterceptorChain.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHandlerInterceptorChain extends WindModule { - protected $_interceptors = array(); - protected $_callBack = null; - protected $_args = array(); - private $_state = true; - - /** - * 设置回调方法 - * - * @param string|array $callBack - * @param array $args - * @return - */ - public function setCallBack($callBack, $args = array()) { - $this->_callBack = $callBack; - $this->_args = $args; - } - - /** - * 执行callback方法 - * - * @throws WindException - * @return void|mixed - */ - public function execute() { - if ($this->_callBack === null) return null; - if (is_string($this->_callBack) && !function_exists($this->_callBack)) { - throw new WindException('[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, - WindException::ERROR_FUNCTION_NOT_EXIST); - } - return call_user_func_array($this->_callBack, (array) $this->_args); - } - - /** - * 返回处理句柄 - * - * @return WindHandlerInterceptor - */ - public function getHandler() { - if ($this->_state) { - $this->addInterceptors(new WindHandlerInterceptor()); - $this->_state = false; - } - if (count($this->_interceptors) <= 0) return null; - $handler = array_shift($this->_interceptors); - if ($handler instanceof WindHandlerInterceptor) { - $handler->setHandlerInterceptorChain($this); - return $handler; - } - Wind::log( - '[core.filter.WindHandlerInterceptorChain.getHandler] the type of Interceptor ' . gettype($handler) . - ' is not supported.', WindLogger::LEVEL_DEBUG, 'wind.core'); - return $this->getHandler(); - } - - /** - * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 - * - * @param $interceptors - * @return - */ - public function addInterceptors($interceptors) { - if (is_array($interceptors)) - $this->_interceptors += $interceptors; - else - $this->_interceptors[] = $interceptors; - } -} -?> \ No newline at end of file From 63e97521052083cbc5d9382cb27110bcf0405346 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:07:44 +0000 Subject: [PATCH 0170/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2230 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/request/IWindRequest.php | 25 - wind/core/request/WindHttpRequest.php | 647 -------------------------- 2 files changed, 672 deletions(-) delete mode 100644 wind/core/request/IWindRequest.php delete mode 100644 wind/core/request/WindHttpRequest.php diff --git a/wind/core/request/IWindRequest.php b/wind/core/request/IWindRequest.php deleted file mode 100644 index aa657cbf..00000000 --- a/wind/core/request/IWindRequest.php +++ /dev/null @@ -1,25 +0,0 @@ - 2010-11-3 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * 处理请求抽象基类 - * 如http请求 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindRequest { - const INPUT_TYPE_GET = 'get'; - const INPUT_TYPE_POST = 'post'; - const INPUT_TYPE_COOKIE = 'cookie'; -} - - - - diff --git a/wind/core/request/WindHttpRequest.php b/wind/core/request/WindHttpRequest.php deleted file mode 100644 index cbc18c41..00000000 --- a/wind/core/request/WindHttpRequest.php +++ /dev/null @@ -1,647 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHttpRequest implements IWindRequest { - /** - * 访问的端口号 - * @var int - */ - private $_port = null; - /** - * 客户端IP - * @var string - */ - private $_clientIp = null; - /** - * 语言信息 - * @var string - */ - private $_language = null; - /** - * 路径信息 - * @var string - */ - private $_pathInfo = null; - /** - * @var string - */ - private $_scriptUrl = null; - /** - * @var string - */ - private $_requestUri = null; - /** - * 基础路径信息 - * @var string - */ - private $_baseUrl = null; - private $_hostInfo = null; - /** - * 请求参数信息 - * @var array - */ - private $_attribute = array(); - /** - * @var WindHttpResponse - */ - private $_response = null; - - public function __construct() { - $this->normalizeRequest(); - } - - protected function normalizeRequest() { - if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { - if (isset($_GET)) $_GET = $this->stripSlashes($_GET); - if (isset($_POST)) $_POST = $this->stripSlashes($_POST); - if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); - if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); - } - } - - public function stripSlashes(&$data) { - return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes($data); - } - - /** - * 设置属性数据 - * - * @param string|array|object $data - * @param string $key - * @return - */ - public function setAttribute($data, $key = '') { - if ($key) { - $this->_attribute[$key] = $data; - return; - } - if (is_object($data)) $data = get_object_vars($data); - if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); - } - - /** - * 根据名称获得服务器和执行环境信息 - * - * @param string|null $name - * @return string|object|array| - */ - public function getAttribute($key, $defaultValue = '') { - if (isset($this->_attribute[$key])) - return $this->_attribute[$key]; - else if (isset($_GET[$key])) - return $_GET[$key]; - else if (isset($_POST[$key])) - return $_POST[$key]; - else if (isset($_COOKIE[$key])) - return $_COOKIE[$key]; - else if (isset($_REQUEST[$key])) - return $_REQUEST[$key]; - else if (isset($_ENV[$key])) - return $_ENV[$key]; - else if (isset($_SERVER[$key])) - return $_SERVER[$key]; - else - return $defaultValue; - } - - /** - * 返回$_GET,$_POST的值,未设置则返回default - * @param string $name | attribute name - */ - public function getRequest($key = null, $defaultValue = null) { - if (!$key) return array_merge($_POST, $_GET); - if (isset($_GET[$key])) return $_GET[$key]; - if (isset($_POST[$key])) return $_POST[$key]; - return $defaultValue; - } - - /** - * 从query中取值 - * - * @param string $name - * @param string $default - * @return string|null - */ - public function getQuery($name = null, $defaultValue = null) { - return $this->getGet($name, $defaultValue); - } - - /** - * 获得post值 - * - * @param string $name - * @param string $defaultValue - * @return string|null - */ - public function getPost($name = null, $defaultValue = null) { - if ($name == null) return $_POST; - return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; - } - - /** - * 获得get值 - * - * @param string $name - * @param string $defaultValue - * @return string|null - */ - public function getGet($name = '', $defaultValue = null) { - if ($name == null) return $_GET; - return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; - } - - /** - * 返回cookie的值,如果$name=null则返回所有Cookie值 - * - * @param string $key - * @param string $defaultValue - * @return string|null|array - */ - public function getCookie($name = null, $defaultValue = null) { - if ($name == null) return $_COOKIE; - return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; - } - - /** - * 返回session的值,如果$name=null则返回所有Cookie值 - * - * @param string $key - * @param string $defaultValue - * @return string|null|array - */ - public function getSession($name = null, $defaultValue = null) { - if ($name == null) return $_SESSION; - return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; - } - - /** - * 返回Server的值,如果$name为空则返回所有Server的值 - * - * @param string $name - * @param string $defaultValue - * @return string|null|array - */ - public function getServer($name = null, $defaultValue = null) { - if ($name == null) return $_SERVER; - return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; - } - - /** - * 返回env中的值,如果$name为null则返回所有env的值 - * - * @param string|null $name - * @param string $defaultValue - * @return string|null|array - */ - public function getEnv($name = null, $defaultValue = null) { - if ($name == null) return $_ENV; - return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; - } - - /** - * 获取协议名称 - * - * @return string - */ - public function getScheme() { - return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; - } - - /** - * 返回请求页面时通信协议的名称和版本 - * @return string - */ - public function getProtocol() { - return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); - } - - /** - * 返回访问IP - * - * @return string|0.0.0.0 - */ - public function getClientIp() { - if (!$this->_clientIp) $this->_getClientIp(); - return $this->_clientIp; - } - - /** - * 获得请求的方法 - */ - public function getRequestMethod() { - return strtoupper($this->getServer('REQUEST_METHOD')); - } - - /** - * 获得请求类型 - * - * @return string - */ - public function getRequestType() { - return IWindRequest::REQUEST_TYPE_WEB; - } - - /** - * 返回该请求是否为ajax请求 - * @return Boolean - */ - public function getIsAjaxRequest() { - return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); - } - - /** - * Returns a boolean indicating whether this request was made using a - * secure channel, such as HTTPS. - * @return Boolean - */ - public function isSecure() { - return !strcasecmp($this->getServer('HTTPS'), 'on'); - } - - /** - * 返回请求是否为GET请求类型 - * @return boolean - */ - public function isGet() { - return !strcasecmp($this->getRequestMethod(), 'GET'); - } - - /** - * 返回请求是否为POST请求类型 - * @return boolean - */ - public function isPost() { - return !strcasecmp($this->getRequestMethod(), 'POST'); - } - - /** - * 返回请求是否为PUT请求类型 - * @return boolean - */ - public function isPut() { - return !strcasecmp($this->getRequestMethod(), 'PUT'); - } - - /** - * 返回请求是否为DELETE请求类型 - * @return boolean - */ - public function isDelete() { - return !strcasecmp($this->getRequestMethod(), 'Delete'); - } - - /** - * 初始化请求的资源标识符 - * 这里的uri是去除协议名、主机名的 - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_requestUri = /example/index.php?a=test - * - * @return string - */ - public function getRequestUri() { - if (!$this->_requestUri) $this->initRequestUri(); - return $this->_requestUri; - } - - /** - * 返回当前执行脚本的绝对路径 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_scriptUrl = /example/index.php - * - * @throws WindException - * @return string - */ - public function getScriptUrl() { - if (!$this->_scriptUrl) $this->_initScriptUrl(); - return $this->_scriptUrl; - } - - /** - * 返回执行脚本 - */ - public function getScript() { - if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; - return substr($this->getScriptUrl(), $pos + 1); - } - - /** - * 获取Http头信息 - * @param string $header 头部名称 - * @return string|null - */ - public function getHeader($header, $default = null) { - $temp = strtoupper(str_replace('-', '_', $header)); - if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; - if (($header = $this->getServer($temp)) != null) return $header; - if (function_exists('apache_request_headers')) { - $headers = apache_request_headers(); - if ($headers[$header]) return $headers[$header]; - } - return $default; - } - - /** - * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 - * - * @throws WindException - * @return string - */ - public function getPathInfo() { - if (!$this->_pathInfo) $this->_initPathInfo(); - return $this->_pathInfo; - } - - /** - * 获取基础URL,这里是去除了脚本文件以及访问参数信息的URL地址信息 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_baseUrl = example - * return absolute url address when absolute is true - * 'example' will be return when absolute is false - * 'http://www.phpwind.net/example' will be return when absolute is true - * 'http://www.phpwind.net:80/example' will be return when absolute is true - * 'http://www.phpwind.net:443/example' will be return when absolute is true - * - * @param boolean $absolute - * @return string - */ - public function getBaseUrl($absolute = false) { - if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); - return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; - } - - /** - * 获得主机信息,包含协议信息,主机名,访问端口信息 - * - * @return string - */ - public function getHostInfo() { - if ($this->_hostInfo === null) $this->_initHostInfo(); - return $this->_hostInfo; - } - - /** - * 返回当前运行脚本所在的服务器的主机名。 - * 如果脚本运行于虚拟主机中 - * 该名称是由那个虚拟主机所设置的值决定 - * - * @return string|'' - */ - public function getServerName() { - return $this->getServer('SERVER_NAME', ''); - } - - /** - * 返回服务端口号 - * https链接的默认端口号为443 - * http链接的默认端口号为80 - * - * @return int - */ - public function getServerPort() { - if (!$this->_port) { - $_default = $this->isSecure() ? 443 : 80; - $this->setServerPort($this->getServer('SERVER_PORT', $_default)); - } - return $this->_port; - } - - /** - * 设置服务端口号 - * https链接的默认端口号为443 - * http链接的默认端口号为80 - * - * @param int $port - */ - public function setServerPort($port) { - $this->_port = (int) $port; - } - - /** - * 返回浏览当前页面的用户的主机名 - * DNS 反向解析不依赖于用户的 REMOTE_ADDR - * - * @return string|null - */ - public function getRemoteHost() { - return $this->getServer('REMOTE_HOST'); - } - - /** - * 返回浏览器发送Referer请求头,可以让服务器了解和追踪发出本次请求的起源URL地址 - * - * @return string|null - */ - public function getUrlReferer() { - return $this->getServer('HTTP_REFERER'); - } - - /** - * 获得用户机器上连接到 Web 服务器所使用的端口号 - * - * @return number|null - */ - public function getRemotePort() { - return $this->getServer('REMOTE_PORT'); - } - - /** - * 返回User-Agent头字段用于指定浏览器或者其他客户端程序的类型和名字 - * 如果客户机是一种无线手持终端,就返回一个WML文件;如果发现客户端是一种普通浏览器, - * 则返回通常的HTML文件 - * - * @return string - */ - public function getUserAgent() { - return $this->getServer('HTTP_USER_AGENT', ''); - } - - /** - * 返回当前请求头中 Accept: 项的内容, - * Accept头字段用于指出客户端程序能够处理的MIME类型,例如 text/html,image/* - * - * @return string|'' - */ - public function getAcceptTypes() { - return $this->getServer('HTTP_ACCEPT', ''); - } - - /** - * 返回客户端程序可以能够进行解码的数据编码方式,这里的编码方式通常指某种压缩方式 - * - * @return string|'' - */ - public function getAcceptCharset() { - return $this->getServer('HTTP_ACCEPT_ENCODING', ''); - } - - /** - * 返回客户端程序期望服务器返回哪个国家的语言文档 - * Accept-Language: en-us,zh-cn - * - * @return string - */ - public function getAcceptLanguage() { - if (!$this->_language) { - $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); - $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; - } - return $this->_language; - } - - /** - * 获得返回信息 - * @return WindHttpResponse - */ - public function getResponse() { - if ($this->_response === null) { - $this->_response = new WindHttpResponse(); - if ($this->getIsAjaxRequest()) { - $this->_response->addHeader('Content-type', 'text/xml;charset=utf-8'); - $this->_response->setIsAjax(true); - } else{ - $this->_response->addHeader('Content-type', 'text/html;charset=utf-8'); - } - } - return $this->_response; - } - - /** - * 返回访问的IP地址 - * - * Example: - * $this->_clientIp = 127.0.0.1 - * - * @return string - */ - private function _getClientIp() { - if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { - $this->_clientIp = $ip; - } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { - $ip = strtok($_ip, ','); - do { - $ip = ip2long($ip); - if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || - (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || - (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { - $this->_clientIp = long2ip($ip); - return; - } - } while (($ip = strtok(','))); - } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { - $this->_clientIp = $ip; - } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { - $this->_clientIp = $ip; - } else { - $this->_clientIp = "0.0.0.0"; - } - } - - /** - * 初始化请求的资源标识符 - * 这里的uri是去除协议名、主机名的 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_requestUri = /example/index.php?a=test - * - * @throws WindException - */ - private function initRequestUri() { - if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { - $this->_requestUri = $requestUri; - } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { - $this->_requestUri = $requestUri; - if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace( - '/^\w+:\/\/[^\/]+/', '', $this->_requestUri); - } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { - $this->_requestUri = $requestUri; - if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; - } else - throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); - } - - /** - * 初始化当前执行脚本的绝对路径 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_scriptUrl = /example/index.php - * - * @throws WindException - * @return - */ - private function _initScriptUrl() { - if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException( - __CLASS__ . ' determine the entry script URL failed!!!'); - $scriptName = basename($scriptName); - if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { - $this->_scriptUrl = $_scriptName; - } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { - $this->_scriptUrl = $_scriptName; - } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && - basename($_scriptName) === $scriptName) { - $this->_scriptUrl = $_scriptName; - } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { - $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; - } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && - ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && - strpos($_scriptName, $_documentRoot) === 0) { - $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); - } else - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); - } - - /** - * 获得主机信息,包含协议信息,主机名,访问端口信息 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_hostInfo = http://www.phpwind.net/ - * $this->_hostInfo = http://www.phpwind.net:80/ - * $this->_hostInfo = https://www.phpwind.net:443/ - * - * @throws WindException - * @return - */ - private function _initHostInfo() { - $http = $this->isSecure() ? 'https' : 'http'; - if (($httpHost = $this->getServer('HTTP_HOST')) != null) - $this->_hostInfo = $http . '://' . $httpHost; - elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { - $this->_hostInfo = $http . '://' . $httpHost; - if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; - } else - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); - } - - /** - * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 - * - * @throws WindException - * @return - */ - private function _initPathInfo() { - $requestUri = urldecode($this->getRequestUri()); - $scriptUrl = $this->getScriptUrl(); - $baseUrl = $this->getBaseUrl(); - if (strpos($requestUri, $scriptUrl) === 0) - $pathInfo = substr($requestUri, strlen($scriptUrl)); - elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) - $pathInfo = substr($requestUri, strlen($baseUrl)); - elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) - $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); - else - throw new WindException(''); - if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); - $this->_pathInfo = trim($pathInfo, '/'); - } - } \ No newline at end of file From ba13031ff76206804cf7b0f6023e5d755f3cae5f Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:07:51 +0000 Subject: [PATCH 0171/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2231 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/response/IWindResponse.php | 11 - wind/core/response/WindHttpResponse.php | 529 ------------------------ 2 files changed, 540 deletions(-) delete mode 100644 wind/core/response/IWindResponse.php delete mode 100644 wind/core/response/WindHttpResponse.php diff --git a/wind/core/response/IWindResponse.php b/wind/core/response/IWindResponse.php deleted file mode 100644 index 0c437993..00000000 --- a/wind/core/response/IWindResponse.php +++ /dev/null @@ -1,11 +0,0 @@ - 2010-11-7 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -interface IWindResponse { - -} \ No newline at end of file diff --git a/wind/core/response/WindHttpResponse.php b/wind/core/response/WindHttpResponse.php deleted file mode 100644 index 34133fc0..00000000 --- a/wind/core/response/WindHttpResponse.php +++ /dev/null @@ -1,529 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHttpResponse implements IWindResponse { - - private $_body = array(); - - private $_bodyIndex = array(); - - private $_headers = array(); - - private $_isRedirect = false; - - private $_status = ''; - - private $_isAjax = false; - - private $_data = array(); - - /* - * Server status codes; see RFC 2068. - * Status code (100) indicating the client can continue. - */ - const SC_CONTINUE = 100; - - /** - * Status code (101) indicating the server is switching protocols - * according to Upgrade header. - */ - const SC_SWITCHING_PROTOCOLS = 101; - - /** - * Status code (200) indicating the request succeeded normally. - */ - const SC_OK = 200; - - /** - * Status code (201) indicating the request succeeded and created - * a new resource on the server. - */ - const SC_CREATED = 201; - - /** - * Status code (202) indicating that a request was accepted for - * processing, but was not completed. - */ - const SC_ACCEPTED = 202; - - /** - * Status code (203) indicating that the meta information presented - * by the client did not originate from the server. - */ - const SC_NON_AUTHORITATIVE_INFORMATION = 203; - - /** - * Status code (204) indicating that the request succeeded but that - * there was no new information to return. - */ - const SC_NO_CONTENT = 204; - - /** - * Status code (205) indicating that the agent SHOULD reset - * the document view which caused the request to be sent. - */ - const SC_RESET_CONTENT = 205; - - /** - * Status code (206) indicating that the server has fulfilled - * the partial GET request for the resource. - */ - const SC_PARTIAL_CONTENT = 206; - - /** - * Status code (300) indicating that the requested resource - * corresponds to any one of a set of representations, each with - * its own specific location. - */ - const SC_MULTIPLE_CHOICES = 300; - - /** - * Status code (301) indicating that the resource has permanently - * moved to a new location, and that future references should use a - * new URI with their requests. - */ - const SC_MOVED_PERMANENTLY = 301; - - /** - * Status code (302) indicating that the resource has temporarily - * moved to another location, but that future references should - * still use the original URI to access the resource. - * - * This definition is being retained for backwards compatibility. - * SC_FOUND is now the preferred definition. - */ - const SC_MOVED_TEMPORARILY = 302; - - /** - * Status code (302) indicating that the resource reside - * temporarily under a different URI. Since the redirection might - * be altered on occasion, the client should continue to use the - * Request-URI for future requests.(HTTP/1.1) To represent the - * status code (302), it is recommended to use this variable. - */ - const SC_FOUND = 302; - - /** - * Status code (303) indicating that the response to the request - * can be found under a different URI. - */ - const SC_SEE_OTHER = 303; - - /** - * Status code (304) indicating that a conditional GET operation - * found that the resource was available and not modified. - */ - const SC_NOT_MODIFIED = 304; - - /** - * Status code (305) indicating that the requested resource - * MUST be accessed through the proxy given by the - * Location field. - */ - const SC_USE_PROXY = 305; - - /** - * Status code (307) indicating that the requested resource - * resides temporarily under a different URI. The temporary URI - * SHOULD be given by the Location - * field in the response. - */ - const SC_TEMPORARY_REDIRECT = 307; - - /** - * Status code (400) indicating the request sent by the client was - * syntactically incorrect. - */ - const SC_BAD_REQUEST = 400; - - /** - * Status code (401) indicating that the request requires HTTP - * authentication. - */ - const SC_UNAUTHORIZED = 401; - - /** - * Status code (402) reserved for future use. - */ - const SC_PAYMENT_REQUIRED = 402; - - /** - * Status code (403) indicating the server understood the request - * but refused to fulfill it. - */ - const SC_FORBIDDEN = 403; - - /** - * Status code (404) indicating that the requested resource is not - * available. - */ - const SC_NOT_FOUND = 404; - - /** - * Status code (405) indicating that the method specified in the - * Request-Line is not allowed for the resource - * identified by the Request-URI. - */ - const SC_METHOD_NOT_ALLOWED = 405; - - /** - * Status code (406) indicating that the resource identified by the - * request is only capable of generating response entities which have - * content characteristics not acceptable according to the accept - * headers sent in the request. - */ - const SC_NOT_ACCEPTABLE = 406; - - /** - * Status code (407) indicating that the client MUST first - * authenticate itself with the proxy. - */ - const SC_PROXY_AUTHENTICATION_REQUIRED = 407; - - /** - * Status code (408) indicating that the client did not produce a - * request within the time that the server was prepared to wait. - */ - const SC_REQUEST_TIMEOUT = 408; - - /** - * Status code (409) indicating that the request could not be - * completed due to a conflict with the current state of the - * resource. - */ - const SC_CONFLICT = 409; - - /** - * Status code (410) indicating that the resource is no longer - * available at the server and no forwarding address is known. - * This condition SHOULD be considered permanent. - */ - const SC_GONE = 410; - - /** - * Status code (411) indicating that the request cannot be handled - * without a defined Content-Length. - */ - const SC_LENGTH_REQUIRED = 411; - - /** - * Status code (412) indicating that the precondition given in one - * or more of the request-header fields evaluated to false when it - * was tested on the server. - */ - const SC_PRECONDITION_FAILED = 412; - - /** - * Status code (413) indicating that the server is refusing to process - * the request because the request entity is larger than the server is - * willing or able to process. - */ - const SC_REQUEST_ENTITY_TOO_LARGE = 413; - - /** - * Status code (414) indicating that the server is refusing to service - * the request because the Request-URI is longer - * than the server is willing to interpret. - */ - const SC_REQUEST_URI_TOO_LONG = 414; - - /** - * Status code (415) indicating that the server is refusing to service - * the request because the entity of the request is in a format not - * supported by the requested resource for the requested method. - */ - const SC_UNSUPPORTED_MEDIA_TYPE = 415; - - /** - * Status code (416) indicating that the server cannot serve the - * requested byte range. - */ - const SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; - - /** - * Status code (417) indicating that the server could not meet the - * expectation given in the Expect request header. - */ - const SC_EXPECTATION_FAILED = 417; - - /** - * Status code (500) indicating an error inside the HTTP server - * which prevented it from fulfilling the request. - */ - const SC_INTERNAL_SERVER_ERROR = 500; - - /** - * Status code (501) indicating the HTTP server does not support - * the functionality needed to fulfill the request. - */ - const SC_NOT_IMPLEMENTED = 501; - - /** - * Status code (502) indicating that the HTTP server received an - * invalid response from a server it consulted when acting as a - * proxy or gateway. - */ - const SC_BAD_GATEWAY = 502; - - /** - * Status code (503) indicating that the HTTP server is - * temporarily overloaded, and unable to handle the request. - */ - const SC_SERVICE_UNAVAILABLE = 503; - - /** - * Status code (504) indicating that the server did not receive - * a timely response from the upstream server while acting as - * a gateway or proxy. - */ - const SC_GATEWAY_TIMEOUT = 504; - - /** - * Status code (505) indicating that the server does not support - * or refuses to support the HTTP protocol version that was used - * in the request message. - */ - const SC_HTTP_VERSION_NOT_SUPPORTED = 505; - - /** - * 设置响应头信息,如果已经设置过同名的响应头,该方法将用新的设置取代原来的头字段 - * - * @param string $name 响应头的名称 - * @param string $value 响应头的字段取值 - */ - public function setHeader($name, $value, $replace = false) { - if (!$name || !$value) - return; - $name = $this->_normalizeHeader($name); - foreach ($this->_headers as $key => $one) { - ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, - 'replace' => $replace); - } - } - - /** - * 设置响应头信息,如果已经设置过同名的响应头,该方法将增加一个同名的响应头 - * - * @param string $name 响应头的名称 - * @param string $value 响应头的字段取值 - */ - public function addHeader($name, $value, $replace = false) { - if ($name == '' || $value == '') - return; - $name = $this->_normalizeHeader($name); - $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); - } - - /** - * 设置响应头状态码 - * - * @param int $status - * @param string $message - */ - public function setStatus($status, $message = '') { - if (!is_int($status) || $status < 100 || $status > 505) - return; - - $this->_status = (int) $status; - } - - /** - * 设置响应内容 - * - * @param string $content - * @param string $name - */ - public function setBody($content, $name = null) { - if (!$content) - return; - !$name && $name = 'default'; - array_unshift($this->_bodyIndex, $name); - $this->_body[$name] = $content; - } - - /** - * 添加cookie信息 - * - * @param Cookie $cookie - */ - public function addCookie(Cookie $cookie) { - - } - - /** - * 发送一个错误的响应信息 - * - * @param int $status - * @param string $message - */ - public function sendError($status = self::SC_NOT_FOUND, $message = '') { - if (!is_int($status) || $status < 400 || $status > 505) - return; - $this->setBody($message); - $this->setStatus($status); - $this->sendResponse(); - } - - /** - * 重定向一个响应信息 - * - * @param string $location - */ - public function sendRedirect($location, $status = 302) { - if (!is_int($status) || $status < 300 || $status > 399) - return; - - $this->addHeader('Location', $location, true); - $this->setStatus($status); - $this->_isRedirect = true; - $this->sendHeaders(); - exit(); - } - - /** - * 发送响应信息 - */ - public function sendResponse() { - $this->sendHeaders(); - $this->sendBody(); - exit(); - } - - /** - * 发送响应头部信息 - */ - public function sendHeaders() { - if ($this->isSendedHeader()) - return; - foreach ($this->_headers as $header) { - header($header['name'] . ': ' . $header['value'], $header['replace']); - } - header('HTTP/1.1 ' . $this->_status); - } - - /** - * 发送响应内容 - */ - public function sendBody() { - /*if ($this->_isAjax) echo "_bodyIndex as $key) - echo $this->_body[$key]; - /*if ($this->_isAjax) echo "]]>";*/ - } - - /** - * 获取内容 - * - * @param string $spec 内容的名称 - * @return string|null - */ - public function getBody($name = false) { - if ($name === false) { - ob_start(); - $this->sendBody(); - return ob_get_clean(); - } elseif ($name === true) { - return $this->_body; - } elseif (is_string($name) && isset($this->_body[$name])) - return $this->_body[$name]; - - return null; - } - - /** - * 是否已经发送了响应头部 - */ - public function isSendedHeader($throw = false) { - $sended = headers_sent($file, $line); - if ($throw && $sended) - throw new WindException(__CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); - - return $sended; - } - - /** - * 获取响应头信息 - * - * @return array - */ - public function getHeaders() { - return $this->_headers; - } - - /** - * 清理响应体信息 - */ - public function clearBody() { - $this->_body = array(); - } - - /** - * 清除响应头信息 - */ - public function clearHeaders() { - $this->_headers = array(); - } - - /** - * 格式化响应头信息 - * - * @param string $name - * @return string - */ - private function _normalizeHeader($name) { - $filtered = str_replace(array('-', '_'), ' ', (string) $name); - $filtered = ucwords(strtolower($filtered)); - $filtered = str_replace(' ', '-', $filtered); - return $filtered; - } - - /** - * @return the $_isAjax - */ - public function getIsAjax() { - return $this->_isAjax; - } - - /** - * @param field_type $_isAjax - */ - public function setIsAjax($_isAjax) { - $this->_isAjax = $_isAjax; - } - - /** - * @return array - */ - public function getData($key1 = '', $key2 = '') { - if (!$key1) - return $this->_data; - if (!$key2) - return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; - return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; - } - - /** - * @param $data - */ - public function setData($data, $key = '') { - if ($key) { - $this->_data[$key] = $data; - return; - } - if (is_object($data)) - $data = get_object_vars($data); - if (is_array($data)) - $this->_data += $data; - } - -} \ No newline at end of file From e088d76555ae881f9890e42a516cfe9bfed4157c Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:08:02 +0000 Subject: [PATCH 0172/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2232 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/router/AbstractWindRouter.php | 173 ------------------------ wind/core/router/WindUrlBasedRouter.php | 62 --------- 2 files changed, 235 deletions(-) delete mode 100644 wind/core/router/AbstractWindRouter.php delete mode 100644 wind/core/router/WindUrlBasedRouter.php diff --git a/wind/core/router/AbstractWindRouter.php b/wind/core/router/AbstractWindRouter.php deleted file mode 100644 index 29b90dca..00000000 --- a/wind/core/router/AbstractWindRouter.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class AbstractWindRouter extends WindModule { - const DEFAULT_ERROR_HANDLER = 'WIND:core.web.WindErrorHandler'; - const CONTROLLER_DEFAULT_PATH = 'controller'; - const CONTROLLER_DEFAULT_SUFFIX = 'Controller'; - /** - * 默认的处理方法‘run’ - * - * @var string - */ - private $action = 'run'; - /** - * 默认的控制器‘index’ - * - * @var string - */ - private $controller = 'index'; - /** - * 默认的系统应用模块名为‘default’ - * - * @var string - */ - private $module = 'default'; - /** - * 系统应用模块寻址路径 - * - * @var string - */ - protected $modulePath = ''; - - private $reParse = true; - - /** - * 该方法定义了路由解析策略 - * @return string | actionHandler - */ - abstract public function parse(); - - /** - * 构建Url并返回 - * @return string - */ - abstract public function buildUrl(); - - /** - * 通过调用该方法返回,解析请求参数,并返回路由结果 - * - * @return - */ - public function doParse() { - if ($this->reParse) { - $this->parse(); - $this->reParse = false; - } - $_moduleName = $this->getModule(); - if (!strcasecmp($this->getController(), 'windError')) { - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log( - '[core.roter.AbstractWindRouter.doParse] action hander: default error action :' . - self::DEFAULT_ERROR_HANDLER, WindLogger::LEVEL_DEBUG, 'wind.core'); - } - return $this->getSystemConfig()->getModuleErrorHandlerByModuleName($_moduleName, - self::DEFAULT_ERROR_HANDLER); - } - $_suffix = $this->getSystemConfig()->getModuleControllerSuffixByModuleName($_moduleName, - self::CONTROLLER_DEFAULT_SUFFIX); - if ($this->modulePath) - $_path = $this->modulePath; - else { - $_path = $this->getSystemConfig()->getModuleControllerPathByModuleName($_moduleName, - self::CONTROLLER_DEFAULT_PATH); - } - $_path .= '.' . ucfirst($this->controller) . $_suffix; - if (strpos($_path, ':') === false) - $_path = Wind::getAppName() . ':' . $_path; - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.router.AbstractWindRouter.doParse] action handler: ' . $_path, WindLogger::LEVEL_DEBUG, - 'wind.core'); - } - $this->destroy(); - return $_path; - } - - /** - * @return - */ - protected function destroy() { - $this->modulePath = ''; - } - - /** - * 设置module信息, 支持格式: - * 'moduleName'; - * 'namespace:modulePath' - * - * @param string $module - * @return - */ - public function setModule($module) { - if (false !== ($pos = strpos($module, ':'))) { - $this->modulePath = $module; - } else { - $this->module = $module; - $this->modulePath = ''; - } - } - - /** - * 获得业务操作 - * - * @return string - */ - public function getAction() { - return $this->action; - } - - /** - * 获得业务对象 - * - * @return string - */ - public function getController() { - return $this->controller; - } - - /** - * 返回一组应用入口 - * - * @return string - */ - public function getModule() { - return $this->module; - } - - /** - * 设置action信息 - * - * @param string $action - * @return - */ - public function setAction($action) { - $this->action = $action; - } - - /** - * 设置controller信息 - * - * @param string $controller - * @return - */ - public function setController($controller) { - $this->controller = $controller; - } - - /** - * @param boolean $reParse - * @return - */ - public function reParse() { - $this->reParse = true; - } - -} \ No newline at end of file diff --git a/wind/core/router/WindUrlBasedRouter.php b/wind/core/router/WindUrlBasedRouter.php deleted file mode 100644 index 2256706d..00000000 --- a/wind/core/router/WindUrlBasedRouter.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @link WRouteParser - * @package - */ -class WindUrlBasedRouter extends AbstractWindRouter { - /* url 路由参数规则 */ - const URL_PARAM = 'url-param'; - const DEFAULT_VALUE = 'default-value'; - /* 后缀名参数规则 */ - const CONTROLLER_SUFFIX = 'controller-suffix'; - const ACTION_SUFFIX = 'action-suffix'; - /* 路由信息 */ - const URL_RULE_MODULE = 'module'; - const URL_RULE_CONTROLLER = 'controller'; - const URL_RULE_ACTION = 'action'; - - /* (non-PHPdoc) - * @see AbstractWindRouter::parse() - */ - public function parse() { - $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->getModule())); - $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->getController())); - $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->getAction())); - } - - /* (non-PHPdoc) - * @see AbstractWindRouter::buildUrl() - */ - public function buildUrl() { - $module = $this->getUrlParamValue(self::URL_RULE_MODULE); - $controller = $this->getUrlParamValue(self::URL_RULE_CONTROLLER); - $action = $this->getUrlParamValue(self::URL_RULE_ACTION); - $url = '?' . $module . '=' . $this->getModule(); - $url .= '&' . $controller . '=' . $this->getController(); - $url .= '&' . $action . '=' . $this->getAction(); - return $url; - } - - /** - * 返回路由的配置信息 - * - * @param urlParam - * @param defaultValue - * @return string - */ - private function getUrlParamValue($type, $defaultValue = '') { - if ($_param = $this->getConfig($type, self::URL_PARAM)) { - $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE, $defaultValue); - return $this->getRequest()->getRequest($_param, $defaultValue); - } - return $defaultValue; - } -} \ No newline at end of file From 33a8bc510f8437805d0c89822a1fd7c437da5f54 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 26 Jul 2011 09:22:30 +0000 Subject: [PATCH 0173/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6--=E5=8E=BB=E9=99=A4=E6=96=87=E4=BB=B6=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=20=E9=85=8D=E7=BD=AE=E9=A1=B9=E7=9A=84=E5=B8=B8?= =?UTF-8?q?=E9=87=8F=E5=AE=9A=E4=B9=89=E5=8E=BB=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2233 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 14 +---- wind/component/cache/WindCache.php | 10 ++-- .../component/cache/strategy/WindApcCache.php | 12 ++--- wind/component/cache/strategy/WindDbCache.php | 43 +++++---------- .../cache/strategy/WindEacceleratorCache.php | 14 +++-- .../cache/strategy/WindFileCache.php | 14 +++-- .../component/cache/strategy/WindMemCache.php | 52 ++++--------------- .../component/cache/strategy/WindWinCache.php | 14 ++--- wind/component/cache/strategy/WindXCache.php | 14 +++-- .../cache/strategy/WindZendCache.php | 11 ++-- 10 files changed, 67 insertions(+), 131 deletions(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index dcb1cadc..c1fe1e48 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -50,16 +50,6 @@ abstract class AbstractWindCache extends WindModule { * @var string */ const EXPIRE = 'expires'; - /** - * 配置文件中缓存安全码名称的定义 - * @var string - */ - const SECURITYCODE = 'securityCode'; - /** - * 配置文件中缓存键的前缀名称的定义 - * @var string - */ - const KEYPREFIX = 'keyPrefix'; /** * 设置缓存,如果key不存在,设置缓存,否则,替换已有key的缓存。 @@ -238,8 +228,8 @@ public function setExpire($expire) { */ public function setConfig($config) { parent::setConfig($config); - $this->setSecurityCode($this->getConfig(self::SECURITYCODE, '', '')); - $this->setKeyPrefix($this->getConfig(self::KEYPREFIX, '', '')); + $this->setSecurityCode($this->getConfig('securityCode', '', '')); + $this->setKeyPrefix($this->getConfig('keyPrefix', '', '')); $this->setExpire($this->getConfig(self::EXPIRE, '', 0)); } } \ No newline at end of file diff --git a/wind/component/cache/WindCache.php b/wind/component/cache/WindCache.php index 4f2ea155..42c7f41a 100644 --- a/wind/component/cache/WindCache.php +++ b/wind/component/cache/WindCache.php @@ -1,11 +1,11 @@ 2011-07-21 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao */ - class WindCache extends WindModule { private $caches = array(); diff --git a/wind/component/cache/strategy/WindApcCache.php b/wind/component/cache/strategy/WindApcCache.php index 22d934a9..c6708ee0 100644 --- a/wind/component/cache/strategy/WindApcCache.php +++ b/wind/component/cache/strategy/WindApcCache.php @@ -1,12 +1,12 @@ 2011-07-21 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao */ -Wind::import('WIND:component.cache.AbstractWindCache'); - class WindApcCache extends AbstractWindCache { public function __construct(){ diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index 8672aa82..38a84235 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -1,11 +1,12 @@ 2011-7-18 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao */ -Wind::import('WIND:component.cache.AbstractWindCache'); class WindDbCache extends AbstractWindCache { /** @@ -48,25 +49,7 @@ class WindDbCache extends AbstractWindCache { * 缓存表过期时间字段 * @var string */ - private $connectionConfig = 'default'; - - /* - * 配置项常量定义 - */ - const DBCACHE = 'config'; - const DBCONFIG = 'dbconfig'; - - const CACHETABLE = 'cacheTables'; - - const TABLENAME = 'tableName'; - - const KEY = 'fieldKey'; - - const VALUE = 'fieldValue'; - - const EXPIRE = 'fieldExpire'; - - const CONNECTION = 'connection'; + private $connectionConfig = ''; public function __construct(WindConnection $connection = null, $config = array()) { $connection && $this->setConnection($connection); @@ -150,12 +133,12 @@ public function deleteExpiredCache() { */ public function setConfig($config) { parent::setConfig($config); - $config = $this->getConfig(self::CACHETABLE); - $this->table = $this->getConfig(self::TABLENAME, '', 'pw_cache', $config); - $this->keyField = $this->getConfig(self::KEY, '', 'key', $config); - $this->valueField = $this->getConfig(self::VALUE, '', 'value', $config); - $this->expireField = $this->getConfig(self::EXPIRE, '', 'expire', $config); - $this->connectionConfig = $this->getConfig(self::CONNECTION, '', 'default', $config); + $config = $this->getConfig('cacheTables'); + $this->table = $this->getConfig('tableName', '', 'pw_cache', $config); + $this->keyField = $this->getConfig('fieldKey', '', 'key', $config); + $this->valueField = $this->getConfig('fieldValue', '', 'value', $config); + $this->expireField = $this->getConfig('fieldExpire', '', 'expire', $config); + $this->connectionConfig = $this->getConfig('connection', '', 'default', $config); } /** diff --git a/wind/component/cache/strategy/WindEacceleratorCache.php b/wind/component/cache/strategy/WindEacceleratorCache.php index cfdb6d28..fd9ccf95 100644 --- a/wind/component/cache/strategy/WindEacceleratorCache.php +++ b/wind/component/cache/strategy/WindEacceleratorCache.php @@ -1,15 +1,13 @@ 2011-7-18 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - * @package - */ -Wind::import('WIND:component.cache.AbstractWindCache'); + +Wind::import('COM:cache.AbstractWindCache'); + /** * Eaccelerator是一款php加速器、优化器、编码器及动态内容缓存。 * WindEaccelerator实现Eaccelerator动态内容缓存功能。 + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao */ class WindEacceleratorCache extends AbstractWindCache { diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 318a33c3..8fc8a31f 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -1,14 +1,12 @@ 2011-7-18 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - * @package + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao */ -Wind::import('WIND:component.cache.AbstractWindCache'); -Wind::import('WIND:component.utility.WindFile'); - class WindFileCache extends AbstractWindCache { /** diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php index 1ff18e1a..9a21279f 100644 --- a/wind/component/cache/strategy/WindMemCache.php +++ b/wind/component/cache/strategy/WindMemCache.php @@ -1,13 +1,11 @@ 2011-7-18 - * @link http://www.cnblogs.com/xiaoyaoxia/ - * @copyright Copyright © 2011-2012 xiaoxiao - * @license - * @package + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao */ -Wind::import('WIND:component.cache.AbstractWindCache'); - class WindMemCache extends AbstractWindCache { /** @@ -22,34 +20,6 @@ class WindMemCache extends AbstractWindCache { */ protected $compress = 0; - /** - * 是否对缓存进行压缩,如果缓存的值较大,可进行压缩 - * @var int - */ - const COMPRESS = 'compress'; - - /** - * 取得memcache配置项 - * @var string - */ - const SERVERCONFIG = 'servers'; - - const HOST = 'host'; - - const PORT = 'port'; - - const PCONNECT = 'pconn'; - - const WEIGHT = 'weight'; - - const TIMEOUT = 'timeout'; - - const RETRY = 'retry'; - - const STATUS = 'status'; - - const FCALLBACK = 'fcallback'; - public function __construct() { if (!extension_loaded('Memcache')) { throw new WindException('WindMemCache requires PHP `Memcache` extension to be loaded !'); @@ -90,8 +60,8 @@ public function clear() { */ public function setConfig($config) { parent::setConfig($config); - $this->compress = $this->getConfig(self::COMPRESS, '', '0'); - $this->setServers($this->getConfig(self::SERVERCONFIG)); + $this->compress = $this->getConfig('compress', '', '0'); + $this->setServers($this->getConfig('servers')); } /** @@ -127,14 +97,14 @@ private function setServers($servers) { * @throws WindException */ private function setServer($server) { - if (!isset($server[self::HOST])) { + if (!isset($server['host'])) { throw new WindException('The memcache server ip address is not exist'); } - if (!isset($server[self::PORT])) { + if (!isset($server['port'])) { throw new WindException('The memcache server port is not exist'); } - $defaultServer = array(self::HOST => '', self::PORT => '', self::PCONNECT => true, self::WEIGHT => 1, - self::TIMEOUT => 15, self::RETRY => 15, self::STATUS => true, self::FCALLBACK => null); + $defaultServer = array('host' => '', 'port' => '', 'pconn' => true, 'weight' => 1, + 'timeout' => 15, 'retry' => 15, 'status' => true, 'fcallback' => null); list($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback) = array_values(array_merge($defaultServer, $server)); $this->memcache->addServer($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback); } diff --git a/wind/component/cache/strategy/WindWinCache.php b/wind/component/cache/strategy/WindWinCache.php index 71a03cce..0fb71a3e 100644 --- a/wind/component/cache/strategy/WindWinCache.php +++ b/wind/component/cache/strategy/WindWinCache.php @@ -1,12 +1,12 @@ 2011-07-21 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.cache.AbstractWindCache'); +Wind::import('COM:cache.AbstractWindCache'); +/** + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ class WindWinCache extends AbstractWindCache { public function __construct() { diff --git a/wind/component/cache/strategy/WindXCache.php b/wind/component/cache/strategy/WindXCache.php index 989b89ae..4da86c85 100644 --- a/wind/component/cache/strategy/WindXCache.php +++ b/wind/component/cache/strategy/WindXCache.php @@ -1,13 +1,11 @@ 2011-7-19 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - * @package +Wind::import('COM:cache.AbstractWindCache'); +/** + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao */ -Wind::import('WIND:component.cache.AbstractWindCache'); - class WindXCache extends AbstractWindCache { public function __construct() { diff --git a/wind/component/cache/strategy/WindZendCache.php b/wind/component/cache/strategy/WindZendCache.php index 4172455a..cb875cb7 100644 --- a/wind/component/cache/strategy/WindZendCache.php +++ b/wind/component/cache/strategy/WindZendCache.php @@ -1,12 +1,11 @@ 2011-07-21 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao */ -Wind::import('WIND:component.cache.AbstractWindCache'); - class WindZendCache extends AbstractWindCache { public function __construct() { From ebc6c3bec2b62730dd036aacf66247fea50916c1 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 26 Jul 2011 09:24:17 +0000 Subject: [PATCH 0174/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6--=E5=8E=BB=E9=99=A4=E6=96=87=E4=BB=B6=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=20=E9=85=8D=E7=BD=AE=E9=A1=B9=E7=9A=84=E5=B8=B8?= =?UTF-8?q?=E9=87=8F=E5=AE=9A=E4=B9=89=E5=8E=BB=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2234 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindFileCache.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 8fc8a31f..288b06d4 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -32,15 +32,6 @@ class WindFileCache extends AbstractWindCache { * @var array */ private $cacheFileList = array(); - - /* - * 配置项 - */ - const CACHEDIR = 'dir'; - - const SUFFIX = 'suffix'; - - const LEVEL = 'dirLevel'; /* (non-PHPdoc) * @see AbstractWindCache::setValue() @@ -195,9 +186,9 @@ public function __destruct() { */ public function setConfig($config) { parent::setConfig($config); - $this->setCacheDir($this->getConfig(self::CACHEDIR)); - $this->setCacheFileSuffix($this->getConfig(self::SUFFIX, '', 'txt')); - $this->setCacheDirectoryLevel($this->getConfig(self::LEVEL)); + $this->setCacheDir($this->getConfig('dir')); + $this->setCacheFileSuffix($this->getConfig('suffix', '', 'txt')); + $this->setCacheDirectoryLevel($this->getConfig('dirLevel', '', '0')); } } \ No newline at end of file From f9e5aaa46621bac688a2994c578a7a901005721f Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:34:19 +0000 Subject: [PATCH 0175/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2235 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 45 +++++++++++----------- wind/_compile/compile.php | 6 +++ wind/component/parser/WindConfigParser.php | 31 ++++++++------- wind/core/web/filter/WindUrlFilter.php | 2 - 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 136ea1b5..d3e0eccd 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -181,7 +181,7 @@ public static function autoLoad($className, $path = '') { if ($path === '') { throw new Exception('auto load ' . $className . ' failed.'); } - $path = self::getRealPath($path); + $path .= '.' . self::$_extensions; if ((include $path) === false) { throw new Exception('[wind.Wind.autoLoad] auto load class ' . $className . ' failed.'); } @@ -211,14 +211,16 @@ public static function getRootPath($namespace) { * @param boolean $info 是否为目录路径 * @return string|array('isPackage','fileName','extension','realPath') */ - public static function getRealPath($filePath, $suffix = '') { + public static function getRealPath($filePath, $suffix = 'php') { if (($pos = strpos($filePath, ':')) !== false) { $namespace = self::getRootPath(substr($filePath, 0, $pos)); if (!$namespace) return $filePath; $filePath = $namespace . D_S . str_replace('.', D_S, substr($filePath, $pos + 1)); } - !$suffix && $suffix = self::$_extensions; + if ($suffix === false) + return $filePath; + $suffix === '' && $suffix = self::$_extensions; return $filePath . '.' . $suffix; } @@ -372,10 +374,13 @@ function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/G */ private static function _setImport($className, $classPath) { self::$_imports[$classPath] = $className; - if (self::$_isAutoLoad) - self::$_classes[$className] = $classPath; - else - self::autoLoad($className, $classPath); + if (!isset(self::$_classes[$className])) { + $_classPath = self::getRealPath($classPath, false); + self::$_classes[$className] = $_classPath; + } else + $_classPath = self::$_classes[$className]; + if (!self::$_isAutoLoad) + self::autoLoad($className, $_classPath); } /** @@ -398,27 +403,16 @@ private static function _registerAutoloader() { */ private static function _loadBaseLib() { self::$_classes = array('WindLogger' => 'log/WindLogger', - 'IWindConfigParser' => 'core/config/parser/IWindConfigParser', - 'WindConfigParser' => 'core/config/parser/WindConfigParser', 'WindConfig' => 'core/config/WindConfig', - 'WindSystemConfig' => 'core/config/WindSystemConfig', 'WindActionException' => 'core/exception/WindActionException', 'WindException' => 'core/exception/WindException', 'WindFinalException' => 'core/exception/WindFinalException', 'IWindFactory' => 'core/factory/IWindFactory', 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', - 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', - 'WindClassDefinition' => 'core/factory/WindClassDefinition', 'WindFactory' => 'core/factory/WindFactory', - 'WindFilter' => 'core/filter/WindFilter', 'WindFilterChain' => 'core/filter/WindFilterChain', - 'WindHandlerInterceptor' => 'core/filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'core/filter/WindHandlerInterceptorChain', - 'IWindRequest' => 'core/request/IWindRequest', 'WindHttpRequest' => 'core/request/WindHttpRequest', - 'IWindResponse' => 'core/response/IWindResponse', 'WindHttpResponse' => 'core/response/WindHttpResponse', - 'AbstractWindRouter' => 'core/router/AbstractWindRouter', - 'WindUrlBasedRouter' => 'core/router/WindUrlBasedRouter', + 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', 'WindFactory' => 'core/factory/WindFactory', 'IWindController' => 'core/web/controller/IWindController', 'WindController' => 'core/web/controller/WindController', 'WindSimpleController' => 'core/web/controller/WindSimpleController', - 'WindLoggerFilter' => 'core/web/filter/WindLoggerFilter', 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', - 'IWindApplication' => 'core/web/IWindApplication', 'IWindErrorMessage' => 'core/web/IWindErrorMessage', + 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', 'IWindApplication' => 'core/web/IWindApplication', + 'IWindErrorMessage' => 'core/web/IWindErrorMessage', 'WindFormListener' => 'core/web/listener/WindFormListener', 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', 'WindValidateListener' => 'core/web/listener/WindValidateListener', @@ -427,7 +421,14 @@ private static function _loadBaseLib() { 'WindFrontController' => 'core/web/WindFrontController', 'WindUrlHelper' => 'core/web/WindUrlHelper', 'WindWebApplication' => 'core/web/WindWebApplication', 'WindEnableValidateModule' => 'core/WindEnableValidateModule', 'WindHelper' => 'core/WindHelper', - 'WindModule' => 'core/WindModule'); + 'WindModule' => 'core/WindModule', 'WindSystemConfig' => 'core/WindSystemConfig', + 'WindFilter' => 'filter/WindFilter', 'WindFilterChain' => 'filter/WindFilterChain', + 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', + 'WindConfigParser' => 'parser/WindConfigParser', 'IWindRequest' => 'http/request/IWindRequest', + 'WindHttpRequest' => 'http/request/WindHttpRequest', 'IWindResponse' => 'http/response/IWindResponse', + 'WindHttpResponse' => 'http/response/WindHttpResponse', 'AbstractWindRouter' => 'router/AbstractWindRouter', + 'WindUrlBasedRouter' => 'router/WindUrlBasedRouter'); } } Wind::init(); diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php index bd75e6f4..435ba019 100644 --- a/wind/_compile/compile.php +++ b/wind/_compile/compile.php @@ -8,6 +8,12 @@ Wind::clear(); Wind::import('COM:log.WindLogger'); Wind::import('WIND:core.*', true); +Wind::import('COM:filter.*', true); +Wind::import('COM:parser.WindConfigParser', true); +Wind::import('COM:http.request.*', true); +Wind::import('COM:http.response.*', true); +Wind::import('COM:router.*', true); + $imports = Wind::getImports(); /* 载入需要的文件信息 */ Wind::import('COM:utility.WindPack'); diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index 55bd70cd..d3a24856 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -1,4 +1,5 @@ doParser($configPath, $this->getConfigFormat($configPath)); - if (!$alias) return $result; + if (!$alias) + return $result; $config[$alias] = $result; $this->saveConfigFile($cacheFileName, $config); return $result; @@ -79,7 +82,8 @@ public function parse($configPath, $alias = '', $append = '') { */ private function getCacheContent($file) { $content = array(); - if (is_file($file)) $content = include ($file); + if (is_file($file)) + $content = include ($file); return is_array($content) ? $content : array(); } @@ -117,8 +121,10 @@ private function createParser($type) { * @return array 返回解析结果 */ private function doParser($configFile, $type) { - if (!$configFile) return array(); - if (!is_file($configFile)) throw new WindException('The file <' . $configFile . '> is not exists'); + if (!$configFile) + return array(); + if (!is_file($configFile)) + throw new WindException('The file <' . $configFile . '> is not exists'); if ($type == 'PHP') { $config = include ($configFile); return (isset($config['wind'])) ? $config['wind'] : $config; @@ -143,7 +149,8 @@ private function doParser($configFile, $type) { * @return boolean false:需要进行解析, true:不需要进行解析,直接读取缓存文件 */ private function needCompiled() { - if (IS_DEBUG && is_dir(COMPILE_PATH)) return true; + if (IS_DEBUG && is_dir(COMPILE_PATH)) + return true; return false; } @@ -155,7 +162,8 @@ private function needCompiled() { * @return boolean : true 解析文件格式成功,解析失败则抛出异常 */ private function getConfigFormat($configPath) { - if ($configPath === '') return self::CONFIG_XML; + if ($configPath === '') + return self::CONFIG_XML; $format = strtoupper(trim(strrchr($configPath, '.'), '.')); if (!in_array($format, $this->getConfigFormatList())) { throw new WindException("The format of the config file doesn't sopported yet!"); @@ -171,7 +179,8 @@ private function getConfigFormat($configPath) { * @return boolean 保存成功则返回true,保存失败则返回false */ private function saveConfigFile($filename, $data) { - if (!$filename || !$data || !is_dir(COMPILE_PATH)) return false; + if (!$filename || !$data || !is_dir(COMPILE_PATH)) + return false; Wind::import('COM:utility.WindFile'); return WindFile::savePhpData($filename, $data); } @@ -192,11 +201,7 @@ private function buildCacheFilePath($fileName) { * @return array 返回配置文件格式的白名单 */ private function getConfigFormatList() { - return array( - self::CONFIG_XML, - self::CONFIG_PHP, - self::CONFIG_INI, - self::CONFIG_PROPERTIES); + return array(self::CONFIG_XML, self::CONFIG_PHP, self::CONFIG_INI, self::CONFIG_PROPERTIES); } /** diff --git a/wind/core/web/filter/WindUrlFilter.php b/wind/core/web/filter/WindUrlFilter.php index f745c674..ec4622d6 100644 --- a/wind/core/web/filter/WindUrlFilter.php +++ b/wind/core/web/filter/WindUrlFilter.php @@ -1,7 +1,5 @@ * @author Qiong Wu * @version $Id$ From 3b19b5f969ffa28659076a6778cc0a066fe80e30 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 26 Jul 2011 09:59:05 +0000 Subject: [PATCH 0176/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2236 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/{web => }/IWindApplication.php | 0 .../{web/controller => }/IWindController.php | 0 wind/core/{web => }/IWindErrorMessage.php | 0 wind/core/IWindFrontController.php | 32 +++++++++++++++++++ .../web/{controller => }/WindController.php | 0 wind/core/web/WindFrontController.php | 5 +-- wind/core/{ => web}/WindHelper.php | 0 .../{controller => }/WindSimpleController.php | 0 wind/core/{ => web}/WindSystemConfig.php | 0 9 files changed, 35 insertions(+), 2 deletions(-) rename wind/core/{web => }/IWindApplication.php (100%) rename wind/core/{web/controller => }/IWindController.php (100%) rename wind/core/{web => }/IWindErrorMessage.php (100%) create mode 100644 wind/core/IWindFrontController.php rename wind/core/web/{controller => }/WindController.php (100%) rename wind/core/{ => web}/WindHelper.php (100%) rename wind/core/web/{controller => }/WindSimpleController.php (100%) rename wind/core/{ => web}/WindSystemConfig.php (100%) diff --git a/wind/core/web/IWindApplication.php b/wind/core/IWindApplication.php similarity index 100% rename from wind/core/web/IWindApplication.php rename to wind/core/IWindApplication.php diff --git a/wind/core/web/controller/IWindController.php b/wind/core/IWindController.php similarity index 100% rename from wind/core/web/controller/IWindController.php rename to wind/core/IWindController.php diff --git a/wind/core/web/IWindErrorMessage.php b/wind/core/IWindErrorMessage.php similarity index 100% rename from wind/core/web/IWindErrorMessage.php rename to wind/core/IWindErrorMessage.php diff --git a/wind/core/IWindFrontController.php b/wind/core/IWindFrontController.php new file mode 100644 index 00000000..f2cba621 --- /dev/null +++ b/wind/core/IWindFrontController.php @@ -0,0 +1,32 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindFrontController { + + /** + * @return WindsystemConfig + */ + public function getWindSystemConfig(); + + /** + * @return WindComponentFactory + */ + public function getWindFactory(); + + /** + * @return WindHttpRequest + */ + public function getRequest(); + + /** + * @return WindHttpResponse + */ + public function getResponse(); + +} + +?> \ No newline at end of file diff --git a/wind/core/web/controller/WindController.php b/wind/core/web/WindController.php similarity index 100% rename from wind/core/web/controller/WindController.php rename to wind/core/web/WindController.php diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 986641c4..9d5ce48d 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -10,7 +10,7 @@ * @version $Id$ * @package */ -class WindFrontController { +class WindFrontController implements IWindFrontController { /** * 框架系统配置信息资源地址,只接受php格式配置 */ @@ -76,7 +76,8 @@ public function run() { protected function getFilterChain() { $filterChainPath = $this->windSystemConfig->getFilterClass(); $filters = $this->windSystemConfig->getFilters(); - if (empty($filters) || empty($filterChainPath)) return null; + if (empty($filters) || empty($filterChainPath)) + return null; return $this->windFactory->createInstance($filterChainPath, array($filters)); } diff --git a/wind/core/WindHelper.php b/wind/core/web/WindHelper.php similarity index 100% rename from wind/core/WindHelper.php rename to wind/core/web/WindHelper.php diff --git a/wind/core/web/controller/WindSimpleController.php b/wind/core/web/WindSimpleController.php similarity index 100% rename from wind/core/web/controller/WindSimpleController.php rename to wind/core/web/WindSimpleController.php diff --git a/wind/core/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php similarity index 100% rename from wind/core/WindSystemConfig.php rename to wind/core/web/WindSystemConfig.php From 521ff08ce2b44956d4e0436e1532f83bd85b2277 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 26 Jul 2011 10:12:24 +0000 Subject: [PATCH 0177/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6--=E5=8E=BB=E9=99=A4=E6=96=87=E4=BB=B6=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=20=E9=85=8D=E7=BD=AE=E9=A1=B9=E7=9A=84=E5=B8=B8?= =?UTF-8?q?=E9=87=8F=E5=AE=9A=E4=B9=89=E5=8E=BB=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2237 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index c049afb9..d4c3fb89 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -75,10 +75,10 @@ - - + From 41d34cfbe14358816b238ddf63dbd56cba7c5d2d Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 26 Jul 2011 10:13:57 +0000 Subject: [PATCH 0178/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6--=E5=8E=BB=E9=99=A4=E6=96=87=E4=BB=B6=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=20=E9=85=8D=E7=BD=AE=E9=A1=B9=E7=9A=84=E5=B8=B8?= =?UTF-8?q?=E9=87=8F=E5=AE=9A=E4=B9=89=E5=8E=BB=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2238 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index d4c3fb89..dc841bd5 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -78,7 +78,7 @@ - + From e187dd1b41e55366f95967c745efcdd509f2b258 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 26 Jul 2011 10:17:40 +0000 Subject: [PATCH 0179/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6--=E5=8E=BB=E9=99=A4=E6=96=87=E4=BB=B6=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=20=E9=85=8D=E7=BD=AE=E9=A1=B9=E7=9A=84=E5=B8=B8?= =?UTF-8?q?=E9=87=8F=E5=AE=9A=E4=B9=89=E5=8E=BB=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2239 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindFileCache.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 288b06d4..ecd6b387 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -163,7 +163,7 @@ private function getCacheFileSuffix() { */ public function setCacheDirectoryLevel($cacheDirectoryLevel) { $cacheDirectoryLevel = intval($cacheDirectoryLevel); - $this->cacheDirectoryLevel = $cacheDirectoryLevel > 5 ? 5 : ($cacheDirectoryLevel < 1 ? 1 : $cacheDirectoryLevel); + $this->cacheDirectoryLevel = $cacheDirectoryLevel > 5 ? 5 : ($cacheDirectoryLevel < 0 ? 0 : $cacheDirectoryLevel); } /** @@ -178,7 +178,7 @@ private function getCacheDirectoryLevel() { * 垃圾回收,清理过期缓存 */ public function __destruct() { - $this->clear(true); +// $this->clear(true); } /* (non-PHPdoc) From 54936e5399e16e36aa2732bf5382b738b4d2ed4f Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 27 Jul 2011 02:22:39 +0000 Subject: [PATCH 0180/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2240 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/db_config.xml | 16 ++++++------ docs/configtemplate/dbcache_config.xml | 32 +++++++++++++++--------- docs/configtemplate/filecache_config.xml | 19 ++++++++------ docs/configtemplate/memcache_config.xml | 31 +++++++++++++++++------ 4 files changed, 64 insertions(+), 34 deletions(-) diff --git a/docs/configtemplate/db_config.xml b/docs/configtemplate/db_config.xml index 0343c17a..fa9959f5 100644 --- a/docs/configtemplate/db_config.xml +++ b/docs/configtemplate/db_config.xml @@ -1,9 +1,11 @@ - - mysql:host=localhost;dbname=test - root - root - utf8 - pw_ - + + + mysql:host=localhost;dbname=test + root + root + utf8 + pw_ + + \ No newline at end of file diff --git a/docs/configtemplate/dbcache_config.xml b/docs/configtemplate/dbcache_config.xml index 078cf251..87904407 100644 --- a/docs/configtemplate/dbcache_config.xml +++ b/docs/configtemplate/dbcache_config.xml @@ -1,16 +1,24 @@ - + + + 0 + + + + + - - - - - - - - - - - + + + default + + pw_cache + + key + + value + + expire + diff --git a/docs/configtemplate/filecache_config.xml b/docs/configtemplate/filecache_config.xml index 8c4e3b44..005d6a02 100644 --- a/docs/configtemplate/filecache_config.xml +++ b/docs/configtemplate/filecache_config.xml @@ -1,14 +1,17 @@ - + - - - + WIND:_compile - - - + php + + 0 + - + 0 + + + + diff --git a/docs/configtemplate/memcache_config.xml b/docs/configtemplate/memcache_config.xml index 388f0c85..9dd2554d 100644 --- a/docs/configtemplate/memcache_config.xml +++ b/docs/configtemplate/memcache_config.xml @@ -1,21 +1,38 @@ - + + + 0 + + + + + + + + 127.0.0.1 + 11211 + + true + + 1 + + 15 + + 15 + + true + + 127.0.0.1 11212 - - - - - - From 521c7775fa1bf0cd23d6a1908eec94deff785fbc Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 27 Jul 2011 02:23:50 +0000 Subject: [PATCH 0181/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2241 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/wind_config.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/configtemplate/wind_config.xml b/docs/configtemplate/wind_config.xml index a0e2adfc..a3b73b8f 100644 --- a/docs/configtemplate/wind_config.xml +++ b/docs/configtemplate/wind_config.xml @@ -42,5 +42,6 @@ +
\ No newline at end of file From 1ce21963ef4459134deb1692a39aca62f3cfe42f Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 03:41:44 +0000 Subject: [PATCH 0182/1065] =?UTF-8?q?rootpath=20=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=8C=E9=80=9A=E8=BF=87=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2242 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 3 ++- wind/core/web/WindFrontController.php | 1 - wind/core/web/WindSystemConfig.php | 29 ++++++++------------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index d3e0eccd..cece88a4 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -36,9 +36,10 @@ class Wind { * @throws WindException * @return */ - public static function run($appName = 'default', $config = '') { + public static function run($appName = 'default', $config = '', $rootPath = '') { self::beforRun(); if (!isset(self::$_app[$appName])) { + Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); $frontController = new WindFrontController($appName, $config); /* 将当前的app压入数组的开始 */ $_cache = self::getAppName(); diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 9d5ce48d..ca37cda6 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -89,7 +89,6 @@ protected function init($appName, $config) { $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); $this->windFactory = new WindFactory(@include ($configPath)); $this->windSystemConfig = new WindSystemConfig($config, $appName, $this->windFactory); - Wind::register($this->windSystemConfig->getRootPath(), $this->windSystemConfig->getAppName(), true); } /** diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index cd0fe287..a91ebfee 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -43,21 +43,6 @@ public function getAppName() { return $this->appName; } - /** - * 返回应用路径信息 - * - * @return string - */ - public function getRootPath() { - if (!$this->rootPath) { - $rootPath = $this->getConfig('root-path'); - if (!$rootPath) - $rootPath = dirname($_SERVER['SCRIPT_FILENAME']); - $this->rootPath = $rootPath; - } - return $this->rootPath; - } - /** * 返回当前应用的启动脚本位置 */ @@ -200,20 +185,22 @@ public function getCacheConfig($type = '') { } return $this->getConfig('cache', $type); } - + /** - * 获得DB配置 + * 获得DB配置,根据DB名义的别名来获取DB链接配置信息. + * 当别名为空时,返回全部DB链接配置. + * * @param string $type */ - public function getDbConfig($type = '') { - $config = $this->getConfig('db'); + public function getDbConfig($dbName = '') { + $config = $this->getConfig('db', 'config'); if (isset($config['resource'])) { $config = $this->parseResource($config['resource']); $this->_config['db'] = $config; } - return $this->getConfig('db', $type); + return $this->getConfig('db', $dbName); } - + /** * 解析resource的配置 * From a41124bdca61c63a47aed59fe3cdaa5ee3eebac5 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 04:58:00 +0000 Subject: [PATCH 0183/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=B8=AD=20=E2=80=98value=E2=80=99=E5=B1=9E=E6=80=A7=E5=88=A0?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2243 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 11 +++++----- wind/component/viewer/WindView.php | 32 ++++++++++++++++++++---------- wind/core/web/WindDispatcher.php | 10 ++++++---- wind/core/web/WindSystemConfig.php | 7 +++---- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index cece88a4..4628f060 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -40,11 +40,10 @@ public static function run($appName = 'default', $config = '', $rootPath = '') { self::beforRun(); if (!isset(self::$_app[$appName])) { Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); - $frontController = new WindFrontController($appName, $config); /* 将当前的app压入数组的开始 */ $_cache = self::getAppName(); array_unshift(self::$_currentApp, array($appName, $_cache)); - self::$_app[$appName] = $frontController; + self::$_app[$appName] = new WindFrontController($appName, $config); } self::getApp()->run(); self::afterRun(); @@ -329,8 +328,7 @@ protected static function resetApp() { * @return */ protected static function beforRun() { - self::profileBegin('WINDAPP', 'wind app run time profiles!', 'wind.profile'); - set_error_handler(array(new WindErrorHandler(), 'errorHandle'), error_reporting()); + set_error_handler(array(new WindErrorHandler(), 'errorHandle')); set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); } @@ -341,8 +339,8 @@ protected static function afterRun() { self::resetApp(); restore_error_handler(); restore_exception_handler(); - self::profileEnd('WINDAPP'); - self::getLogger()->flush(); + if (self::$_logger) + self::$_logger->flush(); } /** @@ -433,6 +431,7 @@ private static function _loadBaseLib() { } } Wind::init(); + /* 组件定义 */ define('COMPONENT_WEBAPP', 'windWebApp'); define('COMPONENT_ERRORHANDLER', 'errorHandler'); diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 13306c46..a2278dd9 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -46,7 +46,11 @@ class WindView extends WindModule { * @var boolean */ protected $isCache = false; - + /** + * 编译目录 + * + * @var string + */ protected $compileDir; /** * 视图解析引擎 @@ -75,9 +79,12 @@ public function render($forward, $router, $display = false) { return; } $this->setTemplateName($_templateName); - if ($_ext = $forward->getTemplateExt()) $this->setTemplateExt($_ext); - if ($_path = $forward->getTemplatePath()) $this->setTemplateDir($_path); - if ($_layout = $forward->getLayout()) $this->setLayout($_layout); + if ($_ext = $forward->getTemplateExt()) + $this->setTemplateExt($_ext); + if ($_path = $forward->getTemplatePath()) + $this->setTemplateDir($_path); + if ($_layout = $forward->getLayout()) + $this->setLayout($_layout); $viewResolver = $this->getViewResolver(); $viewResolver->windAssign($forward->getVars(), $_templateName); @@ -117,9 +124,12 @@ public function getCompileFile($template = '', $ext = '') { * @param $path */ private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) { - if (!$fileName) $fileName = $this->getTemplateName(); - if (!$fileExt) $fileExt = $this->getTemplateExt(); - if (strrpos($path, ':') === false) $path = Wind::getAppName() . ':' . $path; + if (!$fileName) + $fileName = $this->getTemplateName(); + if (!$fileExt) + $fileExt = $this->getTemplateExt(); + if (strrpos($path, ':') === false) + $path = Wind::getAppName() . ':' . $path; if ($ifCheckPath) { $dir = Wind::getRealDir($path); if (!is_dir($dir)) { @@ -137,10 +147,10 @@ private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) * @return */ public function init() { - $this->setTemplateDir($this->getConfig(self::TEMPLATE_DIR, 'value')); - $this->setCompileDir($this->getConfig(self::COMPILE_DIR, 'value')); - $this->setTemplateExt($this->getConfig(self::TEMPLATE_EXT, 'value')); - $this->setIsCache($this->getConfig(self::IS_CACHE, 'value')); + $this->setTemplateDir($this->getConfig(self::TEMPLATE_DIR)); + $this->setCompileDir($this->getConfig(self::COMPILE_DIR)); + $this->setTemplateExt($this->getConfig(self::TEMPLATE_EXT)); + $this->setIsCache($this->getConfig(self::IS_CACHE)); } /** diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php index 91396495..a72c68ee 100644 --- a/wind/core/web/WindDispatcher.php +++ b/wind/core/web/WindDispatcher.php @@ -60,8 +60,9 @@ protected function dispatchWithRedirect($app, $forward, $router) { $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { - throw new WindException('[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request ', - WindException::ERROR_SYSTEM_ERROR); + throw new WindFinalException( + '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . + $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->getUrlHelper()->checkUrl($_url); @@ -87,8 +88,9 @@ protected function dispatchWithAction($app, $forward, $router) { $_c && $router->setController($_c); $_m && $router->setModule($_m); if (!$this->checkProcess($router)) { - throw new WindException('[core.web.WindDispatcher.dispatchWithAction] Duplicate request ', - WindException::ERROR_SYSTEM_ERROR); + throw new WindFinalException( + '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . + $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } $app->processRequest(); } diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index a91ebfee..3667ee1d 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -7,7 +7,6 @@ * @package */ class WindSystemConfig extends WindModule { - private $rootPath = ''; private $appName = ''; /** @@ -150,7 +149,7 @@ public function getModuleViewConfigByModuleName($name, $default = '') { */ public function getModuleErrorHandlerByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('error-handler', 'class', $default, $module); + return $this->getConfig('error-handler', '', $default, $module); } /** @@ -160,7 +159,7 @@ public function getModuleErrorHandlerByModuleName($name, $default = '') { */ public function getModuleControllerPathByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('controller-path', 'value', $default, $module); + return $this->getConfig('controller-path', '', $default, $module); } /** @@ -170,7 +169,7 @@ public function getModuleControllerPathByModuleName($name, $default = '') { */ public function getModuleControllerSuffixByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('controller-suffix', 'value', $default, $module); + return $this->getConfig('controller-suffix', '', $default, $module); } /** From 6d0be050213b6324666aca51dcc4d36817553e4e Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 04:58:22 +0000 Subject: [PATCH 0184/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=B8=AD=20=E2=80=98value=E2=80=99=E5=B1=9E=E6=80=A7=E5=88=A0?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2244 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/db_config.xml | 3 +- ...er_config.xml => view_compiler_config.xml} | 0 docs/configtemplate/view_config.xml | 14 +++++++ docs/configtemplate/wind_config.xml | 38 +++++++++++++++---- 4 files changed, 46 insertions(+), 9 deletions(-) rename docs/configtemplate/{compiler_config.xml => view_compiler_config.xml} (100%) create mode 100644 docs/configtemplate/view_config.xml diff --git a/docs/configtemplate/db_config.xml b/docs/configtemplate/db_config.xml index fa9959f5..16c20920 100644 --- a/docs/configtemplate/db_config.xml +++ b/docs/configtemplate/db_config.xml @@ -1,7 +1,8 @@ - + + COM:db.WindConnection mysql:host=localhost;dbname=test root root diff --git a/docs/configtemplate/compiler_config.xml b/docs/configtemplate/view_compiler_config.xml similarity index 100% rename from docs/configtemplate/compiler_config.xml rename to docs/configtemplate/view_compiler_config.xml diff --git a/docs/configtemplate/view_config.xml b/docs/configtemplate/view_config.xml new file mode 100644 index 00000000..3d6e8c5a --- /dev/null +++ b/docs/configtemplate/view_config.xml @@ -0,0 +1,14 @@ + + + + + template + + htm + + data.template + + false + + + diff --git a/docs/configtemplate/wind_config.xml b/docs/configtemplate/wind_config.xml index a3b73b8f..55b73beb 100644 --- a/docs/configtemplate/wind_config.xml +++ b/docs/configtemplate/wind_config.xml @@ -3,7 +3,7 @@ - + @@ -24,24 +24,46 @@ - + controller - + Controller - + WIND:core.web.WindErrorHandler + - + template - + htm - + data.template - + + + + mysql:host=localhost;dbname=test + root + root + utf8 + pw_ + + + COM:db.WindConnection + mysql:host=localhost;dbname=test + root + root + utf8 + pw_ + + + COM:db.WindConnectionManager + + + \ No newline at end of file From a98b0ff0aee86ba740e425ad94b52339eabf4085 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 04:59:42 +0000 Subject: [PATCH 0185/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=B8=AD=20=E2=80=98value=E2=80=99=E5=B1=9E=E6=80=A7=E5=88=A0?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2245 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index dc841bd5..8c536763 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -27,7 +27,7 @@ - @@ -51,14 +51,15 @@ - - - - - + template + htm + compile.template + false + + Date: Wed, 27 Jul 2011 08:50:30 +0000 Subject: [PATCH 0186/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=B8=AD=20=E2=80=98value=E2=80=99=E5=B1=9E=E6=80=A7=E5=88=A0?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2246 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/wind_config.xml | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/docs/configtemplate/wind_config.xml b/docs/configtemplate/wind_config.xml index 55b73beb..39813b35 100644 --- a/docs/configtemplate/wind_config.xml +++ b/docs/configtemplate/wind_config.xml @@ -44,15 +44,8 @@ - - - mysql:host=localhost;dbname=test - root - root - utf8 - pw_ - - + + COM:db.WindConnection mysql:host=localhost;dbname=test root @@ -60,10 +53,6 @@ utf8 pw_ - - COM:db.WindConnectionManager - - - + \ No newline at end of file From df1bed2ef6feb58282609a780d976cb22a2ed70f Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 08:51:29 +0000 Subject: [PATCH 0187/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2247 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index 4628f060..14dd4f1a 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -211,7 +211,7 @@ public static function getRootPath($namespace) { * @param boolean $info 是否为目录路径 * @return string|array('isPackage','fileName','extension','realPath') */ - public static function getRealPath($filePath, $suffix = 'php') { + public static function getRealPath($filePath, $suffix = '') { if (($pos = strpos($filePath, ':')) !== false) { $namespace = self::getRootPath(substr($filePath, 0, $pos)); if (!$namespace) From d18d73593ab9bc5ea722a9c7e6db83087a8d87d9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 08:51:35 +0000 Subject: [PATCH 0188/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2248 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDao.php | 16 ++++++-------- wind/component/dao/WindDaoFactory.php | 31 ++++++++++++++++----------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php index ed9bbb02..e568c236 100644 --- a/wind/component/dao/WindDao.php +++ b/wind/component/dao/WindDao.php @@ -12,7 +12,7 @@ class WindDao extends WindModule { * 链接配置文件或是配置数组 * @var string|array */ - protected $configName = ''; + protected $dbName = ''; /** * cache类型定义 * @@ -26,6 +26,9 @@ class WindDao extends WindModule { */ protected $cacheConfig = ''; + /** + * @var object + */ protected $connection = null; private $cacheHandler = null; @@ -42,12 +45,7 @@ public function getCacheMethods() { * @return WindConnection */ public function getConnection() { - $connection = $this->_getConnection(); - if ($connection instanceof WindConnection) { - return $connection; - } - if ($connection instanceof WindConnectionManager) - return $connection->getConnection(); + return $this->_getConnection(); } /** @@ -60,8 +58,8 @@ public function getCacheHandler() { /** * @return the $configName */ - public function getConfigName() { - return $this->configName; + public function getDBName() { + return $this->dbName; } /** diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index 058b1082..910780ab 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -41,7 +41,8 @@ public function getDao($className) { if (strpos($className, ":") === false && strpos($className, ".") === false) { $className = $this->getDaoResource() . '.' . $className; } - if (isset($this->daos[$className])) return $this->daos[$className]; + if (isset($this->daos[$className])) + return $this->daos[$className]; $className = Wind::import($className); $daoInstance = WindFactory::createInstance($className); @@ -81,12 +82,14 @@ public function setDaoResource($daoResource) { private function registerCacheListener($daoInstance) { $caches = (array) $daoInstance->getCacheMethods(); foreach ($caches as $classMethod => $classPath) { - if (!$classMethod) continue; + if (!$classMethod) + continue; if ($classPath === 'default') $_className = Wind::import('COM:dao.listener.WindDaoCacheListener'); else $_className = Wind::import($classPath); - if (!$_className) continue; + if (!$_className) + continue; $daoInstance->registerEventListener($classMethod, new $_className($daoInstance)); } } @@ -97,17 +100,18 @@ private function registerCacheListener($daoInstance) { * @param WindDao $daoObject */ protected function createDbConnection($daoObject) { - $configName = $daoObject->getConfigName() ? $daoObject->getConfigName() : 'default'; - $alias = 'db_' . $configName; + if (!($configName = $daoObject->getDBName())) + $alias = 'db_default'; + else + $alias = 'db_' . $configName; if (!$this->getSystemFactory()->checkAlias($alias)) { $config = $this->getSystemConfig()->getDbConfig($configName); - $definition = array( - 'path' => $this->getConfig('class', '', 'COM:db.WindConnection', $config), - 'alias' => $alias, - 'config' => $config, - 'initMethod' => 'init', - 'scope' => 'application', - ); + if (!$config) + throw new WindDbException('[component.dao.WindDaoFactory.createDbConnection] (' . $configName . ')', + WindDbException::DB_CONN_NOT_EXIST); + $_path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); + $definition = array('path' => $_path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', + 'scope' => 'application'); $this->getSystemFactory()->addClassDefinitions($alias, $definition); } $daoObject->setDelayAttributes(array('connection' => array('ref' => $alias))); @@ -119,7 +123,8 @@ protected function createDbConnection($daoObject) { * @param WindDao $daoObject */ protected function createCacheHandler($daoObject) { - if (!($_className = $daoObject->getCacheClass())) return; + if (!($_className = $daoObject->getCacheClass())) + return; $_classConfig = $daoObject->getCacheConfig(); $_alias = $_className . '_' . md5((is_string($_classConfig) ? $_classConfig : serialize($_classConfig))); if (!$this->getSystemFactory()->checkAlias($_alias)) { From d0a15b58adae895a34687ca889e8bdf1db3065a7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 08:51:41 +0000 Subject: [PATCH 0189/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2249 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindModule.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 4d1991e2..2dc3cfc9 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -136,16 +136,14 @@ protected function validatePropertyName($propertyName, $value = null) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, - 'wind.core'); + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, - 'wind.core'); + (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { @@ -176,8 +174,10 @@ public function getConfig($configName = '', $subConfigName = '', $default = '', return $config; if (!isset($config[$configName])) return $default; - if ($subConfigName === '' || !isset($config[$configName][$subConfigName])) + if ($subConfigName === '') return $config[$configName]; + if (!isset($config[$configName][$subConfigName])) + return $default; return $config[$configName][$subConfigName]; } @@ -195,7 +195,7 @@ public function setConfig($config) { $config = $configParser->parse($config, get_class($this), 'cache_wind_config'); } if (!$this->_config) { - $this->_config = array_merge($this->_config, $config); + $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } From 278ea54459a448c0a9efacdea334583337deb335 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 08:51:49 +0000 Subject: [PATCH 0190/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2250 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 26 ++++++++++++++------- wind/core/web/WindSystemConfig.php | 36 +++++++++++++++++++----------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 48db585c..6a30ea12 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -52,9 +52,10 @@ public function getInstance($alias, $args = array()) { } elseif (isset($_subDefinition['ref'])) $args[] = $this->getInstance($_subDefinition['ref']); } + $config = $this->buildConfig($definition, $alias); $instance = $this->createInstance($definition['className'], $args); - if ($definition['config']) - $this->buildConfig($definition['config'], $instance); + if (!empty($config)) + $instance->setConfig($config); if ($definition['properties']) $this->buildProperties($definition['properties'], $instance); if ($definition['initMethod']) @@ -88,14 +89,23 @@ protected function setScope($alias, $scope, $instance) { /** * 为类对象设置配置 * - * @param WindModule $instance - * @param WindFactory $factory + * @param array|string $config + * @param string $alias * @return */ - protected function buildConfig($config, $instance) { - if (isset($config['resource'])) - $config = $config['resource']; - $instance->setConfig($config); + protected function buildConfig(&$definition, $alias) { + if (!($config = $definition['config'])) + return array(); + if (isset($config['resource']) && !empty($config['resource'])) { + $_configPath = Wind::getRealPath($config['resource'], false); + $configParser = $this->getInstance(COMPONENT_CONFIGPARSER); + $config = $configParser->parse($_configPath, $alias, 'cache_wind_config'); + } + if (isset($config['class']) && !$definition['path']) { + $definition['path'] = $config['class']; + $definition['className'] = Wind::import($definition['path']); + } + return $config; } /** diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 3667ee1d..c5cfb413 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -23,16 +23,12 @@ public function __construct($config, $appName, $factory) { * @see WindModule::setConfig() */ public function setConfig($config, $factory = null) { - if (!$config) - return; if (is_string($config)) { - $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($config, $this->appName . '_config'); - } - if (isset($config[$this->appName])) { - $this->_config = $config[$this->appName]; + $config = $this->parseConfig($config, '', '', $factory); + if (isset($config[$this->appName])) + $this->_config = $config[$this->appName]; } else - $this->_config = $config; + $this->_config = (array) $config; } /** @@ -189,17 +185,31 @@ public function getCacheConfig($type = '') { * 获得DB配置,根据DB名义的别名来获取DB链接配置信息. * 当别名为空时,返回全部DB链接配置. * - * @param string $type + * @param string $dbName */ public function getDbConfig($dbName = '') { - $config = $this->getConfig('db', 'config'); - if (isset($config['resource'])) { - $config = $this->parseResource($config['resource']); - $this->_config['db'] = $config; + $config = $this->getConfig('db'); + if (isset($config['resource']) && !empty($config['resource'])) { + $_resource = Wind::getRealPath($config['resource'], false); + $this->_config['db'] = $this->parseConfig($_resource, 'db', true); } return $this->getConfig('db', $dbName); } + /** + * @param string $config + * @param factory + */ + private function parseConfig($config, $key = 'config', $append = '', $factory = null) { + if ($factory === null) + $factory = $this->getSystemFactory(); + $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); + $key = $this->appName . '_' . $key; + $append === true && $append = $this->appName . '_config'; + $config = $configParser->parse($config, $key, $append); + return $config; + } + /** * 解析resource的配置 * From dba21428556a9d720063472af9b2e1d1f6c5b1ee Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 08:54:30 +0000 Subject: [PATCH 0191/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2251 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindSystemConfig.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index c5cfb413..44a1cd9c 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -191,16 +191,19 @@ public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], false); - $this->_config['db'] = $this->parseConfig($_resource, 'db', true); + $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } /** + * 配置解析方法 * @param string $config + * @param string $key + * @param string|boolean $append * @param factory */ - private function parseConfig($config, $key = 'config', $append = '', $factory = null) { + private function parseConfig($config, $key = 'config', $append = true, $factory = null) { if ($factory === null) $factory = $this->getSystemFactory(); $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); From c20fcc44736fd728cfd586551b721239ad9854bf Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 27 Jul 2011 09:07:41 +0000 Subject: [PATCH 0192/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2252 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 8c536763..ac2a0e13 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -50,7 +50,7 @@ - + template htm compile.template @@ -59,28 +59,33 @@ - + - + - + - + - + + compile + + + + + + compile.cache + From 148b8c2b0a6ff920344bb45487b540aa10917b8a Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 09:19:33 +0000 Subject: [PATCH 0193/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2253 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/http/response/WindHttpResponse.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index 34133fc0..d0093199 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -396,7 +396,6 @@ public function sendRedirect($location, $status = 302) { public function sendResponse() { $this->sendHeaders(); $this->sendBody(); - exit(); } /** From d23255911160b04956932034741a78738195e590 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 09:22:27 +0000 Subject: [PATCH 0194/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2254 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 14dd4f1a..f213d311 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -37,16 +37,24 @@ class Wind { * @return */ public static function run($appName = 'default', $config = '', $rootPath = '') { - self::beforRun(); + self::beforRun($appName, $config, $rootPath); if (!isset(self::$_app[$appName])) { Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); - /* 将当前的app压入数组的开始 */ - $_cache = self::getAppName(); - array_unshift(self::$_currentApp, array($appName, $_cache)); self::$_app[$appName] = new WindFrontController($appName, $config); - } + } else + unset(self::$_currentApp[$appName]); + /*foreach (self::$_currentApp as $key => $value) { + if ($value[0] == $appName) { + unset(self::$_currentApp[$key]); + } + }*/ + + /* 将当前的app压入数组的开始 */ + $_cache = self::getAppName(); + self::$_currentApp[0] = array($appName, $_cache); + //array_unshift(self::$_currentApp, array($appName, $_cache)); self::getApp()->run(); - self::afterRun(); + self::afterRun($appName, $config, $rootPath); } /** @@ -316,18 +324,23 @@ protected static function resetApp() { $_current = self::$_currentApp[0]; if ($_current[1] === '') return; - foreach (self::$_currentApp as $key => $value) { + self::$_currentApp[$_current[0]] = $_current; + self::$_currentApp[0] = self::$_currentApp[$_current[1]]; + unset(self::$_currentApp[$_current[1]]); + /*foreach (self::$_currentApp as $key => $value) { if ($value[0] == $_current[1]) { array_unshift(self::$_currentApp, $value); unset(self::$_currentApp[$key]); } - } + }*/ } /** * @return */ - protected static function beforRun() { + protected static function beforRun($appName, $config, $rootPath) { + if ($appName === 0) + throw new WindException('unsupported appName (' . $appName . ')', WindException::ERROR_SYSTEM_ERROR); set_error_handler(array(new WindErrorHandler(), 'errorHandle')); set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); } @@ -335,7 +348,7 @@ protected static function beforRun() { /** * @return */ - protected static function afterRun() { + protected static function afterRun($appName, $config, $rootPath) { self::resetApp(); restore_error_handler(); restore_exception_handler(); From dc3d4ba0071ef366e906d65b2adacb7abc2a503c Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 09:22:35 +0000 Subject: [PATCH 0195/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2255 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 123 ++++++++++---------------- wind/core/web/WindFrontController.php | 8 +- 2 files changed, 51 insertions(+), 80 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 6a30ea12..4cd4bbd5 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -67,6 +67,53 @@ public function getInstance($alias, $args = array()) { return $instance; } + /* (non-PHPdoc) + * @see AbstractWindFactory::createInstance() + */ + static public function createInstance($className, $args = array()) { + try { + if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { + Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, + WindLogger::LEVEL_DEBUG, 'core.factory'); + } + $reflection = new ReflectionClass($className); + return call_user_func_array(array($reflection, 'newInstance'), (array) $args); + } catch (Exception $e) { + throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); + } + } + + /* (non-PHPdoc) + * @see IWindFactory::getPrototype() + */ + public function getPrototype($alias) { + $instance = $this->getInstance($alias); + if ($instance === null) + return null; + return clone $instance; + } + + /** + * 动态添加类定义对象 + * + * @param string $alias + * @param array $classDefinition + * @return + */ + public function addClassDefinitions($alias, $classDefinition) { + $this->classDefinitions[$alias] = $classDefinition; + } + + /** + * 类定义检查,检查类型以是否已经存在 + * + * @param array $definition + * @return boolean + */ + public function checkAlias($alias) { + return isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : false; + } + /** * @param string $alias * @param string $scope @@ -177,80 +224,4 @@ private function buildDefinition(&$definition) { return true; } - /* (non-PHPdoc) - * @see IWindFactory::getPrototype() - */ - public function getPrototype($alias) { - $instance = $this->getInstance($alias); - if ($instance === null) - return null; - return clone $instance; - } - - /* (non-PHPdoc) - * @see AbstractWindFactory::createInstance() - */ - static public function createInstance($className, $args = array()) { - try { - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, - WindLogger::LEVEL_DEBUG, 'core.factory'); - } - $reflection = new ReflectionClass($className); - return call_user_func_array(array($reflection, 'newInstance'), (array) $args); - } catch (Exception $e) { - throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); - } - } - - /** - * @param string $classAlias - * @return boolean - */ - public function setSingled($classAlias, $instance) { - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.factory.WindFactory.createInstance] create singled instance:' . $classAlias, - WindLogger::LEVEL_DEBUG, 'core.factory'); - } - $this->instances[$classAlias] = $instance; - } - - /** - * 获得类定义对象 - * - * @param string $classAlias - * @return WindClassDefinition - */ - protected function getClassDefinitionByAlias($classAlias) { - if (!($definition = $this->classDefinitions[$classAlias])) - return null; - if ($definition instanceof WindClassDefinition) - return $definition; - $classDefinition = self::createInstance('WindClassDefinition', array($definition)); - $classDefinition->setAlias($classAlias); - $this->addClassDefinitions($classDefinition); - return $classDefinition; - } - - /** - * 动态添加类定义对象 - * - * @param string $alias - * @param array $classDefinition - * @return - */ - public function addClassDefinitions($alias, $classDefinition) { - $this->classDefinitions[$alias] = $classDefinition; - } - - /** - * 类定义检查,检查类型以是否已经存在 - * - * @param array $definition - * @return boolean - */ - public function checkAlias($alias) { - return isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : false; - } - } \ No newline at end of file diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index ca37cda6..731c8ec1 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -74,11 +74,11 @@ public function run() { * @return WindFilterChain */ protected function getFilterChain() { - $filterChainPath = $this->windSystemConfig->getFilterClass(); - $filters = $this->windSystemConfig->getFilters(); - if (empty($filters) || empty($filterChainPath)) + if (!($filters = $this->windSystemConfig->getFilters())) return null; - return $this->windFactory->createInstance($filterChainPath, array($filters)); + if (!($filterChainPath = $this->windSystemConfig->getFilterClass())) + return null; + return $this->getWindFactory()->createInstance($filterChainPath, array($filters)); } /** From 33664d3debd88482cd7f72dbf602fcb427318e10 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 09:34:00 +0000 Subject: [PATCH 0196/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2256 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index f213d311..4e6061b6 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -42,17 +42,19 @@ public static function run($appName = 'default', $config = '', $rootPath = '') { Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); self::$_app[$appName] = new WindFrontController($appName, $config); } else - unset(self::$_currentApp[$appName]); - /*foreach (self::$_currentApp as $key => $value) { + foreach (self::$_currentApp as $key => $value) { if ($value[0] == $appName) { unset(self::$_currentApp[$key]); } - }*/ - + } + /* 将当前的app压入数组的开始 */ $_cache = self::getAppName(); - self::$_currentApp[0] = array($appName, $_cache); - //array_unshift(self::$_currentApp, array($appName, $_cache)); + if ($_cache === $appName) + throw new WindException('Duplicate app.', WindException::ERROR_SYSTEM_ERROR); + + //self::$_currentApp[0] = array($appName, $_cache); + array_unshift(self::$_currentApp, array($appName, $_cache)); self::getApp()->run(); self::afterRun($appName, $config, $rootPath); } @@ -324,15 +326,16 @@ protected static function resetApp() { $_current = self::$_currentApp[0]; if ($_current[1] === '') return; - self::$_currentApp[$_current[0]] = $_current; - self::$_currentApp[0] = self::$_currentApp[$_current[1]]; - unset(self::$_currentApp[$_current[1]]); - /*foreach (self::$_currentApp as $key => $value) { + + /*self::$_currentApp[$_current[0]] = $_current; + self::$_currentApp[0] = self::$_currentApp[$_current[1]];*/ + //unset(self::$_currentApp[$_current[1]]); + foreach (self::$_currentApp as $key => $value) { if ($value[0] == $_current[1]) { array_unshift(self::$_currentApp, $value); unset(self::$_currentApp[$key]); } - }*/ + } } /** From 97bd76155fdbe4804df2f94cc6f7b0a80e5dea23 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 09:36:10 +0000 Subject: [PATCH 0197/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2257 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index 4e6061b6..2510f534 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -9,7 +9,7 @@ /* debug/log */ !defined('IS_DEBUG') && define('IS_DEBUG', 1); !defined('LOG_DIR') && define('LOG_DIR', COMPILE_PATH . 'log'); -!defined('LOG_WRITE_LEVEL') && define('LOG_WRITE_LEVEL', 2); +!defined('LOG_WRITE_LEVEL') && define('LOG_WRITE_LEVEL', 0); define('DEBUG_TIME', microtime(true)); /** * the last known user to change this file in the repository <$LastChangedBy: yishuo $> From 593ecf97e01ebcf8f5583cae39d1c2c76af36509 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 27 Jul 2011 09:53:20 +0000 Subject: [PATCH 0198/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2258 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 16 ++++---- wind/_compile/components_config.xml | 3 +- .../cache/strategy/WindFileCache.php | 1 + wind/component/parser/IWindConfigParser.php | 4 +- wind/component/parser/WindConfigParser.php | 37 +++++++++---------- wind/core/web/WindSystemConfig.php | 8 ++-- 6 files changed, 34 insertions(+), 35 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 2510f534..e7be52b9 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -38,6 +38,14 @@ class Wind { */ public static function run($appName = 'default', $config = '', $rootPath = '') { self::beforRun($appName, $config, $rootPath); + /* 将当前的app压入数组的开始 */ + $_cache = self::getAppName(); + if ($_cache === $appName) + throw new WindException('Duplicate app.', WindException::ERROR_SYSTEM_ERROR); + + //self::$_currentApp[0] = array($appName, $_cache); + array_unshift(self::$_currentApp, array($appName, $_cache)); + if (!isset(self::$_app[$appName])) { Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); self::$_app[$appName] = new WindFrontController($appName, $config); @@ -47,14 +55,6 @@ public static function run($appName = 'default', $config = '', $rootPath = '') { unset(self::$_currentApp[$key]); } } - - /* 将当前的app压入数组的开始 */ - $_cache = self::getAppName(); - if ($_cache === $appName) - throw new WindException('Duplicate app.', WindException::ERROR_SYSTEM_ERROR); - - //self::$_currentApp[0] = array($appName, $_cache); - array_unshift(self::$_currentApp, array($appName, $_cache)); self::getApp()->run(); self::afterRun($appName, $config, $rootPath); } diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index ac2a0e13..ce91561d 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -81,10 +81,9 @@ compile - - compile.cache + compile diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index ecd6b387..dbfdb0b4 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -68,6 +68,7 @@ public function clear($isExpired = false) { * @return string */ protected function buildSecurityKey($key) { + $key = str_replace(D_S, '', $key); if (($dir = $this->checkCacheDir($key)) !== false) return $dir; $filename = parent::buildSecurityKey($key) . '.' . trim($this->getCacheFileSuffix(), '.'); $_tmp = $this->getCacheDir(); diff --git a/wind/component/parser/IWindConfigParser.php b/wind/component/parser/IWindConfigParser.php index 1bb9ad2a..063f9970 100644 --- a/wind/component/parser/IWindConfigParser.php +++ b/wind/component/parser/IWindConfigParser.php @@ -18,9 +18,9 @@ interface IWindConfigParser { * * @param string $name 解析后保存的文件名字 * @param string $configPath 待解析文件的绝对路径 - * @param boolean $isApp 判断是应用解析还是组件配置解析 + * @param AbstractWindCache $cache 缓存策略 * @return array 解析成功返回的数据 */ - public function parse($configPath, $alias = '', $append = ''); + public function parse($configPath, $alias = '', AbstractWindCache $cache = null); } \ No newline at end of file diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index d3a24856..4af629b4 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -50,16 +50,14 @@ public function __construct() {} * * @param string $configPath 待解析的文件路径 * @param string $alias 解析后保存的key名 - * @param string $append 采用最佳的方法追加到$appandName指定的文件中 + * @param AbstractWindCache $cache 缓存策略 * @return array 解析结果 */ - public function parse($configPath, $alias = '', $append = '') { + public function parse($configPath, $alias = '', AbstractWindCache $cache = null) { $config = array(); $alias = trim($alias); - $append = !$append ? '' : trim($append); - $alias && $cacheFileName = ($append ? $this->buildCacheFilePath($append) : $this->buildCacheFilePath($alias)); - if ($alias) { - $config = $this->getCacheContent($cacheFileName); + if ($alias && $cache) { + $config = $this->getCacheContent($cache, $alias); if (isset($config[$alias]) && !$this->needCompiled()) { return $config[$alias]; } @@ -67,23 +65,23 @@ public function parse($configPath, $alias = '', $append = '') { if (!($configPath = trim($configPath))) throw new WindException('Please input the file path!'); $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); - if (!$alias) - return $result; + if (!$alias || !$cache) return $result; $config[$alias] = $result; - $this->saveConfigFile($cacheFileName, $config); + $this->saveConfigFile($cache, $alias, $config); return $result; } /** * 获得缓存文件内容 - * + * + * @param AbstractWindCache $cache * @param string $file 缓存文件名 * @return array 缓存文件内容 */ - private function getCacheContent($file) { + private function getCacheContent(AbstractWindCache $cache, $file) { $content = array(); if (is_file($file)) - $content = include ($file); + $content = $cache->get($file); return is_array($content) ? $content : array(); } @@ -173,16 +171,15 @@ private function getConfigFormat($configPath) { /** * 保存成文件 - * - * @param string $filename 保存的文件名 + * + * @param AbstractWindCache $cache + * @param string $alias 保存的key * @param array $data 需要保持的数据 * @return boolean 保存成功则返回true,保存失败则返回false */ - private function saveConfigFile($filename, $data) { - if (!$filename || !$data || !is_dir(COMPILE_PATH)) - return false; - Wind::import('COM:utility.WindFile'); - return WindFile::savePhpData($filename, $data); + private function saveConfigFile(AbstractWindCache $cache, $alias, $data) { + if (!$data) return false; + return $cache->set($alias, $data, 0); } /** @@ -192,7 +189,7 @@ private function saveConfigFile($filename, $data) { * @return string 返回缓存文件的$fileName的绝对路径 */ private function buildCacheFilePath($fileName) { - return rtrim(COMPILE_PATH, '/') . D_S . strtolower($fileName) . '.php'; + return strtolower($fileName) . '.php'; } /** diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 44a1cd9c..bcd23425 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -24,9 +24,11 @@ public function __construct($config, $appName, $factory) { */ public function setConfig($config, $factory = null) { if (is_string($config)) { - $config = $this->parseConfig($config, '', '', $factory); - if (isset($config[$this->appName])) - $this->_config = $config[$this->appName]; + $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); + $config = $configParser->parse($config, $this->appName . '_config', $factory->getInstance('windCache'));//将不做保存处理 + } + if (isset($config[$this->appName])) { + $this->_config = $config[$this->appName]; } else $this->_config = (array) $config; } From ebf2550fef0e3b72ee0ef43956f7d00712cfb5e3 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 27 Jul 2011 09:58:42 +0000 Subject: [PATCH 0199/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2259 18ba2127-5a84-46d4-baec-3457e417f034 --- .../cache/AbstractWindCacheDependency.php | 2 +- .../dependency/WindDbCacheDependency.php | 27 ++++++++++++------- wind/component/cache/strategy/WindDbCache.php | 1 - 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/wind/component/cache/AbstractWindCacheDependency.php b/wind/component/cache/AbstractWindCacheDependency.php index e49fef55..80f56701 100644 --- a/wind/component/cache/AbstractWindCacheDependency.php +++ b/wind/component/cache/AbstractWindCacheDependency.php @@ -6,7 +6,7 @@ * @version $Id$ * @package */ -abstract class AbstractWindCacheDependency { +abstract class AbstractWindCacheDependency extends WindModule { /** * 依赖的依据 diff --git a/wind/component/cache/dependency/WindDbCacheDependency.php b/wind/component/cache/dependency/WindDbCacheDependency.php index 50ccabdb..fd58c835 100644 --- a/wind/component/cache/dependency/WindDbCacheDependency.php +++ b/wind/component/cache/dependency/WindDbCacheDependency.php @@ -9,12 +9,12 @@ Wind::import('WIND:component.cache.dependency.AbstractWindCacheDependency'); class WindDbCacheDependency extends AbstractWindCacheDependency{ private $sql = ''; - private $config = ''; + private $configName = ''; private $connection = null; - public function __construct($sql, $config = '') { + public function __construct($sql, $configName = '') { $sql && $this->sql = $sql; - $config && $this->config = $this->config; + $configName && $this->configName = $configName; } /* @@ -28,16 +28,23 @@ protected function notifyDependencyChanged() { /** * 获得链接对象 - * //TODO DB链接对象~获取全局统一。。 */ private function getConnection() { - if ($this->connection != null ) return $this->connection; - if ($this->config) { - $this->connection = new WindConnection(); - $this->connection->setConfig($this->dbConfig); - $this->connection->init(); - return $this->connection; + if ( null != $this->connection) return $this->connection; + $alias = 'db_' . $this->configName; + if (!$this->getSystemFactory()->checkAlias($alias)) { + $config = $this->getSystemConfig()->getDbConfig($this->configName); + $definition = array( + 'path' => $this->getConfig('class', '', 'COM:db.WindConnection', $config), + 'alias' => $alias, + 'config' => $config, + 'initMethod' => 'init', + 'scope' => 'application', + ); + $this->getSystemFactory()->addClassDefinitions($alias, $definition); } + $this->connection = $this->getSystemFactory()->getInstance($alias); + return $this->connection; } diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index 38a84235..9c590fb2 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -169,7 +169,6 @@ public function setConnection($connection) { /** * 获得链接对象 * @return WindConnection - * //TODO DB链接对象~获取全局统一。。 */ private function getConnection() { if (null == $this->connection) { From f7efc0aa004325fdba5c4ee42c552fbcc2d2d3f7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 10:12:45 +0000 Subject: [PATCH 0200/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2260 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index e7be52b9..2d1cbcff 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -56,9 +56,18 @@ public static function run($appName = 'default', $config = '', $rootPath = '') { } } self::getApp()->run(); + self::resetApp(); self::afterRun($appName, $config, $rootPath); } + /** + * 开发环境脚本入口 + */ + public static function runWithCompile($appName = 'default', $config = '') { + require_once (self::getRealPath('WIND:_compile.compile')); + self::run($appName, $config); + } + /** * 返回当前appName * @@ -85,14 +94,6 @@ public static function getApp() { WindException::ERROR_CLASS_NOT_EXIST); } - /** - * 开发环境脚本入口 - */ - public static function runWithCompile($appName = 'default', $config = '') { - require_once (self::getRealPath('WIND:_compile.compile')); - self::run($appName, $config); - } - /** * 加载一个类或者加载一个包 * 如果加载的包中有子文件夹不进行循环加载 @@ -352,7 +353,6 @@ protected static function beforRun($appName, $config, $rootPath) { * @return */ protected static function afterRun($appName, $config, $rootPath) { - self::resetApp(); restore_error_handler(); restore_exception_handler(); if (self::$_logger) From dc9bf01753b40580d7d7c3c5dabafab178f3b979 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 10:19:51 +0000 Subject: [PATCH 0201/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2261 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindSystemConfig.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index bcd23425..44a1cd9c 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -24,11 +24,9 @@ public function __construct($config, $appName, $factory) { */ public function setConfig($config, $factory = null) { if (is_string($config)) { - $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($config, $this->appName . '_config', $factory->getInstance('windCache'));//将不做保存处理 - } - if (isset($config[$this->appName])) { - $this->_config = $config[$this->appName]; + $config = $this->parseConfig($config, '', '', $factory); + if (isset($config[$this->appName])) + $this->_config = $config[$this->appName]; } else $this->_config = (array) $config; } From e7a86d8052ec83f0ba7882e60cc5d82152e231b4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 10:21:51 +0000 Subject: [PATCH 0202/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2262 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindSystemConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 44a1cd9c..97463b36 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -209,7 +209,7 @@ private function parseConfig($config, $key = 'config', $append = true, $factory $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); $key = $this->appName . '_' . $key; $append === true && $append = $this->appName . '_config'; - $config = $configParser->parse($config, $key, $append); + $config = $configParser->parse($config, $key, $append, $factory->getInstance(COMPONENT_CACHE)); return $config; } From c9516a7550a2d878b36a3a984832acab740ca334 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 27 Jul 2011 10:26:49 +0000 Subject: [PATCH 0203/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2263 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/Wind.php b/wind/Wind.php index 2d1cbcff..9dc2c811 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -462,6 +462,7 @@ private static function _loadBaseLib() { define('COMPONENT_DB', 'db'); define('COMPONENT_DISPATCHER', 'dispatcher'); define('COMPONENT_CONFIGPARSER', 'configParser'); +define('COMPONENT_CACHE', 'windCache'); //TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 //********************约定变量*********************************** define('WIND_M_ERROR', 'windError'); From 8748fb4205c66785a698425d1409299dff8ea7c7 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 27 Jul 2011 10:52:57 +0000 Subject: [PATCH 0204/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2264 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/parser/IWindConfigParser.php | 5 +++-- wind/component/parser/WindConfigParser.php | 10 ++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/wind/component/parser/IWindConfigParser.php b/wind/component/parser/IWindConfigParser.php index 063f9970..0695ad50 100644 --- a/wind/component/parser/IWindConfigParser.php +++ b/wind/component/parser/IWindConfigParser.php @@ -17,10 +17,11 @@ interface IWindConfigParser { * 如果是应用解析需要进行merge操作,如果是组件解析则不用 * * @param string $name 解析后保存的文件名字 - * @param string $configPath 待解析文件的绝对路径 + * @param string $configPath 待解析文件的绝对路径 + * @param string $append 追加的文件 * @param AbstractWindCache $cache 缓存策略 * @return array 解析成功返回的数据 */ - public function parse($configPath, $alias = '', AbstractWindCache $cache = null); + public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } \ No newline at end of file diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index 4af629b4..df85ed6d 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -49,15 +49,17 @@ public function __construct() {} * 如果都不存在,则执行解析,并根据是否追加的条件,进行追加或是新建。 * * @param string $configPath 待解析的文件路径 - * @param string $alias 解析后保存的key名 + * @param string $alias 解析后保存的key名 + * @param string $append 追加的文件 * @param AbstractWindCache $cache 缓存策略 * @return array 解析结果 */ - public function parse($configPath, $alias = '', AbstractWindCache $cache = null) { + public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { $config = array(); $alias = trim($alias); + $key = $append ? $append : $alias; if ($alias && $cache) { - $config = $this->getCacheContent($cache, $alias); + $config = $this->getCacheContent($cache, $key); if (isset($config[$alias]) && !$this->needCompiled()) { return $config[$alias]; } @@ -67,7 +69,7 @@ public function parse($configPath, $alias = '', AbstractWindCache $cache = null) $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); if (!$alias || !$cache) return $result; $config[$alias] = $result; - $this->saveConfigFile($cache, $alias, $config); + $this->saveConfigFile($cache, $key, $config); return $result; } From 6e1cf4a2b2d707f309e438c2d1b2a4a9fcfd151f Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 02:59:36 +0000 Subject: [PATCH 0205/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2265 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindSystemConfig.php | 33 ------------------------------ 1 file changed, 33 deletions(-) diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 97463b36..855a65f1 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -168,19 +168,6 @@ public function getModuleControllerSuffixByModuleName($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $module); } - /** - * 获得缓存配置 - * @param string $type - */ - public function getCacheConfig($type = '') { - $config = $this->getConfig('cache'); - if (isset($config['resource'])) { - $config = $this->parseResource($config['resource']); - $this->_config['cache'] = $config; - } - return $this->getConfig('cache', $type); - } - /** * 获得DB配置,根据DB名义的别名来获取DB链接配置信息. * 当别名为空时,返回全部DB链接配置. @@ -213,24 +200,4 @@ private function parseConfig($config, $key = 'config', $append = true, $factory return $config; } - /** - * 解析resource的配置 - * - * @param string $resource - * @return array - */ - private function parseResource($resource) { - $fileName = $resource; - $ext = 'php'; - if (($extPois = strpos($resource, '.')) !== false) { - $fileName = substr($resource, 0, $extPois); - $ext = substr($resource, $extPois + 1); - } - $fileName = (false === strpos($resource, ':')) ? Wind::getAppName() . ':' . $fileName : $fileName; - $filePath = !is_file($resource) ? Wind::getRealPath($fileName, $ext) : $resource; - $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($filePath); - return $config; - } - } \ No newline at end of file From a817b193bc1154575e390d24d79a2c2373ffb841 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 03:00:34 +0000 Subject: [PATCH 0206/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2266 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/filecache_config.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configtemplate/filecache_config.xml b/docs/configtemplate/filecache_config.xml index 005d6a02..2cb5c505 100644 --- a/docs/configtemplate/filecache_config.xml +++ b/docs/configtemplate/filecache_config.xml @@ -1,6 +1,6 @@ - + WIND:_compile @@ -14,4 +14,4 @@ - + From a21fe5f17fa236c8de723b39961da921c400d6d0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 03:46:52 +0000 Subject: [PATCH 0207/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84=20daoFactory=20db?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E9=83=A8=E5=88=86=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2267 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 72 +++++++-------------------------------------------- 1 file changed, 10 insertions(+), 62 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 9dc2c811..9164d709 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -38,25 +38,11 @@ class Wind { */ public static function run($appName = 'default', $config = '', $rootPath = '') { self::beforRun($appName, $config, $rootPath); - /* 将当前的app压入数组的开始 */ - $_cache = self::getAppName(); - if ($_cache === $appName) - throw new WindException('Duplicate app.', WindException::ERROR_SYSTEM_ERROR); - - //self::$_currentApp[0] = array($appName, $_cache); - array_unshift(self::$_currentApp, array($appName, $_cache)); - if (!isset(self::$_app[$appName])) { Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); self::$_app[$appName] = new WindFrontController($appName, $config); - } else - foreach (self::$_currentApp as $key => $value) { - if ($value[0] == $appName) { - unset(self::$_currentApp[$key]); - } - } + } self::getApp()->run(); - self::resetApp(); self::afterRun($appName, $config, $rootPath); } @@ -74,9 +60,9 @@ public static function runWithCompile($appName = 'default', $config = '') { * @return string */ public static function getAppName() { - if (!isset(self::$_currentApp[0])) - return ''; - return self::$_currentApp[0][0]; + if (empty(self::$_currentApp)) + throw new WindException('Get appName failed. current app is not exists.', WindException::ERROR_SYSTEM_ERROR); + return end(self::$_currentApp); } /** @@ -322,29 +308,16 @@ public static function clear() { * @return */ protected static function resetApp() { - if (!isset(self::$_currentApp[0])) - return; - $_current = self::$_currentApp[0]; - if ($_current[1] === '') - return; - - /*self::$_currentApp[$_current[0]] = $_current; - self::$_currentApp[0] = self::$_currentApp[$_current[1]];*/ - //unset(self::$_currentApp[$_current[1]]); - foreach (self::$_currentApp as $key => $value) { - if ($value[0] == $_current[1]) { - array_unshift(self::$_currentApp, $value); - unset(self::$_currentApp[$key]); - } - } + array_pop(self::$_currentApp); } /** * @return */ protected static function beforRun($appName, $config, $rootPath) { - if ($appName === 0) - throw new WindException('unsupported appName (' . $appName . ')', WindException::ERROR_SYSTEM_ERROR); + if (in_array($appName, self::$_currentApp)) + throw new WindException('Nested request', WindException::ERROR_SYSTEM_ERROR); + array_push(self::$_currentApp, $appName); set_error_handler(array(new WindErrorHandler(), 'errorHandle')); set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); } @@ -353,6 +326,7 @@ protected static function beforRun($appName, $config, $rootPath) { * @return */ protected static function afterRun($appName, $config, $rootPath) { + self::resetApp(); restore_error_handler(); restore_exception_handler(); if (self::$_logger) @@ -417,33 +391,7 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - self::$_classes = array('WindLogger' => 'log/WindLogger', - 'WindActionException' => 'core/exception/WindActionException', - 'WindException' => 'core/exception/WindException', - 'WindFinalException' => 'core/exception/WindFinalException', 'IWindFactory' => 'core/factory/IWindFactory', - 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', - 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', 'WindFactory' => 'core/factory/WindFactory', - 'IWindController' => 'core/web/controller/IWindController', - 'WindController' => 'core/web/controller/WindController', - 'WindSimpleController' => 'core/web/controller/WindSimpleController', - 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', 'IWindApplication' => 'core/web/IWindApplication', - 'IWindErrorMessage' => 'core/web/IWindErrorMessage', - 'WindFormListener' => 'core/web/listener/WindFormListener', - 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', - 'WindValidateListener' => 'core/web/listener/WindValidateListener', - 'WindDispatcher' => 'core/web/WindDispatcher', 'WindErrorHandler' => 'core/web/WindErrorHandler', - 'WindErrorMessage' => 'core/web/WindErrorMessage', 'WindForward' => 'core/web/WindForward', - 'WindFrontController' => 'core/web/WindFrontController', 'WindUrlHelper' => 'core/web/WindUrlHelper', - 'WindWebApplication' => 'core/web/WindWebApplication', - 'WindEnableValidateModule' => 'core/WindEnableValidateModule', 'WindHelper' => 'core/WindHelper', - 'WindModule' => 'core/WindModule', 'WindSystemConfig' => 'core/WindSystemConfig', - 'WindFilter' => 'filter/WindFilter', 'WindFilterChain' => 'filter/WindFilterChain', - 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', - 'WindConfigParser' => 'parser/WindConfigParser', 'IWindRequest' => 'http/request/IWindRequest', - 'WindHttpRequest' => 'http/request/WindHttpRequest', 'IWindResponse' => 'http/response/IWindResponse', - 'WindHttpResponse' => 'http/response/WindHttpResponse', 'AbstractWindRouter' => 'router/AbstractWindRouter', - 'WindUrlBasedRouter' => 'router/WindUrlBasedRouter'); + self::$_classes = array('WindLogger' => 'log/WindLogger', 'WindActionException' => 'core/exception/WindActionException', 'WindException' => 'core/exception/WindException', 'WindFinalException' => 'core/exception/WindFinalException', 'IWindFactory' => 'core/factory/IWindFactory', 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', 'WindFactory' => 'core/factory/WindFactory', 'IWindController' => 'core/web/controller/IWindController', 'WindController' => 'core/web/controller/WindController', 'WindSimpleController' => 'core/web/controller/WindSimpleController', 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', 'IWindApplication' => 'core/web/IWindApplication', 'IWindErrorMessage' => 'core/web/IWindErrorMessage', 'WindFormListener' => 'core/web/listener/WindFormListener', 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', 'WindValidateListener' => 'core/web/listener/WindValidateListener', 'WindDispatcher' => 'core/web/WindDispatcher', 'WindErrorHandler' => 'core/web/WindErrorHandler', 'WindErrorMessage' => 'core/web/WindErrorMessage', 'WindForward' => 'core/web/WindForward', 'WindFrontController' => 'core/web/WindFrontController', 'WindUrlHelper' => 'core/web/WindUrlHelper', 'WindWebApplication' => 'core/web/WindWebApplication', 'WindEnableValidateModule' => 'core/WindEnableValidateModule', 'WindHelper' => 'core/WindHelper', 'WindModule' => 'core/WindModule', 'WindSystemConfig' => 'core/WindSystemConfig', 'WindFilter' => 'filter/WindFilter', 'WindFilterChain' => 'filter/WindFilterChain', 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', 'WindConfigParser' => 'parser/WindConfigParser', 'IWindRequest' => 'http/request/IWindRequest', 'WindHttpRequest' => 'http/request/WindHttpRequest', 'IWindResponse' => 'http/response/IWindResponse', 'WindHttpResponse' => 'http/response/WindHttpResponse', 'AbstractWindRouter' => 'router/AbstractWindRouter', 'WindUrlBasedRouter' => 'router/WindUrlBasedRouter'); } } Wind::init(); From 7fa1286c3998f8b7efb91196d05558f78b05e901 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 04:45:09 +0000 Subject: [PATCH 0208/1065] =?UTF-8?q?bug=20=E4=BF=AE=E5=A4=8D=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2268 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 4 ---- wind/component/http/response/WindHttpResponse.php | 1 - wind/component/parser/WindConfigParser.php | 6 ++++-- wind/core/web/WindFrontController.php | 12 +++++++++--- wind/core/web/WindSystemConfig.php | 3 +++ 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 9164d709..a875816f 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -318,8 +318,6 @@ protected static function beforRun($appName, $config, $rootPath) { if (in_array($appName, self::$_currentApp)) throw new WindException('Nested request', WindException::ERROR_SYSTEM_ERROR); array_push(self::$_currentApp, $appName); - set_error_handler(array(new WindErrorHandler(), 'errorHandle')); - set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); } /** @@ -327,8 +325,6 @@ protected static function beforRun($appName, $config, $rootPath) { */ protected static function afterRun($appName, $config, $rootPath) { self::resetApp(); - restore_error_handler(); - restore_exception_handler(); if (self::$_logger) self::$_logger->flush(); } diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index d0093199..8dbc3c5e 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -371,7 +371,6 @@ public function sendError($status = self::SC_NOT_FOUND, $message = '') { return; $this->setBody($message); $this->setStatus($status); - $this->sendResponse(); } /** diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index df85ed6d..d0de507b 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -67,7 +67,8 @@ public function parse($configPath, $alias = '', $append = '', AbstractWindCache if (!($configPath = trim($configPath))) throw new WindException('Please input the file path!'); $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); - if (!$alias || !$cache) return $result; + if (!$alias || !$cache) + return $result; $config[$alias] = $result; $this->saveConfigFile($cache, $key, $config); return $result; @@ -180,7 +181,8 @@ private function getConfigFormat($configPath) { * @return boolean 保存成功则返回true,保存失败则返回false */ private function saveConfigFile(AbstractWindCache $cache, $alias, $data) { - if (!$data) return false; + if (!$data) + return false; return $cache->set($alias, $data, 0); } diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 731c8ec1..08d4f5dd 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -41,8 +41,9 @@ public function __construct($appName, $config = '') { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(); $this->init($appName, $config); - } catch (Exception $exception) { - throw new Exception('System failed to initialize.' . $exception->getMessage()); + } catch (Exception $e) { + Wind::log('System failed to initialize. (' . $e->getMessage() . ')', WindLogger::LEVEL_INFO, 'wind.core'); + throw new WindException('System failed to initialize.'); } } @@ -94,13 +95,18 @@ protected function init($appName, $config) { /** * 预处理Process方法 */ - protected function beforeProcess() {} + protected function beforeProcess() { + set_error_handler(array(new WindErrorHandler(), 'errorHandle')); + set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); + } /** * 后处理Process方法 */ protected function afterProcess() { $this->response->sendResponse(); + restore_error_handler(); + restore_exception_handler(); } /** diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 855a65f1..3ec61295 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -191,6 +191,9 @@ public function getDbConfig($dbName = '') { * @param factory */ private function parseConfig($config, $key = 'config', $append = true, $factory = null) { + if (!$config) + return array(); + if ($factory === null) $factory = $this->getSystemFactory(); $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); From 1e3916635df69064d1b9c7f3547cbc299cf137c1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 04:47:41 +0000 Subject: [PATCH 0209/1065] =?UTF-8?q?bug=20=E4=BF=AE=E5=A4=8D=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2269 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index a875816f..fb5f9252 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -387,7 +387,48 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - self::$_classes = array('WindLogger' => 'log/WindLogger', 'WindActionException' => 'core/exception/WindActionException', 'WindException' => 'core/exception/WindException', 'WindFinalException' => 'core/exception/WindFinalException', 'IWindFactory' => 'core/factory/IWindFactory', 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', 'WindFactory' => 'core/factory/WindFactory', 'IWindController' => 'core/web/controller/IWindController', 'WindController' => 'core/web/controller/WindController', 'WindSimpleController' => 'core/web/controller/WindSimpleController', 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', 'IWindApplication' => 'core/web/IWindApplication', 'IWindErrorMessage' => 'core/web/IWindErrorMessage', 'WindFormListener' => 'core/web/listener/WindFormListener', 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', 'WindValidateListener' => 'core/web/listener/WindValidateListener', 'WindDispatcher' => 'core/web/WindDispatcher', 'WindErrorHandler' => 'core/web/WindErrorHandler', 'WindErrorMessage' => 'core/web/WindErrorMessage', 'WindForward' => 'core/web/WindForward', 'WindFrontController' => 'core/web/WindFrontController', 'WindUrlHelper' => 'core/web/WindUrlHelper', 'WindWebApplication' => 'core/web/WindWebApplication', 'WindEnableValidateModule' => 'core/WindEnableValidateModule', 'WindHelper' => 'core/WindHelper', 'WindModule' => 'core/WindModule', 'WindSystemConfig' => 'core/WindSystemConfig', 'WindFilter' => 'filter/WindFilter', 'WindFilterChain' => 'filter/WindFilterChain', 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', 'WindConfigParser' => 'parser/WindConfigParser', 'IWindRequest' => 'http/request/IWindRequest', 'WindHttpRequest' => 'http/request/WindHttpRequest', 'IWindResponse' => 'http/response/IWindResponse', 'WindHttpResponse' => 'http/response/WindHttpResponse', 'AbstractWindRouter' => 'router/AbstractWindRouter', 'WindUrlBasedRouter' => 'router/WindUrlBasedRouter'); + self::$_classes = array( + 'WindLogger' => 'log/WindLogger', + 'WindActionException' => 'core/exception/WindActionException', + 'WindException' => 'core/exception/WindException', + 'WindFinalException' => 'core/exception/WindFinalException', + 'IWindFactory' => 'core/factory/IWindFactory', + 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', + 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', + 'WindFactory' => 'core/factory/WindFactory', + 'IWindApplication' => 'core/IWindApplication', + 'IWindController' => 'core/IWindController', + 'IWindErrorMessage' => 'core/IWindErrorMessage', + 'IWindFrontController' => 'core/IWindFrontController', + 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', + 'WindFormListener' => 'core/web/listener/WindFormListener', + 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', + 'WindValidateListener' => 'core/web/listener/WindValidateListener', + 'WindController' => 'core/web/WindController', + 'WindDispatcher' => 'core/web/WindDispatcher', + 'WindErrorHandler' => 'core/web/WindErrorHandler', + 'WindErrorMessage' => 'core/web/WindErrorMessage', + 'WindForward' => 'core/web/WindForward', + 'WindFrontController' => 'core/web/WindFrontController', + 'WindHelper' => 'core/web/WindHelper', + 'WindSimpleController' => 'core/web/WindSimpleController', + 'WindSystemConfig' => 'core/web/WindSystemConfig', + 'WindUrlHelper' => 'core/web/WindUrlHelper', + 'WindWebApplication' => 'core/web/WindWebApplication', + 'WindEnableValidateModule' => 'core/WindEnableValidateModule', + 'WindModule' => 'core/WindModule', + 'WindFilter' => 'filter/WindFilter', + 'WindFilterChain' => 'filter/WindFilterChain', + 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', + 'WindConfigParser' => 'parser/WindConfigParser', + 'IWindRequest' => 'http/request/IWindRequest', + 'WindHttpRequest' => 'http/request/WindHttpRequest', + 'IWindResponse' => 'http/response/IWindResponse', + 'WindHttpResponse' => 'http/response/WindHttpResponse', + 'AbstractWindRouter' => 'router/AbstractWindRouter', + 'WindUrlBasedRouter' => 'router/WindUrlBasedRouter', + ); } } Wind::init(); From 45700eeb4f240526db86147e7577d704e3ca089e Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 06:04:01 +0000 Subject: [PATCH 0210/1065] =?UTF-8?q?bug=20=E4=BF=AE=E5=A4=8D=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2270 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 1 + wind/_compile/compile.php | 3 + wind/_compile/components_config.xml | 4 +- wind/component/parser/WindConfigParser.php | 169 +++++++-------------- wind/core/factory/WindFactory.php | 7 +- wind/core/web/WindSystemConfig.php | 6 +- 6 files changed, 63 insertions(+), 127 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index fb5f9252..b7afd4cd 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -52,6 +52,7 @@ public static function run($appName = 'default', $config = '', $rootPath = '') { public static function runWithCompile($appName = 'default', $config = '') { require_once (self::getRealPath('WIND:_compile.compile')); self::run($appName, $config); + } /** diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php index 435ba019..e470d0e3 100644 --- a/wind/_compile/compile.php +++ b/wind/_compile/compile.php @@ -38,6 +38,9 @@ $result = $windConfigParser->parse(_COMPILE_PATH . 'components_config.xml'); WindFile::write($_systemConfig, ' - compile + data - compile + data diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index d0de507b..53a37578 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -16,24 +16,17 @@ class WindConfigParser implements IWindConfigParser { /** * 配置文件支持的格式白名单 */ - const CONFIG_XML = 'XML'; - const CONFIG_PHP = 'PHP'; - const CONFIG_INI = 'INI'; - const CONFIG_PROPERTIES = 'PROPERTIES'; - const WIND_ROOT = 'wind'; + const CONFIG_XML = '.XML'; + const CONFIG_PHP = '.PHP'; + const CONFIG_INI = '.INI'; + const CONFIG_PROPERTIES = '.PROPERTIES'; + /** * 配置解析对象队列 * @var array object $configParser */ private $configParsers = array(); - /** - * 初始化 - * 设置解析数据输出的编码方式 - * @param String $outputEncoding - */ - public function __construct() {} - /** * 解析组件的配置文件 * @@ -55,23 +48,43 @@ public function __construct() {} * @return array 解析结果 */ public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { - $config = array(); - $alias = trim($alias); - $key = $append ? $append : $alias; - if ($alias && $cache) { - $config = $this->getCacheContent($cache, $key); - if (isset($config[$alias]) && !$this->needCompiled()) { - return $config[$alias]; - } - } - if (!($configPath = trim($configPath))) - throw new WindException('Please input the file path!'); - $result = $this->doParser($configPath, $this->getConfigFormat($configPath)); + if ($config = $this->getCache($alias, $append, $cache)) + return $config; + $config = $this->doParser($configPath); + $this->setCache($alias, $append, $cache, $config); + return $config; + } + + /** + * 设置配置缓存 + * @param string $alias + * @param string $append + * @param AbstractWindCache $cache + */ + private function setCache($alias, $append, $cache, $data) { + if (!$alias || !$cache) + return; + if ($append) { + $_config = (array) $cache->get($append); + $_config[$alias] = $data; + $cache->set($append, $_config); + } else + $cache->set($alias, $data); + } + + /** + * 返回配置缓存 + * @param string alias + * @param string append + * @param AbstractWindCache cache + * @return array + */ + private function getCache($alias, $append, $cache) { if (!$alias || !$cache) - return $result; - $config[$alias] = $result; - $this->saveConfigFile($cache, $key, $config); - return $result; + return array(); + $_key = $append ? $append : $alias; + $config = $cache->get($_key); + return isset($config[$alias]) ? $config[$alias] : array(); } /** @@ -108,7 +121,7 @@ private function createParser($type) { return new WindPropertiesParser(); break; default: - throw new WindException('init config parser error.'); + throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } @@ -121,95 +134,15 @@ private function createParser($type) { * @param string $configFile 解析的文件路径 * @return array 返回解析结果 */ - private function doParser($configFile, $type) { - if (!$configFile) - return array(); + private function doParser($configFile) { if (!is_file($configFile)) - throw new WindException('The file <' . $configFile . '> is not exists'); - if ($type == 'PHP') { - $config = include ($configFile); - return (isset($config['wind'])) ? $config['wind'] : $config; - } - if (!isset($this->configParsers[$type])) { - $this->configParsers[$type] = $this->createParser($type); - } - return $this->configParsers[$type]->parse($configFile); - } - - /** - * 返回是否需要执行解析 - * - * 如果是debug模式,则返回false, 进行每次都进行解析 - * 如果不是debug模式,则先判断是否设置了缓存模式 - * 如果没有设置缓存则返回false, 进行解析, - * 如果设置了缓存模式,则判断缓存文件是否存在 - * 如果该解析出来的文件不存在,则返回false, 执行解析 - * 否则返回true, 直接读取缓存 - * - * @param string $cacheFile 缓存文件路径 - * @return boolean false:需要进行解析, true:不需要进行解析,直接读取缓存文件 - */ - private function needCompiled() { - if (IS_DEBUG && is_dir(COMPILE_PATH)) - return true; - return false; - } - - /** - * 获得文件的后缀,决定采用的是哪种配置格式, - * 如果传递的文件配置格式不在支持范围内,则抛出异常 - * - * @param string $configPath 配置文件路径 - * @return boolean : true 解析文件格式成功,解析失败则抛出异常 - */ - private function getConfigFormat($configPath) { - if ($configPath === '') - return self::CONFIG_XML; - $format = strtoupper(trim(strrchr($configPath, '.'), '.')); - if (!in_array($format, $this->getConfigFormatList())) { - throw new WindException("The format of the config file doesn't sopported yet!"); - } - return $format; - } - - /** - * 保存成文件 - * - * @param AbstractWindCache $cache - * @param string $alias 保存的key - * @param array $data 需要保持的数据 - * @return boolean 保存成功则返回true,保存失败则返回false - */ - private function saveConfigFile(AbstractWindCache $cache, $alias, $data) { - if (!$data) - return false; - return $cache->set($alias, $data, 0); - } - - /** - * 构造文件的路径 - * - * @param string $fileName 缓存文件的名字 - * @return string 返回缓存文件的$fileName的绝对路径 - */ - private function buildCacheFilePath($fileName) { - return strtolower($fileName) . '.php'; - } - - /** - * 获得支持解析的配置文件格式的白名单 - * - * @return array 返回配置文件格式的白名单 - */ - private function getConfigFormatList() { - return array(self::CONFIG_XML, self::CONFIG_PHP, self::CONFIG_INI, self::CONFIG_PROPERTIES); - } - - /** - * 析构函数 - * - */ - public function __destruct() { - $this->configParser = array(); + throw new WindException( + '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); + $ext = strtoupper(strrchr($configFile, '.')); + if ($ext == self::CONFIG_PHP) + return @include ($configFile); + if (!isset($this->configParsers[$ext])) + $this->configParsers[$ext] = $this->createParser($ext); + return $this->configParsers[$ext]->parse($configFile); } } \ No newline at end of file diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 4cd4bbd5..2d893a22 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -146,7 +146,8 @@ protected function buildConfig(&$definition, $alias) { if (isset($config['resource']) && !empty($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], false); $configParser = $this->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($_configPath, $alias, 'cache_wind_config'); + $config = $configParser->parse($_configPath, $alias, 'cache_wind_config', + $this->getInstance(COMPONENT_CACHE)); } if (isset($config['class']) && !$definition['path']) { $definition['path'] = $config['class']; @@ -217,11 +218,9 @@ protected function buildProperties($properties, $instance) { * @return boolean */ private function buildDefinition(&$definition) { - $_definition = array('path' => '', 'className' => '', 'factoryMethod' => '', 'initMethod' => '', - 'scope' => 'application', 'proxy' => false, 'properties' => array(), 'config' => array(), 'constructorArg' => array()); + $_definition = array('path' => '', 'className' => '', 'factoryMethod' => '', 'initMethod' => '', 'scope' => 'application', 'proxy' => false, 'properties' => array(), 'config' => array(), 'constructorArg' => array()); $definition = array_merge($_definition, $definition); $definition['className'] = Wind::import($definition['path']); - return true; } } \ No newline at end of file diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 3ec61295..5f881fb6 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -24,7 +24,7 @@ public function __construct($config, $appName, $factory) { */ public function setConfig($config, $factory = null) { if (is_string($config)) { - $config = $this->parseConfig($config, '', '', $factory); + $config = $this->parseConfig($config, 'config', '', $factory); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else @@ -197,9 +197,9 @@ private function parseConfig($config, $key = 'config', $append = true, $factory if ($factory === null) $factory = $this->getSystemFactory(); $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); - $key = $this->appName . '_' . $key; $append === true && $append = $this->appName . '_config'; - $config = $configParser->parse($config, $key, $append, $factory->getInstance(COMPONENT_CACHE)); + $config = $configParser->parse($config, $this->appName . '_' . $key, $append, + $factory->getInstance(COMPONENT_CACHE)); return $config; } From a2fb740eed3a9eb9c3c52f8f3baa997cbca59b3e Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 06:31:19 +0000 Subject: [PATCH 0211/1065] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D=EF=BC=8C=20?= =?UTF-8?q?=E7=BB=91=E5=AE=9Acolumns=20=E5=90=8E=E7=BB=AD=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2271 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 66cb024e..b8512243 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -34,8 +34,10 @@ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { $this->_columns = $sqlStatement->getColumns(); } else $this->_statement = $sqlStatement; - if ($fetchMode != 0) $this->_fetchMode = $fetchMode; - if ($fetchMode != 0) $this->_fetchType = $fetchType; + if ($fetchMode != 0) + $this->_fetchMode = $fetchMode; + if ($fetchMode != 0) + $this->_fetchType = $fetchType; } /** @@ -77,20 +79,24 @@ public function columnCount() { * @return array */ public function fetch($fetchMode = 0, $fetchType = 0) { - if ($fetchMode === 0) $fetchMode = $this->_fetchMode; - if ($fetchType === 0) $fetchMode = $this->_fetchType; + if ($fetchMode === 0) + $fetchMode = $this->_fetchMode; + if ($fetchType === 0) + $fetchMode = $this->_fetchType; return $this->_fetch($fetchMode, $fetchType); } /** - * (non-PHPdoc) + * (non-PHPdoc) * @see WindResult::fetch() */ private function _fetch($fetchMode, $fetchType) { - if (!empty($this->_columns)) $fetchMode = PDO::FETCH_BOUND; + if (!empty($this->_columns)) + $fetchMode = PDO::FETCH_BOUND; $result = array(); if ($row = $this->_statement->fetch($fetchMode, $fetchType)) { - if (empty($this->_columns)) return $row; + if (empty($this->_columns)) + return $row; foreach ($this->_columns as $key => $value) { $result[$key] = $value; } @@ -107,11 +113,12 @@ private function _fetch($fetchMode, $fetchType) { * @return array */ public function fetchAll($index = '', $fetchMode = 0) { - if ($fetchMode === 0) $fetchMode = $this->_fetchMode; - if ('' === $index) return $this->_statement->fetchAll($fetchMode); + if ($fetchMode === 0) + $fetchMode = $this->_fetchMode; $result = array(); - while ($row = $this->fetch($fetchMode)) - isset($row[$index]) ? $result[$row[$index]] = $row : $result[] = $row; + while ($row = $this->fetch($fetchMode)) { + $result[] = $index ? (isset($row[$index]) ? $row[$index] : '') : $row; + } return $result; } From d2ea5372891058141b1a2e1b88b5df920769165f Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 18:58:31 +0000 Subject: [PATCH 0212/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=8C=E6=A0=87=E7=AD=BE=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2272 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/dbcache_config.xml | 30 ++++++++++-------------- docs/configtemplate/filecache_config.xml | 15 ++++++------ docs/configtemplate/wind_config.xml | 1 - 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/docs/configtemplate/dbcache_config.xml b/docs/configtemplate/dbcache_config.xml index 87904407..5f0ab8da 100644 --- a/docs/configtemplate/dbcache_config.xml +++ b/docs/configtemplate/dbcache_config.xml @@ -1,24 +1,18 @@ - + 0 - + - - - - - - default - - pw_cache - - key - - value - - expire - - + + + pw_cache + + key + + value + + expire + diff --git a/docs/configtemplate/filecache_config.xml b/docs/configtemplate/filecache_config.xml index 2cb5c505..4794b8ad 100644 --- a/docs/configtemplate/filecache_config.xml +++ b/docs/configtemplate/filecache_config.xml @@ -1,17 +1,18 @@ + + 0 + + + + + WIND:_compile php - 0 + 0 - - 0 - - - - diff --git a/docs/configtemplate/wind_config.xml b/docs/configtemplate/wind_config.xml index 39813b35..11d147bd 100644 --- a/docs/configtemplate/wind_config.xml +++ b/docs/configtemplate/wind_config.xml @@ -5,7 +5,6 @@ class: 指定该应用的配置 root-path: 指定该应用的入口地址 --> - From 80324ef9f52eff55ec01cf23689fb24a34a5c6ed Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 19:02:36 +0000 Subject: [PATCH 0213/1065] =?UTF-8?q?Wind.php=20realpath=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AF=B9=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=90=8E=E7=BC=80=E7=9A=84=E5=A4=84=E7=90=86=20?= =?UTF-8?q?=E6=94=B9=E8=BF=9BWindFileCache=E7=AD=96=E7=95=A5=EF=BC=8C=20?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E6=AC=A1=E6=96=87=E4=BB=B6=E5=88=A4?= =?UTF-8?q?=E6=96=AD=EF=BC=8C=E5=B0=86=E5=AF=B9=E8=BF=87=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=88=A4=E6=96=AD=E7=AD=96=E7=95=A5=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=88=B0=20hasChange()=20=E6=96=B9=E6=B3=95=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=96=87=E4=BB=B6=E5=A4=B9=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E7=9A=84=E7=AD=96=E7=95=A5=E6=94=B9=E8=BF=9B=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E8=AF=A5=E7=AD=96=E7=95=A5=EF=BC=88=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=95=88=E7=8E=87=E7=BC=BA=E9=99=B7=EF=BC=8C=E4=B8=8D=E5=A4=AA?= =?UTF-8?q?=E5=AE=9E=E7=94=A8=EF=BC=89=20=E5=A2=9E=E5=8A=A0cache=E5=B1=82?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=20dbCache=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E8=BF=9B=E8=A1=8C=E5=88=B0=E4=B8=80=E5=8D=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2273 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 83 ++++-------- wind/_compile/components_config.xml | 17 +-- wind/component/cache/AbstractWindCache.php | 126 +++++++++++------- wind/component/cache/WindCache.php | 32 ++--- .../cache/exception/WindCacheException.php | 13 ++ .../cache/strategy/WindFileCache.php | 98 ++++---------- wind/component/dao/WindDaoFactory.php | 30 +++-- wind/component/parser/WindConfigParser.php | 42 ++---- wind/component/utility/WindFile.php | 11 +- wind/core/factory/WindFactory.php | 6 +- wind/core/web/WindFrontController.php | 16 +-- wind/core/web/WindSystemConfig.php | 2 +- 12 files changed, 205 insertions(+), 271 deletions(-) create mode 100644 wind/component/cache/exception/WindCacheException.php diff --git a/wind/Wind.php b/wind/Wind.php index b7afd4cd..002d1a7c 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -52,7 +52,7 @@ public static function run($appName = 'default', $config = '', $rootPath = '') { public static function runWithCompile($appName = 'default', $config = '') { require_once (self::getRealPath('WIND:_compile.compile')); self::run($appName, $config); - + } /** @@ -206,20 +206,26 @@ public static function getRootPath($namespace) { /** * 解析路径信息,并返回路径的详情 * @param string $filePath 路径信息 - * @param boolean $info 是否为目录路径 + * @param boolean $suffix 是否存在文件后缀true,false,default * @return string|array('isPackage','fileName','extension','realPath') */ public static function getRealPath($filePath, $suffix = '') { - if (($pos = strpos($filePath, ':')) !== false) { + if (false !== ($pos = strpos($filePath, ':'))) { $namespace = self::getRootPath(substr($filePath, 0, $pos)); - if (!$namespace) - return $filePath; - $filePath = $namespace . D_S . str_replace('.', D_S, substr($filePath, $pos + 1)); + $filePath = substr($filePath, $pos + 1); + } else + $namespace = self::getRootPath(self::getAppName()); + if ($suffix === '') { + $suffix = self::$_extensions; + } elseif ($suffix === true) { + if ($pos = strrpos($filePath, '.')) { + $suffix = substr($filePath, $pos + 1); + $filePath = substr($filePath, 0, $pos); + } } - if ($suffix === false) - return $filePath; - $suffix === '' && $suffix = self::$_extensions; - return $filePath . '.' . $suffix; + $filePath = str_replace('.', D_S, $filePath); + $namespace && $filePath = $namespace . D_S . $filePath; + return $suffix ? $filePath . '.' . $suffix : $filePath; } /** @@ -229,13 +235,13 @@ public static function getRealPath($filePath, $suffix = '') { * @return string|array('isPackage','fileName','extension','realPath') */ public static function getRealDir($dirPath) { - if (($pos = strpos($dirPath, ':')) === false) - return $dirPath; - $namespace = self::getRootPath(substr($dirPath, 0, $pos)); - if (!$namespace) - return $dirPath; - $dirPath = str_replace('.', D_S, substr($dirPath, $pos + 1)); - return $namespace . D_S . $dirPath; + if (false !== ($pos = strpos($dirPath, ':'))) { + $namespace = self::getRootPath(substr($dirPath, 0, $pos)); + $dirPath = substr($dirPath, $pos + 1); + } else + $namespace = self::getRootPath(self::getAppName()); + $namespace && $dirPath = $namespace . D_S . str_replace('.', D_S, $dirPath); + return $dirPath; } /** @@ -388,48 +394,7 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - self::$_classes = array( - 'WindLogger' => 'log/WindLogger', - 'WindActionException' => 'core/exception/WindActionException', - 'WindException' => 'core/exception/WindException', - 'WindFinalException' => 'core/exception/WindFinalException', - 'IWindFactory' => 'core/factory/IWindFactory', - 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', - 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', - 'WindFactory' => 'core/factory/WindFactory', - 'IWindApplication' => 'core/IWindApplication', - 'IWindController' => 'core/IWindController', - 'IWindErrorMessage' => 'core/IWindErrorMessage', - 'IWindFrontController' => 'core/IWindFrontController', - 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', - 'WindFormListener' => 'core/web/listener/WindFormListener', - 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', - 'WindValidateListener' => 'core/web/listener/WindValidateListener', - 'WindController' => 'core/web/WindController', - 'WindDispatcher' => 'core/web/WindDispatcher', - 'WindErrorHandler' => 'core/web/WindErrorHandler', - 'WindErrorMessage' => 'core/web/WindErrorMessage', - 'WindForward' => 'core/web/WindForward', - 'WindFrontController' => 'core/web/WindFrontController', - 'WindHelper' => 'core/web/WindHelper', - 'WindSimpleController' => 'core/web/WindSimpleController', - 'WindSystemConfig' => 'core/web/WindSystemConfig', - 'WindUrlHelper' => 'core/web/WindUrlHelper', - 'WindWebApplication' => 'core/web/WindWebApplication', - 'WindEnableValidateModule' => 'core/WindEnableValidateModule', - 'WindModule' => 'core/WindModule', - 'WindFilter' => 'filter/WindFilter', - 'WindFilterChain' => 'filter/WindFilterChain', - 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', - 'WindConfigParser' => 'parser/WindConfigParser', - 'IWindRequest' => 'http/request/IWindRequest', - 'WindHttpRequest' => 'http/request/WindHttpRequest', - 'IWindResponse' => 'http/response/IWindResponse', - 'WindHttpResponse' => 'http/response/WindHttpResponse', - 'AbstractWindRouter' => 'router/AbstractWindRouter', - 'WindUrlBasedRouter' => 'router/WindUrlBasedRouter', - ); + self::$_classes = array('WindLogger' => 'log/WindLogger', 'WindActionException' => 'core/exception/WindActionException', 'WindException' => 'core/exception/WindException', 'WindFinalException' => 'core/exception/WindFinalException', 'IWindFactory' => 'core/factory/IWindFactory', 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', 'WindFactory' => 'core/factory/WindFactory', 'IWindApplication' => 'core/IWindApplication', 'IWindController' => 'core/IWindController', 'IWindErrorMessage' => 'core/IWindErrorMessage', 'IWindFrontController' => 'core/IWindFrontController', 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', 'WindFormListener' => 'core/web/listener/WindFormListener', 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', 'WindValidateListener' => 'core/web/listener/WindValidateListener', 'WindController' => 'core/web/WindController', 'WindDispatcher' => 'core/web/WindDispatcher', 'WindErrorHandler' => 'core/web/WindErrorHandler', 'WindErrorMessage' => 'core/web/WindErrorMessage', 'WindForward' => 'core/web/WindForward', 'WindFrontController' => 'core/web/WindFrontController', 'WindHelper' => 'core/web/WindHelper', 'WindSimpleController' => 'core/web/WindSimpleController', 'WindSystemConfig' => 'core/web/WindSystemConfig', 'WindUrlHelper' => 'core/web/WindUrlHelper', 'WindWebApplication' => 'core/web/WindWebApplication', 'WindEnableValidateModule' => 'core/WindEnableValidateModule', 'WindModule' => 'core/WindModule', 'WindFilter' => 'filter/WindFilter', 'WindFilterChain' => 'filter/WindFilterChain', 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', 'WindConfigParser' => 'parser/WindConfigParser', 'IWindRequest' => 'http/request/IWindRequest', 'WindHttpRequest' => 'http/request/WindHttpRequest', 'IWindResponse' => 'http/response/IWindResponse', 'WindHttpResponse' => 'http/response/WindHttpResponse', 'AbstractWindRouter' => 'router/AbstractWindRouter', 'WindUrlBasedRouter' => 'router/WindUrlBasedRouter'); } } Wind::init(); diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index f720dedb..1c377efe 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -62,25 +62,26 @@ - + - + - - - - - data - + + + + data diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index c1fe1e48..25d3e0ad 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -1,4 +1,5 @@ @@ -51,6 +52,37 @@ abstract class AbstractWindCache extends WindModule { */ const EXPIRE = 'expires'; + /** + * 执行添加操作 + * + * @param string $key + * @param object $value + * @param int $expires + * @throws WindException + */ + protected abstract function setValue($key, $value, $expires = 0); + + /** + * 执行获取操作 + * + * @param string $key + * @throws WindException + */ + protected abstract function getValue($key); + + /** + * 需要实现的删除操作 + * @param string $key + * @return + */ + protected abstract function deleteValue($key); + + /** + * 清空所有缓存 + * @return + */ + public abstract function clear(); + /** * 设置缓存,如果key不存在,设置缓存,否则,替换已有key的缓存。 * @param string $key 保存缓存数据的键。 @@ -60,42 +92,32 @@ abstract class AbstractWindCache extends WindModule { * @return boolean */ public function set($key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { - $data = array(self::DATA => $value, self::EXPIRE => $expires, self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); - if (null != $denpendency) { - $denpendency->injectDependent(); - $data[self::DEPENDENCY] = serialize($denpendency); - $data[self::DEPENDENCYCLASS] = get_class($denpendency); + try { + $data = array(self::DATA => $value, self::EXPIRE => $expires, self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); + if (null != $denpendency) { + $denpendency->injectDependent(); + $data[self::DEPENDENCY] = serialize($denpendency); + $data[self::DEPENDENCYCLASS] = get_class($denpendency); + } + return $this->setValue($this->buildSecurityKey($key), serialize($data), $expires); + } catch (Exception $e) { + throw new WindCacheException('Setting cache failed.' . $e->getMessage()); } - return $this->setValue($this->buildSecurityKey($key), serialize($data), $expires); } - /** - * 执行添加操作 - * - * @param string $key - * @param object $value - * @param int $expires - * @throws WindException - */ - protected abstract function setValue($key, $value, $expires = 0); - /** * 获取指定缓存 * @param string $key 获取缓存数据的标识,即键 * @return mixed */ public function get($key) { - return $this->formatData($key, $this->getValue($this->buildSecurityKey($key))); + try { + return $this->formatData($key, $this->getValue($this->buildSecurityKey($key))); + } catch (Exception $e) { + throw new WindCacheException('Getting cache data failed. (' . $e->getMessage() . ')'); + } } - /** - * 执行获取操作 - * - * @param string $key - * @throws WindException - */ - protected abstract function getValue($key); - /** * 通过key批量获取缓存数据 * @param array $keys @@ -116,15 +138,13 @@ public function batchGet(array $keys) { * @return string */ public function delete($key) { - return $this->deleteValue($this->buildSecurityKey($key)); + try { + return $this->deleteValue($this->buildSecurityKey($key)); + } catch (Exception $e) { + throw new WindException('Delete cache data failed. (' . $e->getMessage() . ')'); + } } - /** - * 需要实现的删除操作 - * @param string $key - */ - protected abstract function deleteValue($key); - /** * 通过key批量删除缓存数据 * @param array $keys @@ -136,41 +156,43 @@ public function batchDelete(array $keys) { return true; } - /** - * 清空所有缓存 - */ - public abstract function clear(); - /** * 格式化输出 + * * @param string $value * @return array */ protected function formatData($key, $value) { $data = unserialize($value); - if (!is_array($data)) return null; - if ($this->hasChanged($key, $data)) return null; - return isset($data[self::DATA]) ? $data[self::DATA] : null; + if (!is_array($data)) return array(); + if ($this->hasChanged($key, $data)) return array(); + return isset($data[self::DATA]) ? $data[self::DATA] : array(); } /** - * 如果缓存中有数据,则检查缓存依赖是否已经变更,如果变更则删除缓存 + * 如果缓存中有数据,则检查缓存依赖是否已经变更,如果变更则删除缓存 + * * @param string $key 键 * @param array $data 缓存中的数据 * @return boolean true表示缓存依赖已变更,false表示缓存依赖未变改 */ protected function hasChanged($key, array $data) { - if (null === $data[self::DEPENDENCY] && '' === $data[self::DEPENDENCYCLASS]) return false; - $dependency = unserialize($data[self::DEPENDENCY]); - if (($dependency instanceof AbstractWindCacheDependency) && $dependency->hasChanged()) { - $this->delete($key); - return true; - } - return false; + if (isset($data[self::DEPENDENCY]) && $data[self::DEPENDENCY]) { + $dependency = unserialize($data[self::DEPENDENCY]); + if (!$dependency->hasChanged()) return false; + } elseif (isset($data[self::EXPIRE]) && $data[self::EXPIRE]) { + $_overTime = $data[self::EXPIRE] + $data[self::STORETIME]; + if ($_overTime >= time()) return false; + } else + return false; + + $this->delete($key); + return true; } /** * 生成安全的key + * * @param string $key * @return string */ @@ -180,6 +202,7 @@ protected function buildSecurityKey($key) { /** * 返回缓存Key值前缀,默认值为null无任何前缀添加 + * * @return the $prefix */ protected function getKeyPrefix() { @@ -224,12 +247,13 @@ public function setExpire($expire) { /** * 设置配置信息 + * * @param array $config */ public function setConfig($config) { parent::setConfig($config); - $this->setSecurityCode($this->getConfig('securityCode', '', '')); - $this->setKeyPrefix($this->getConfig('keyPrefix', '', '')); - $this->setExpire($this->getConfig(self::EXPIRE, '', 0)); + $this->setSecurityCode($this->getConfig('security-code', '', '')); + $this->setKeyPrefix($this->getConfig('key-prefix', '', '')); + $this->setExpire($this->getConfig('expires', '', 0)); } } \ No newline at end of file diff --git a/wind/component/cache/WindCache.php b/wind/component/cache/WindCache.php index 42c7f41a..615b261c 100644 --- a/wind/component/cache/WindCache.php +++ b/wind/component/cache/WindCache.php @@ -18,7 +18,7 @@ class WindCache extends WindModule { const WINCACHE = 'win'; const XCACHE = 'XCache'; const ZEND = 'ZendCache'; - + /** * 保存数据 * @@ -33,7 +33,7 @@ public function set($type, $key, $value, $expires = 0, AbstractWindCacheDependen $cache = $this->getCache($type); return $cache->set($key, $value, $expires, $denpendency); } - + /** * 获取数据 * @@ -45,7 +45,7 @@ public function get($type, $key) { $cache = $this->getCache($type); return $cache->get($key); } - + /** * 删除缓存数据 * @@ -57,7 +57,7 @@ public function delete($type, $key) { $cache = $this->getCache($type); return $cache->delete($key); } - + /** * 批量获取数据 * @@ -69,7 +69,7 @@ public function batchGet($type, array $keys) { $cache = $this->getCache($type); return $cache->batchGet($keys); } - + /** * 通过key批量删除缓存数据 * @@ -81,7 +81,7 @@ public function batchDelete($type, array $keys) { $cache = $this->getCache($type); return $cache->batchDelete($keys); } - + /** * 通过key批量删除缓存数据 * @@ -93,13 +93,12 @@ public function clear($type = '') { $cache = $this->getCache($type); return $cache->clear(); } - foreach($this->caches as $key => $cache) { + foreach ($this->caches as $key => $cache) { $cache->clear(); } return true; } - - + /** * 获得缓存类型 * @@ -108,25 +107,26 @@ public function clear($type = '') { */ public function getCache($type) { $className = $this->getCacheMap($type); - if (!$className) throw new WindException('The cache strategy \'' . $type . '\' is not exists!'); - if (isset($this->caches[$className])) return $this->caches[$className]; + if (!$className) + throw new WindException('The cache strategy \'' . $type . '\' is not exists!'); + if (isset($this->caches[$className])) + return $this->caches[$className]; Wind::import('WIND:component.cache.strategy.' . $className); $cache = new $className(); $config = $this->getSystemConfig()->getCacheConfig($type); - if ($config) $cache->setConfig($config); + if ($config) + $cache->setConfig($config); $this->caches[$className] = $cache; return $cache; } - + /** * 对应类型对应的缓存 * * @param string $type */ private function getCacheMap($type) { - $types = array(self::DB => 'WindDbCache', self::APC => 'WindApcCache', self::FILE => 'WindFileCache', - self::EAC => 'WindEacceleratorCache', self::MEMCACHE => 'WindMemCache', self::WINCACHE => 'WindWinCache', - self::XCACHE => 'WindXCache', self::ZEND => 'WindZendCache'); + $types = array(self::DB => 'WindDbCache', self::APC => 'WindApcCache', self::FILE => 'WindFileCache', self::EAC => 'WindEacceleratorCache', self::MEMCACHE => 'WindMemCache', self::WINCACHE => 'WindWinCache', self::XCACHE => 'WindXCache', self::ZEND => 'WindZendCache'); return isset($types[$type]) ? $types[$type] : null; } } \ No newline at end of file diff --git a/wind/component/cache/exception/WindCacheException.php b/wind/component/cache/exception/WindCacheException.php new file mode 100644 index 00000000..17a4c37e --- /dev/null +++ b/wind/component/cache/exception/WindCacheException.php @@ -0,0 +1,13 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindCacheException extends WindException { + + +} + +?> \ No newline at end of file diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index dbfdb0b4..0fa6c0e8 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -31,58 +31,56 @@ class WindFileCache extends AbstractWindCache { * 保存操作的路径信息, 存储使用过的key路径 * @var array */ - private $cacheFileList = array(); + private $cacheFileList = array(); /* (non-PHPdoc) * @see AbstractWindCache::setValue() */ protected function setValue($key, $value, $expire = 0) { - return $this->writeData($key, $value, $expire); + return WindFile::write($key, $value) == strlen($value); } /* (non-PHPdoc) * @see AbstractWindCache::get() */ protected function getValue($key) { - return $this->readData($key); + if (!is_file($key)) return null; + return WindFile::read($key); } /* (non-PHPdoc) * @see AbstractWindCache::deleteValue() */ protected function deleteValue($cacheFile) { - if (is_file($cacheFile)) return WindFile::delFile($cacheFile); - return false; + return WindFile::write($cacheFile, ''); } /* (non-PHPdoc) * @see AbstractWindCache::clear() */ - public function clear($isExpired = false) { - return WindFile::clearDir($this->getCacheDir(), $isExpired); + public function clear() { + return WindFile::clearDir($this->getCacheDir()); } /** - * 获取缓存文件名。 + * 获取缓存文件名。 + * * @param string $key * @return string */ protected function buildSecurityKey($key) { - $key = str_replace(D_S, '', $key); - if (($dir = $this->checkCacheDir($key)) !== false) return $dir; - $filename = parent::buildSecurityKey($key) . '.' . trim($this->getCacheFileSuffix(), '.'); - $_tmp = $this->getCacheDir(); - if (0 < $this->getCacheDirectoryLevel()) { - for ($i = $this->getCacheDirectoryLevel(); $i > 0; --$i) { - if (false === ($prefix = substr($key, $i+$i, 2))) continue; - $_tmp .= DIRECTORY_SEPARATOR . $prefix; - } + if ($dir = $this->checkCacheDir($key)) return $dir; + $_dir = $this->getCacheDir(); + if ($level = $this->getCacheDirectoryLevel()) { + $_subdir = substr(md5($key), 0, $level); + $_dir .= DIRECTORY_SEPARATOR . $_subdir; + if (!is_dir($_dir)) mkdir($_dir, 0777, true); } - if (!is_dir($_tmp)) mkdir($_tmp, 0777, true); - $this->cacheFileList[$key] = $_tmp . D_S . $filename; - return $_tmp . D_S . $filename; + $filename = parent::buildSecurityKey($key) . '.' . $this->getCacheFileSuffix(); + $this->cacheFileList[$key] = ($_dir ? $_dir . DIRECTORY_SEPARATOR . $filename : $filename); + return $this->cacheFileList[$key]; } - + /** * 采用最近最少使用原则算法 * @@ -93,65 +91,30 @@ private function checkCacheDir($key) { return isset($this->cacheFileList[$key]) ? $this->cacheFileList[$key] : false; } - /** - * 写入文件缓存 - * @param string $file 缓存文件名 - * @param string $data 缓存数据 - * @param int $mtime 缓存文件的修改时间,即缓存的过期时间 - * @return boolean - */ - private function writeData($file, $data, $mtime = 0) { - if (WindFile::write($file, $data) == strlen($data)) { - $mtime += $mtime ? time() : 0; - chmod($file, 0777); - return touch($file, $mtime); - } - return false; - } - - /** - * 从文件中读取缓存内容 - * @param string $file 缓存文件名 - * @return null|string - */ - private function readData($file) { - if (false === is_file($file)) return null; - clearstatcache(); - $mtime = filemtime($file); - if (0 === $mtime || ($mtime && $mtime > time())) - return WindFile::read($file); - elseif (0 < $mtime) - WindFile::delFile($file); - return null; - } - /** * 设置缓存目录 * @param string $dir */ public function setCacheDir($dir) { - $this->cacheFileList = array(); - $dir = (false === strpos($dir, ':')) ? Wind::getAppName() . ':' . $dir : $dir; - $this->cacheDir = !is_dir($dir) ? Wind::getRealDir($dir) : $dir; + $_dir = Wind::getRealDir($dir); + if (!is_dir($_dir)) mkdir($_dir, 0777, true); + $this->cacheDir = $_dir; } /** * @return the $cacheDir */ private function getCacheDir() { - if (!is_dir($this->cacheDir)) mkdir($this->cacheDir, 0777, true); return $this->cacheDir; } - /** * @param string $cacheFileSuffix */ public function setCacheFileSuffix($cacheFileSuffix) { - $this->cacheFileList = array(); $this->cacheFileSuffix = $cacheFileSuffix; } - + /** * @return the $cacheFileSuffix */ @@ -163,25 +126,17 @@ private function getCacheFileSuffix() { * @param int $cacheDirectoryLevel */ public function setCacheDirectoryLevel($cacheDirectoryLevel) { - $cacheDirectoryLevel = intval($cacheDirectoryLevel); - $this->cacheDirectoryLevel = $cacheDirectoryLevel > 5 ? 5 : ($cacheDirectoryLevel < 0 ? 0 : $cacheDirectoryLevel); + $this->cacheDirectoryLevel = $cacheDirectoryLevel; } - + /** * 返回cache目录级别,默认为0,不分级,最大分级为5 * @return the $cacheDirectoryLevel */ - private function getCacheDirectoryLevel() { + public function getCacheDirectoryLevel() { return $this->cacheDirectoryLevel; } - /** - * 垃圾回收,清理过期缓存 - */ - public function __destruct() { -// $this->clear(true); - } - /* (non-PHPdoc) * @see AbstractWindCache::setConfig() */ @@ -189,7 +144,6 @@ public function setConfig($config) { parent::setConfig($config); $this->setCacheDir($this->getConfig('dir')); $this->setCacheFileSuffix($this->getConfig('suffix', '', 'txt')); - $this->setCacheDirectoryLevel($this->getConfig('dirLevel', '', '0')); } } \ No newline at end of file diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index 910780ab..07449623 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -51,11 +51,10 @@ public function getDao($className) { return $daoInstance; } catch (Exception $exception) { Wind::log( - '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . - $exception->getMessage(), WindLogger::LEVEL_DEBUG, 'wind.component'); + '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . $exception->getMessage(), + WindLogger::LEVEL_DEBUG, 'wind.component'); throw new WindDaoException( - '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . - $exception->getMessage()); + '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . $exception->getMessage()); } } @@ -100,17 +99,20 @@ private function registerCacheListener($daoInstance) { * @param WindDao $daoObject */ protected function createDbConnection($daoObject) { - if (!($configName = $daoObject->getDBName())) - $alias = 'db_default'; - else - $alias = 'db_' . $configName; + $configName = $daoObject->getDBName(); + $config = $this->getSystemConfig()->getDbConfig($configName); + if (!$config) + throw new WindDbException('[component.dao.WindDaoFactory.createDbConnection] (' . $configName . ')', + WindDbException::DB_CONN_NOT_EXIST); + + $_path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); + $alias = $configName ? $_path . $configName : $_path; if (!$this->getSystemFactory()->checkAlias($alias)) { - $config = $this->getSystemConfig()->getDbConfig($configName); - if (!$config) - throw new WindDbException('[component.dao.WindDaoFactory.createDbConnection] (' . $configName . ')', - WindDbException::DB_CONN_NOT_EXIST); - $_path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); - $definition = array('path' => $_path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', + $definition = array( + 'path' => $_path, + 'alias' => $alias, + 'config' => $config, + 'initMethod' => 'init', 'scope' => 'application'); $this->getSystemFactory()->addClassDefinitions($alias, $definition); } diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index 53a37578..01d7807e 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -48,8 +48,7 @@ class WindConfigParser implements IWindConfigParser { * @return array 解析结果 */ public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { - if ($config = $this->getCache($alias, $append, $cache)) - return $config; + if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; @@ -62,14 +61,14 @@ public function parse($configPath, $alias = '', $append = '', AbstractWindCache * @param AbstractWindCache $cache */ private function setCache($alias, $append, $cache, $data) { - if (!$alias || !$cache) - return; + if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); - } else + } else { $cache->set($alias, $data); + } } /** @@ -80,27 +79,13 @@ private function setCache($alias, $append, $cache, $data) { * @return array */ private function getCache($alias, $append, $cache) { - if (!$alias || !$cache) - return array(); - $_key = $append ? $append : $alias; - $config = $cache->get($_key); + if (!$alias || !$cache) return array(); + if (!$append) return $cache->get($alias); + + $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } - /** - * 获得缓存文件内容 - * - * @param AbstractWindCache $cache - * @param string $file 缓存文件名 - * @return array 缓存文件内容 - */ - private function getCacheContent(AbstractWindCache $cache, $file) { - $content = array(); - if (is_file($file)) - $content = $cache->get($file); - return is_array($content) ? $content : array(); - } - /** * 创建配置文件解析器 * @@ -135,14 +120,11 @@ private function createParser($type) { * @return array 返回解析结果 */ private function doParser($configFile) { - if (!is_file($configFile)) - throw new WindException( - '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); + if (!is_file($configFile)) throw new WindException( + '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); - if ($ext == self::CONFIG_PHP) - return @include ($configFile); - if (!isset($this->configParsers[$ext])) - $this->configParsers[$ext] = $this->createParser($ext); + if ($ext == self::CONFIG_PHP) return @include ($configFile); + if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } \ No newline at end of file diff --git a/wind/component/utility/WindFile.php b/wind/component/utility/WindFile.php index 5ba47fe5..29156154 100644 --- a/wind/component/utility/WindFile.php +++ b/wind/component/utility/WindFile.php @@ -1,4 +1,6 @@ @@ -47,7 +49,6 @@ class WindFile { * @param boolean $ifLock 是否对文件加锁 */ public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { - Wind::import("COM:utility.WindString"); $temp = " $value) { @@ -74,7 +75,6 @@ public static function savePhpData($fileName, $data, $isBuildReturn = true, $met * @return int 返回写入的字节数 */ public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { - Wind::import("COM:utility.WindSecurity"); $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; @@ -94,7 +94,6 @@ public static function write($fileName, $data, $method = self::READWRITE, $ifLoc * @return string */ public static function read($fileName, $method = self::READ) { - Wind::import("COM:utility.WindSecurity"); $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { @@ -108,10 +107,12 @@ public static function read($fileName, $method = self::READ) { /** * 按目录删除文件 * @param string $dir 目录 - * @param boolean $ifexpiled 是否过期 + * @param boolean $ifexpiled 是否过期 + * @deprecated * @return boolean */ public static function clearDir($dir, $ifexpiled = false) { + //TODO 删除掉是否过期相关处理,不要将外部业务需求,耦合进工具库方法 if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; @@ -223,7 +224,7 @@ public static function getDirectoryInfo($dir) { * @return boolean */ public static function delFile($filename) { - return unlink($filename); + return @unlink($filename); } /** diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 2d893a22..5b21f2a4 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -144,10 +144,10 @@ protected function buildConfig(&$definition, $alias) { if (!($config = $definition['config'])) return array(); if (isset($config['resource']) && !empty($config['resource'])) { - $_configPath = Wind::getRealPath($config['resource'], false); + $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($_configPath, $alias, 'cache_wind_config', - $this->getInstance(COMPONENT_CACHE)); + $cache = $alias !== COMPONENT_CACHE ? $this->getInstance(COMPONENT_CACHE) : null; + $config = $configParser->parse($_configPath, $alias, 'components_config_cache', $cache); } if (isset($config['class']) && !$definition['path']) { $definition['path'] = $config['class']; diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 08d4f5dd..77685543 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -40,10 +40,12 @@ public function __construct($appName, $config = '') { try { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(); - $this->init($appName, $config); + $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); + $this->windFactory = new WindFactory(@include ($configPath)); + $this->windSystemConfig = new WindSystemConfig($config, $appName, $this->windFactory); } catch (Exception $e) { Wind::log('System failed to initialize. (' . $e->getMessage() . ')', WindLogger::LEVEL_INFO, 'wind.core'); - throw new WindException('System failed to initialize.'); + throw new WindException('System failed to initialize.' . $e->getMessage()); } } @@ -82,16 +84,6 @@ protected function getFilterChain() { return $this->getWindFactory()->createInstance($filterChainPath, array($filters)); } - /** - * 初始全局工厂类 - * @return - */ - protected function init($appName, $config) { - $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); - $this->windFactory = new WindFactory(@include ($configPath)); - $this->windSystemConfig = new WindSystemConfig($config, $appName, $this->windFactory); - } - /** * 预处理Process方法 */ diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 5f881fb6..25cee0d6 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -177,7 +177,7 @@ public function getModuleControllerSuffixByModuleName($name, $default = '') { public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { - $_resource = Wind::getRealPath($config['resource'], false); + $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); From 5723ab89df44151fdfcd777d31b31a6d5f1619fc Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 28 Jul 2011 22:26:24 +0000 Subject: [PATCH 0214/1065] =?UTF-8?q?Wind.php=20realpath=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AF=B9=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=90=8E=E7=BC=80=E7=9A=84=E5=A4=84=E7=90=86=20?= =?UTF-8?q?=E6=94=B9=E8=BF=9BWindFileCache=E7=AD=96=E7=95=A5=EF=BC=8C=20?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E6=AC=A1=E6=96=87=E4=BB=B6=E5=88=A4?= =?UTF-8?q?=E6=96=AD=EF=BC=8C=E5=B0=86=E5=AF=B9=E8=BF=87=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=88=A4=E6=96=AD=E7=AD=96=E7=95=A5=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=88=B0=20hasChange()=20=E6=96=B9=E6=B3=95=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=96=87=E4=BB=B6=E5=A4=B9=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E7=9A=84=E7=AD=96=E7=95=A5=E6=94=B9=E8=BF=9B=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E8=AF=A5=E7=AD=96=E7=95=A5=EF=BC=88=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=95=88=E7=8E=87=E7=BC=BA=E9=99=B7=EF=BC=8C=E4=B8=8D=E5=A4=AA?= =?UTF-8?q?=E5=AE=9E=E7=94=A8=EF=BC=89=20=E5=A2=9E=E5=8A=A0cache=E5=B1=82?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=20dbCache=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E8=BF=9B=E8=A1=8C=E5=88=B0=E4=B8=80=E5=8D=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2274 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDaoFactory.php | 33 ++++-------- wind/component/db/WindConnection.php | 50 ++++++++++++++----- wind/component/db/WindSqlStatement.php | 9 ++-- .../db/mysql/WindMysqlPdoAdapter.php | 25 +++++++--- 4 files changed, 72 insertions(+), 45 deletions(-) diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index 07449623..dd00caac 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -41,8 +41,7 @@ public function getDao($className) { if (strpos($className, ":") === false && strpos($className, ".") === false) { $className = $this->getDaoResource() . '.' . $className; } - if (isset($this->daos[$className])) - return $this->daos[$className]; + if (isset($this->daos[$className])) return $this->daos[$className]; $className = Wind::import($className); $daoInstance = WindFactory::createInstance($className); @@ -81,14 +80,12 @@ public function setDaoResource($daoResource) { private function registerCacheListener($daoInstance) { $caches = (array) $daoInstance->getCacheMethods(); foreach ($caches as $classMethod => $classPath) { - if (!$classMethod) - continue; + if (!$classMethod) continue; if ($classPath === 'default') $_className = Wind::import('COM:dao.listener.WindDaoCacheListener'); else $_className = Wind::import($classPath); - if (!$_className) - continue; + if (!$_className) continue; $daoInstance->registerEventListener($classMethod, new $_className($daoInstance)); } } @@ -101,21 +98,14 @@ private function registerCacheListener($daoInstance) { protected function createDbConnection($daoObject) { $configName = $daoObject->getDBName(); $config = $this->getSystemConfig()->getDbConfig($configName); - if (!$config) - throw new WindDbException('[component.dao.WindDaoFactory.createDbConnection] (' . $configName . ')', - WindDbException::DB_CONN_NOT_EXIST); + if (!$config) throw new WindDbException( + '[component.dao.WindDaoFactory.createDbConnection] (' . $configName . ')', + WindDbException::DB_CONN_NOT_EXIST); - $_path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); - $alias = $configName ? $_path . $configName : $_path; - if (!$this->getSystemFactory()->checkAlias($alias)) { - $definition = array( - 'path' => $_path, - 'alias' => $alias, - 'config' => $config, - 'initMethod' => 'init', - 'scope' => 'application'); - $this->getSystemFactory()->addClassDefinitions($alias, $definition); - } + $path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); + $alias = $configName ? $path . $configName : $path . get_class($this); + $definition = array('path' => $path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', 'scope' => 'application'); + $this->getSystemFactory()->addClassDefinitions($alias, $definition); $daoObject->setDelayAttributes(array('connection' => array('ref' => $alias))); } @@ -125,8 +115,7 @@ protected function createDbConnection($daoObject) { * @param WindDao $daoObject */ protected function createCacheHandler($daoObject) { - if (!($_className = $daoObject->getCacheClass())) - return; + if (!($_className = $daoObject->getCacheClass())) return; $_classConfig = $daoObject->getCacheConfig(); $_alias = $_className . '_' . md5((is_string($_classConfig) ? $_classConfig : serialize($_classConfig))); if (!$this->getSystemFactory()->checkAlias($_alias)) { diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 062c5baa..5e305fe7 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -165,27 +165,54 @@ public function query($sql) { } } - /* (non-PHPdoc) - * @see WindMysqlPdoAdapter::filterArray() + /** + * 过滤SQL元数据,数据库对象(如表名字,字段等) + * + * @param string $data + * @throws WindDbException + */ + public function sqlMetadata($data) { + $data = str_replace(array('`', ' '), '', $data); + return ' `' . $data . '` '; + } + + /** + * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组 + * + * @param array $array */ public function quoteArray($array) { return $this->getDbHandle()->filterArray($array); } - /* (non-PHPdoc) - * @see WindMysqlPdoAdapter::quote() + /** + * sql元数据安全过滤 + * + * @param string $string */ public function quote($string) { return $this->getDbHandle()->quote($string); } - - /* (non-PHPdoc) - * @see WindMysqlPdoAdapter::sqlSingle() + + /** + * 组装单条 key=value 形式的SQL查询语句值 insert/update并进行安全过滤 + * + * @param array $array */ public function sqlSingle($array) { return $this->getDbHandle()->sqlSingle($array); } - + + /** + * 创建表 + * + * @param string $tableName + * @param array $fileds + */ + public function createTable($tableName, $values, $engine = '', $autoIncrement = '') { + return $this->getDbHandle()->createTable($tableName, $values, $engine, $this->_charset, $autoIncrement); + } + /** * 返回最后一条插入数据ID * @@ -230,9 +257,8 @@ public function init() { $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->_dbHandle->setCharset($this->_charset); Wind::log( - "component.db.WindConnection.init() \r\n dsn: " . $this->_dsn . " \r\n username: " . $this->_user . - " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, - WindLogger::LEVEL_DEBUG); + "component.db.WindConnection.init() \r\n dsn: " . $this->_dsn . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, + WindLogger::LEVEL_DEBUG); } catch (PDOException $e) { $this->close(); Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", WindLogger::LEVEL_TRACE); @@ -241,7 +267,7 @@ public function init() { } /** - * (non-PHPdoc) + * (non-PHPdoc) * @see WindModule::setConfig() */ public function setConfig($config) { diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 6c4b24ff..dc9d0134 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -27,8 +27,7 @@ class WindSqlStatement { * * @var array */ - private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'string' => PDO::PARAM_STR, - 'NULL' => PDO::PARAM_NULL); + private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); private $_columns = array(); /** @@ -137,7 +136,7 @@ public function bindValue($parameter, $value, $data_type = null) { */ public function bindValues($values) { if (!is_array($values)) { - throw new WindSqlException( + throw new WindDbException( '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type ' . gettype($values)); } $keied = (array_keys($values) !== range(0, sizeof($values) - 1)); @@ -356,8 +355,8 @@ public function init() { "component.db"); $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString()); Wind::log( - "component.db.WindSqlStatement._init Initialize DBStatement. This statement is " . - get_class($this->_statement), WindLogger::LEVEL_DEBUG, "component.db"); + "component.db.WindSqlStatement._init Initialize DBStatement. This statement is " . get_class( + $this->_statement), WindLogger::LEVEL_DEBUG, "component.db"); } catch (PDOException $e) { Wind::log("Component.db.WindSqlStatement._init Initialize DBStatement failed.", WindLogger::LEVEL_TRACE, "component.db"); diff --git a/wind/component/db/mysql/WindMysqlPdoAdapter.php b/wind/component/db/mysql/WindMysqlPdoAdapter.php index 472b3a8b..719ab15f 100644 --- a/wind/component/db/mysql/WindMysqlPdoAdapter.php +++ b/wind/component/db/mysql/WindMysqlPdoAdapter.php @@ -6,7 +6,20 @@ * @package */ class WindMysqlPdoAdapter extends PDO { - + + /** + * 创建表 + * @param $tableName + * @param $values + */ + public function createTable($tableName, $values, $engine, $charset, $autoIncrement) { + $_sql = "CREATE TABLE IF NOT EXISTS $tableName ($values)ENGINE="; + $_sql .= $engine ? $engine : 'MyISAM'; + $_sql .= $charset ? " DEFAULT CHARSET=$charset" : ''; + $_sql .= $autoIncrement ? " AUTO_INCREMENT=$autoIncrement" : ''; + return $this->query($_sql); + } + /** * 设置链接使用字符集 * @param string $charset @@ -40,7 +53,7 @@ public function filterArray($variable, $result = '') { } return $result; } - + /** * 组装单条 key=value 形式的SQL查询语句值 insert/update * @param $array @@ -48,22 +61,22 @@ public function filterArray($variable, $result = '') { * @return string */ public function sqlSingle($array) { - if (!is_array($array)) return ''; + if (!is_array($array)) return ''; $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . $this->fieldMeta($key) . '=' . $this->quote($val); } return $str; } - + /** * 过滤SQL元数据,数据库对象(如表名字,字段等) * @param $data 元数据 * @return string 经过转义的元数据字符串 */ private function fieldMeta($data) { - $data = str_replace(array('`', ' '), '',$data); - return ' `'.$data.'` '; + $data = str_replace(array('`', ' '), '', $data); + return ' `' . $data . '` '; } } ?> \ No newline at end of file From c80eb39ae895d592e963c90a69e236c721043648 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 29 Jul 2011 02:00:35 +0000 Subject: [PATCH 0215/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2275 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindFileCache.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 0fa6c0e8..76181e17 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -69,9 +69,9 @@ public function clear() { * @return string */ protected function buildSecurityKey($key) { - if ($dir = $this->checkCacheDir($key)) return $dir; + if (false !== ($dir = $this->checkCacheDir($key))) return $dir; $_dir = $this->getCacheDir(); - if ($level = $this->getCacheDirectoryLevel()) { + if (0 <= ($level = $this->getCacheDirectoryLevel())) { $_subdir = substr(md5($key), 0, $level); $_dir .= DIRECTORY_SEPARATOR . $_subdir; if (!is_dir($_dir)) mkdir($_dir, 0777, true); From 2908d27985d94409bb06d10590cc15ae9643c5f3 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 29 Jul 2011 02:01:03 +0000 Subject: [PATCH 0216/1065] =?UTF-8?q?DAO:cache=E7=B1=BB=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2276 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDaoFactory.php | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index dd00caac..64728594 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -119,22 +119,13 @@ protected function createCacheHandler($daoObject) { $_classConfig = $daoObject->getCacheConfig(); $_alias = $_className . '_' . md5((is_string($_classConfig) ? $_classConfig : serialize($_classConfig))); if (!$this->getSystemFactory()->checkAlias($_alias)) { - $definition = new WindClassDefinition(); - $definition->setPath($_className); - $definition->setAlias($_alias); - $definition->setInitMethod('init'); - $definition->setScope(WindClassDefinition::SCOPE_SINGLETON); - if (is_array($_classConfig)) - $definition->setConfig($_classConfig); - else - $definition->setConfig(array(WindClassDefinition::RESOURCE => $_classConfig)); - - $this->getSystemFactory()->addClassDefinitions($definition); + $definition = array('path' => $_className, 'alias' => $_alias, 'initMethod' => 'init', 'scope' => 'singleton'); + $definition['config'] = is_array($_classConfig) ? $_classConfig : array('resource' => $_classConfig); + $this->getSystemFactory()->addClassDefinitions($_alias, $definition); } - $daoObject->setDelayAttributes(array('cacheHandler' => array(WindClassDefinition::REF => $_alias))); + $daoObject->setDelayAttributes(array('cacheHandler' => array('ref' => $_alias))); $daoObject = new WindClassProxy($daoObject); $this->registerCacheListener($daoObject); } - } ?> \ No newline at end of file From c065ac1af7c87bd83d72e79859f43f4bdad34079 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 29 Jul 2011 02:31:12 +0000 Subject: [PATCH 0217/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2277 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindDbCache.php | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index 9c590fb2..a229ea08 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -49,7 +49,7 @@ class WindDbCache extends AbstractWindCache { * 缓存表过期时间字段 * @var string */ - private $connectionConfig = ''; + private $dbConfigName = ''; public function __construct(WindConnection $connection = null, $config = array()) { $connection && $this->setConnection($connection); @@ -133,12 +133,11 @@ public function deleteExpiredCache() { */ public function setConfig($config) { parent::setConfig($config); - $config = $this->getConfig('cacheTables'); - $this->table = $this->getConfig('tableName', '', 'pw_cache', $config); - $this->keyField = $this->getConfig('fieldKey', '', 'key', $config); - $this->valueField = $this->getConfig('fieldValue', '', 'value', $config); - $this->expireField = $this->getConfig('fieldExpire', '', 'expire', $config); - $this->connectionConfig = $this->getConfig('connection', '', 'default', $config); + $this->table = $this->getConfig('table-name', '', 'pw_cache', $config); + $this->keyField = $this->getConfig('field-key', '', 'key', $config); + $this->valueField = $this->getConfig('field-value', '', 'value', $config); + $this->expireField = $this->getConfig('field-expire', '', 'expire', $config); + $this->dbConfigName = $this->getConfig('dbconfig-name', '', '', $config); } /** @@ -172,16 +171,11 @@ public function setConnection($connection) { */ private function getConnection() { if (null == $this->connection) { - $alias = 'db_' . $this->connectionConfig; + $config = $this->getSystemConfig()->getDbConfig($this->dbConfigName); + $path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); + $alias = $this->dbConfigName ? $path . $this->dbConfigName : $path . get_class($this); if (!$this->getSystemFactory()->checkAlias($alias)) { - $config = $this->getSystemConfig()->getDbConfig($this->connectionConfig); - $definition = array( - 'path' => $this->getConfig('class', '', 'COM:db.WindConnection', $config), - 'alias' => $alias, - 'config' => $config, - 'initMethod' => 'init', - 'scope' => 'application', - ); + $definition = array('path' => $path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', 'scope' => 'application'); $this->getSystemFactory()->addClassDefinitions($alias, $definition); } $this->connection = $this->getSystemFactory()->getInstance($alias); From e364b551a767d5ca8642e639ef7bdf18e4f0a45e Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 29 Jul 2011 02:31:28 +0000 Subject: [PATCH 0218/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2278 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/dbcache_config.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/configtemplate/dbcache_config.xml b/docs/configtemplate/dbcache_config.xml index 5f0ab8da..112a8ca2 100644 --- a/docs/configtemplate/dbcache_config.xml +++ b/docs/configtemplate/dbcache_config.xml @@ -7,6 +7,8 @@ + + pw_cache From f2d3ea07f7ba95c4be1170b20ec29aabf03e615a Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 29 Jul 2011 09:12:01 +0000 Subject: [PATCH 0219/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2279 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindFileCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 76181e17..34b115a5 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -71,7 +71,7 @@ public function clear() { protected function buildSecurityKey($key) { if (false !== ($dir = $this->checkCacheDir($key))) return $dir; $_dir = $this->getCacheDir(); - if (0 <= ($level = $this->getCacheDirectoryLevel())) { + if (0 < ($level = $this->getCacheDirectoryLevel())) { $_subdir = substr(md5($key), 0, $level); $_dir .= DIRECTORY_SEPARATOR . $_subdir; if (!is_dir($_dir)) mkdir($_dir, 0777, true); From d0dd6746bc3489a543f18b8307333fdebf3bb69e Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 1 Aug 2011 02:11:11 +0000 Subject: [PATCH 0220/1065] =?UTF-8?q?Wind.php=20realpath=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AF=B9=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=90=8E=E7=BC=80=E7=9A=84=E5=A4=84=E7=90=86=20?= =?UTF-8?q?=E6=94=B9=E8=BF=9BWindFileCache=E7=AD=96=E7=95=A5=EF=BC=8C=20?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E6=AC=A1=E6=96=87=E4=BB=B6=E5=88=A4?= =?UTF-8?q?=E6=96=AD=EF=BC=8C=E5=B0=86=E5=AF=B9=E8=BF=87=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=88=A4=E6=96=AD=E7=AD=96=E7=95=A5=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=88=B0=20hasChange()=20=E6=96=B9=E6=B3=95=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=96=87=E4=BB=B6=E5=A4=B9=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E7=9A=84=E7=AD=96=E7=95=A5=E6=94=B9=E8=BF=9B=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E8=AF=A5=E7=AD=96=E7=95=A5=EF=BC=88=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=95=88=E7=8E=87=E7=BC=BA=E9=99=B7=EF=BC=8C=E4=B8=8D=E5=A4=AA?= =?UTF-8?q?=E5=AE=9E=E7=94=A8=EF=BC=89=20=E5=A2=9E=E5=8A=A0cache=E5=B1=82?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=20dbCache=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E8=BF=9B=E8=A1=8C=E5=88=B0=E4=B8=80=E5=8D=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2280 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindFileCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 34b115a5..4b1fe9d8 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -34,7 +34,7 @@ class WindFileCache extends AbstractWindCache { private $cacheFileList = array(); /* (non-PHPdoc) - * @see AbstractWindCache::setValue() + * @see AbstractWindCache::setValue($key, $value, $expires) */ protected function setValue($key, $value, $expire = 0) { return WindFile::write($key, $value) == strlen($value); From 89dc3cf6b805a9a0e9210bb59759203a1e77fafe Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 1 Aug 2011 03:09:17 +0000 Subject: [PATCH 0221/1065] =?UTF-8?q?Wind.php=20realpath=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AF=B9=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=90=8E=E7=BC=80=E7=9A=84=E5=A4=84=E7=90=86=20?= =?UTF-8?q?=E6=94=B9=E8=BF=9BWindFileCache=E7=AD=96=E7=95=A5=EF=BC=8C=20?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E6=AC=A1=E6=96=87=E4=BB=B6=E5=88=A4?= =?UTF-8?q?=E6=96=AD=EF=BC=8C=E5=B0=86=E5=AF=B9=E8=BF=87=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=88=A4=E6=96=AD=E7=AD=96=E7=95=A5=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=88=B0=20hasChange()=20=E6=96=B9=E6=B3=95=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=96=87=E4=BB=B6=E5=A4=B9=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E7=9A=84=E7=AD=96=E7=95=A5=E6=94=B9=E8=BF=9B=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E8=AF=A5=E7=AD=96=E7=95=A5=EF=BC=88=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=95=88=E7=8E=87=E7=BC=BA=E9=99=B7=EF=BC=8C=E4=B8=8D=E5=A4=AA?= =?UTF-8?q?=E5=AE=9E=E7=94=A8=EF=BC=89=20=E5=A2=9E=E5=8A=A0cache=E5=B1=82?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=20dbCache=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E8=BF=9B=E8=A1=8C=E5=88=B0=E4=B8=80=E5=8D=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2281 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 5b21f2a4..072a9ff8 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -40,10 +40,8 @@ public function __construct($classDefinitions = array()) { * @see AbstractWindFactory::getInstance() */ public function getInstance($alias, $args = array()) { - if (isset($this->instances[$alias])) - return $this->instances[$alias]; - if (!($definition = $this->checkAlias($alias))) - return null; + if (isset($this->instances[$alias])) return $this->instances[$alias]; + if (!($definition = $this->checkAlias($alias))) return null; $this->buildDefinition($definition); $_subDefinitions = $definition['constructorArg']; foreach ($_subDefinitions as $_subDefinition) { @@ -54,14 +52,10 @@ public function getInstance($alias, $args = array()) { } $config = $this->buildConfig($definition, $alias); $instance = $this->createInstance($definition['className'], $args); - if (!empty($config)) - $instance->setConfig($config); - if ($definition['properties']) - $this->buildProperties($definition['properties'], $instance); - if ($definition['initMethod']) - $this->executeInitMethod($definition['initMethod'], $instance); - if ($definition['proxy']) - $instance = $this->setProxyForClass($definition['proxy'], $instance); + if (!empty($config)) $instance->setConfig($config); + if ($definition['properties']) $this->buildProperties($definition['properties'], $instance); + if ($definition['initMethod']) $this->executeInitMethod($definition['initMethod'], $instance); + if ($definition['proxy']) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; @@ -88,8 +82,7 @@ static public function createInstance($className, $args = array()) { */ public function getPrototype($alias) { $instance = $this->getInstance($alias); - if ($instance === null) - return null; + if ($instance === null) return null; return clone $instance; } @@ -101,6 +94,7 @@ public function getPrototype($alias) { * @return */ public function addClassDefinitions($alias, $classDefinition) { + if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } @@ -141,8 +135,7 @@ protected function setScope($alias, $scope, $instance) { * @return */ protected function buildConfig(&$definition, $alias) { - if (!($config = $definition['config'])) - return array(); + if (!($config = $definition['config'])) return array(); if (isset($config['resource']) && !empty($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance(COMPONENT_CONFIGPARSER); @@ -181,8 +174,7 @@ protected function executeInitMethod($initMethod, $instance) { * @return WindClassProxy */ protected function setProxyForClass($proxy, $instance) { - if ($proxy === 'false' || $proxy === false) - return $instance; + if ($proxy === 'false' || $proxy === false) return $instance; $proxy = Wind::import(self::WIND_PROXY); return $this->createInstance($proxy, array($instance)); } From 78d8891aa1634b06b8de63db458dedbe18a6bc09 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 1 Aug 2011 03:20:34 +0000 Subject: [PATCH 0222/1065] =?UTF-8?q?Wind.php=20realpath=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AF=B9=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=90=8E=E7=BC=80=E7=9A=84=E5=A4=84=E7=90=86=20?= =?UTF-8?q?=E6=94=B9=E8=BF=9BWindFileCache=E7=AD=96=E7=95=A5=EF=BC=8C=20?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E6=AC=A1=E6=96=87=E4=BB=B6=E5=88=A4?= =?UTF-8?q?=E6=96=AD=EF=BC=8C=E5=B0=86=E5=AF=B9=E8=BF=87=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=88=A4=E6=96=AD=E7=AD=96=E7=95=A5=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=88=B0=20hasChange()=20=E6=96=B9=E6=B3=95=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=96=87=E4=BB=B6=E5=A4=B9=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E7=9A=84=E7=AD=96=E7=95=A5=E6=94=B9=E8=BF=9B=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E8=AF=A5=E7=AD=96=E7=95=A5=EF=BC=88=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=95=88=E7=8E=87=E7=BC=BA=E9=99=B7=EF=BC=8C=E4=B8=8D=E5=A4=AA?= =?UTF-8?q?=E5=AE=9E=E7=94=A8=EF=BC=89=20=E5=A2=9E=E5=8A=A0cache=E5=B1=82?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=20dbCache=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E8=BF=9B=E8=A1=8C=E5=88=B0=E4=B8=80=E5=8D=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2282 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 45 ++++++++++----------------- wind/core/web/WindFrontController.php | 35 +++++++++++---------- 2 files changed, 34 insertions(+), 46 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 002d1a7c..a5f1596d 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -40,7 +40,7 @@ public static function run($appName = 'default', $config = '', $rootPath = '') { self::beforRun($appName, $config, $rootPath); if (!isset(self::$_app[$appName])) { Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); - self::$_app[$appName] = new WindFrontController($appName, $config); + self::$_app[$appName] = new WindFrontController($config); } self::getApp()->run(); self::afterRun($appName, $config, $rootPath); @@ -61,8 +61,7 @@ public static function runWithCompile($appName = 'default', $config = '') { * @return string */ public static function getAppName() { - if (empty(self::$_currentApp)) - throw new WindException('Get appName failed. current app is not exists.', WindException::ERROR_SYSTEM_ERROR); + if (empty(self::$_currentApp)) throw new WindException('Get appName failed.', WindException::ERROR_SYSTEM_ERROR); return end(self::$_currentApp); } @@ -98,10 +97,8 @@ public static function getApp() { * @return string|null */ public static function import($filePath, $recursivePackage = false) { - if (!$filePath) - return; - if (isset(self::$_imports[$filePath])) - return self::$_imports[$filePath]; + if (!$filePath) return; + if (isset(self::$_imports[$filePath])) return self::$_imports[$filePath]; if (($pos = strrpos($filePath, '.')) !== false) $fileName = substr($filePath, $pos + 1); elseif (($pos1 = strrpos($filePath, ':')) !== false) @@ -112,8 +109,7 @@ public static function import($filePath, $recursivePackage = false) { if ($isPackage) { $filePath = substr($filePath, 0, $pos); $dirPath = self::getRealDir($filePath); - if (!$dh = opendir($dirPath)) - throw new Exception('the file ' . $dirPath . ' open failed!'); + if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); while (($file = readdir($dh)) !== false) { if (is_dir($dirPath . D_S . $file)) { if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { @@ -147,18 +143,15 @@ public static function import($filePath, $recursivePackage = false) { * @return */ public static function register($path, $alias = '', $includePath = false, $reset = false) { - if (!$path) - return; + if (!$path) return; $alias = strtolower($alias); if (!empty($alias)) { - if (!isset(self::$_namespace[$alias]) || $reset) - self::$_namespace[$alias] = $path; + if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = $path; } if ($includePath) { if (empty(self::$_includePaths)) { self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); - if (($pos = array_search('.', self::$_includePaths, true)) !== false) - unset(self::$_includePaths[$pos]); + if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset(self::$_includePaths[$pos]); } array_unshift(self::$_includePaths, $path); if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { @@ -174,8 +167,7 @@ public static function register($path, $alias = '', $includePath = false, $reset * @return null */ public static function autoLoad($className, $path = '') { - if (isset(self::$_classes[$className])) - $path = self::$_classes[$className]; + if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; if ($path === '') { throw new Exception('auto load ' . $className . ' failed.'); } @@ -248,8 +240,7 @@ public static function getRealDir($dirPath) { * 初始化框架 */ public static function init() { - if (IS_DEBUG) - self::_checkEnvironment(); + if (IS_DEBUG) self::_checkEnvironment(); self::_setDefaultSystemNamespace(); self::_registerAutoloader(); self::_loadBaseLib(); @@ -322,8 +313,8 @@ protected static function resetApp() { * @return */ protected static function beforRun($appName, $config, $rootPath) { - if (in_array($appName, self::$_currentApp)) - throw new WindException('Nested request', WindException::ERROR_SYSTEM_ERROR); + if (!$appName || in_array($appName, self::$_currentApp)) throw new WindException('Nested request', + WindException::ERROR_SYSTEM_ERROR); array_push(self::$_currentApp, $appName); } @@ -332,8 +323,7 @@ protected static function beforRun($appName, $config, $rootPath) { */ protected static function afterRun($appName, $config, $rootPath) { self::resetApp(); - if (self::$_logger) - self::$_logger->flush(); + if (self::$_logger) self::$_logger->flush(); } /** @@ -354,8 +344,7 @@ private static function _checkEnvironment() { throw new Exception('[wind._checkEnvironment] php version is lower, php ' . PHPVERSION . ' or later.', E_WARNING); } - if (!defined('COMPILE_PATH')) - throw new Exception('compile path undefined.'); + if (!defined('COMPILE_PATH')) throw new Exception('compile path undefined.'); function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); } @@ -371,8 +360,7 @@ private static function _setImport($className, $classPath) { self::$_classes[$className] = $_classPath; } else $_classPath = self::$_classes[$className]; - if (!self::$_isAutoLoad) - self::autoLoad($className, $_classPath); + if (!self::$_isAutoLoad) self::autoLoad($className, $_classPath); } /** @@ -380,8 +368,7 @@ private static function _setImport($className, $classPath) { * @return */ private static function _registerAutoloader() { - if (!self::$_isAutoLoad) - return; + if (!self::$_isAutoLoad) return; if (function_exists('spl_autoload_register')) spl_autoload_register('Wind::autoLoad'); else diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 77685543..1ccc50e4 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -31,22 +31,15 @@ class WindFrontController implements IWindFrontController { * @var WindFactory */ protected $windFactory = null; + + private $config; /** * @param WindConfig $windConfig * @param WindFactory $windFactory */ - public function __construct($appName, $config = '') { - try { - $this->request = new WindHttpRequest(); - $this->response = $this->request->getResponse(); - $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); - $this->windFactory = new WindFactory(@include ($configPath)); - $this->windSystemConfig = new WindSystemConfig($config, $appName, $this->windFactory); - } catch (Exception $e) { - Wind::log('System failed to initialize. (' . $e->getMessage() . ')', WindLogger::LEVEL_INFO, 'wind.core'); - throw new WindException('System failed to initialize.' . $e->getMessage()); - } + public function __construct($config = '') { + $this->config = $config; } /** @@ -77,10 +70,8 @@ public function run() { * @return WindFilterChain */ protected function getFilterChain() { - if (!($filters = $this->windSystemConfig->getFilters())) - return null; - if (!($filterChainPath = $this->windSystemConfig->getFilterClass())) - return null; + if (!($filters = $this->windSystemConfig->getFilters())) return null; + if (!($filterChainPath = $this->windSystemConfig->getFilterClass())) return null; return $this->getWindFactory()->createInstance($filterChainPath, array($filters)); } @@ -88,8 +79,18 @@ protected function getFilterChain() { * 预处理Process方法 */ protected function beforeProcess() { - set_error_handler(array(new WindErrorHandler(), 'errorHandle')); - set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); + try { + $this->request = new WindHttpRequest(); + $this->response = $this->request->getResponse(); + $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); + $this->windFactory = new WindFactory(@include ($configPath)); + $this->windSystemConfig = new WindSystemConfig($this->config, Wind::getAppName(), $this->windFactory); + set_error_handler(array(new WindErrorHandler(), 'errorHandle')); + set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); + } catch (Exception $e) { + Wind::log('System failed to initialize. (' . $e->getMessage() . ')', WindLogger::LEVEL_INFO, 'wind.core'); + throw new WindException('System failed to initialize.' . $e->getMessage()); + } } /** From 418d62d2a4810d25854811d5757c9c29d990b167 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 1 Aug 2011 07:19:08 +0000 Subject: [PATCH 0223/1065] =?UTF-8?q?Wind.php=20realpath=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=EF=BC=8C=E6=94=AF=E6=8C=81=E5=AF=B9=20?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=90=8E=E7=BC=80=E7=9A=84=E5=A4=84=E7=90=86=20?= =?UTF-8?q?=E6=94=B9=E8=BF=9BWindFileCache=E7=AD=96=E7=95=A5=EF=BC=8C=20?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E6=AC=A1=E6=96=87=E4=BB=B6=E5=88=A4?= =?UTF-8?q?=E6=96=AD=EF=BC=8C=E5=B0=86=E5=AF=B9=E8=BF=87=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=88=A4=E6=96=AD=E7=AD=96=E7=95=A5=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=88=B0=20hasChange()=20=E6=96=B9=E6=B3=95=E4=B8=AD=EF=BC=8C?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=96=87=E4=BB=B6=E5=A4=B9=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E7=9A=84=E7=AD=96=E7=95=A5=E6=94=B9=E8=BF=9B=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E8=AF=A5=E7=AD=96=E7=95=A5=EF=BC=88=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=95=88=E7=8E=87=E7=BC=BA=E9=99=B7=EF=BC=8C=E4=B8=8D=E5=A4=AA?= =?UTF-8?q?=E5=AE=9E=E7=94=A8=EF=BC=89=20=E5=A2=9E=E5=8A=A0cache=E5=B1=82?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86=20dbCache=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E8=BF=9B=E8=A1=8C=E5=88=B0=E4=B8=80=E5=8D=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2283 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindResultSet.php | 32 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index b8512243..c31c5485 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -34,10 +34,8 @@ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { $this->_columns = $sqlStatement->getColumns(); } else $this->_statement = $sqlStatement; - if ($fetchMode != 0) - $this->_fetchMode = $fetchMode; - if ($fetchMode != 0) - $this->_fetchType = $fetchType; + if ($fetchMode != 0) $this->_fetchMode = $fetchMode; + if ($fetchMode != 0) $this->_fetchType = $fetchType; } /** @@ -79,10 +77,8 @@ public function columnCount() { * @return array */ public function fetch($fetchMode = 0, $fetchType = 0) { - if ($fetchMode === 0) - $fetchMode = $this->_fetchMode; - if ($fetchType === 0) - $fetchMode = $this->_fetchType; + if ($fetchMode === 0) $fetchMode = $this->_fetchMode; + if ($fetchType === 0) $fetchMode = $this->_fetchType; return $this->_fetch($fetchMode, $fetchType); } @@ -91,12 +87,10 @@ public function fetch($fetchMode = 0, $fetchType = 0) { * @see WindResult::fetch() */ private function _fetch($fetchMode, $fetchType) { - if (!empty($this->_columns)) - $fetchMode = PDO::FETCH_BOUND; + if (!empty($this->_columns)) $fetchMode = PDO::FETCH_BOUND; $result = array(); if ($row = $this->_statement->fetch($fetchMode, $fetchType)) { - if (empty($this->_columns)) - return $row; + if (empty($this->_columns)) return $row; foreach ($this->_columns as $key => $value) { $result[$key] = $value; } @@ -113,12 +107,16 @@ private function _fetch($fetchMode, $fetchType) { * @return array */ public function fetchAll($index = '', $fetchMode = 0) { - if ($fetchMode === 0) - $fetchMode = $this->_fetchMode; + if ($fetchMode === 0) $fetchMode = $this->_fetchMode; $result = array(); - while ($row = $this->fetch($fetchMode)) { - $result[] = $index ? (isset($row[$index]) ? $row[$index] : '') : $row; - } + if (!$index) + while ($row = $this->fetch($fetchMode)) + $result[] = $row; + else + while ($row = $this->fetch($fetchMode)) { + if (!isset($row[$index])) continue; + $result[$row[$index]] = $row; + } return $result; } From ab093eefd725250e88a1b8e60f42b1772c30e6d2 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 1 Aug 2011 09:04:39 +0000 Subject: [PATCH 0224/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2284 18ba2127-5a84-46d4-baec-3457e417f034 --- .../component/cache/strategy/WindApcCache.php | 2 +- .../cache/strategy/WindEacceleratorCache.php | 2 +- .../component/cache/strategy/WindMemCache.php | 12 ++--- .../component/cache/strategy/WindWinCache.php | 2 +- wind/component/cache/strategy/WindXCache.php | 46 +++++++++++++++++-- .../cache/strategy/WindZendCache.php | 2 +- 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/wind/component/cache/strategy/WindApcCache.php b/wind/component/cache/strategy/WindApcCache.php index c6708ee0..cbcc786e 100644 --- a/wind/component/cache/strategy/WindApcCache.php +++ b/wind/component/cache/strategy/WindApcCache.php @@ -11,7 +11,7 @@ class WindApcCache extends AbstractWindCache { public function __construct(){ if (!extension_loaded('apc')) { - throw new WindException('The apc extension must be loaded !'); + throw new WindCacheException('The apc extension must be loaded !'); } } diff --git a/wind/component/cache/strategy/WindEacceleratorCache.php b/wind/component/cache/strategy/WindEacceleratorCache.php index fd9ccf95..35a466a2 100644 --- a/wind/component/cache/strategy/WindEacceleratorCache.php +++ b/wind/component/cache/strategy/WindEacceleratorCache.php @@ -13,7 +13,7 @@ class WindEacceleratorCache extends AbstractWindCache { public function __construct() { if (!function_exists('eaccelerator_get')) { - throw new WindException('The eaccelerator extension must be loaded !'); + throw new WindCacheException('The eaccelerator extension must be loaded !'); } } diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php index 9a21279f..274912a0 100644 --- a/wind/component/cache/strategy/WindMemCache.php +++ b/wind/component/cache/strategy/WindMemCache.php @@ -22,7 +22,7 @@ class WindMemCache extends AbstractWindCache { public function __construct() { if (!extension_loaded('Memcache')) { - throw new WindException('WindMemCache requires PHP `Memcache` extension to be loaded !'); + throw new WindCacheException('WindMemCache requires PHP `Memcache` extension to be loaded !'); } $this->memcache = new Memcache(); } @@ -80,12 +80,12 @@ public function setConfig($config) { * 'port'=>11212 * 'pconn'=>false * ) - * @throws WindException + * @throws WindCacheException */ private function setServers($servers) { foreach ($servers as $server) { if (!is_array($server)) { - throw new WindException('The memcache config is incorrect'); + throw new WindCacheException('The memcache config is incorrect'); } $this->setServer($server); } @@ -94,14 +94,14 @@ private function setServers($servers) { /** * 设置配置信息 * - * @throws WindException + * @throws WindCacheException */ private function setServer($server) { if (!isset($server['host'])) { - throw new WindException('The memcache server ip address is not exist'); + throw new WindCacheException('The memcache server ip address is not exist'); } if (!isset($server['port'])) { - throw new WindException('The memcache server port is not exist'); + throw new WindCacheException('The memcache server port is not exist'); } $defaultServer = array('host' => '', 'port' => '', 'pconn' => true, 'weight' => 1, 'timeout' => 15, 'retry' => 15, 'status' => true, 'fcallback' => null); diff --git a/wind/component/cache/strategy/WindWinCache.php b/wind/component/cache/strategy/WindWinCache.php index 0fb71a3e..a249b54c 100644 --- a/wind/component/cache/strategy/WindWinCache.php +++ b/wind/component/cache/strategy/WindWinCache.php @@ -11,7 +11,7 @@ class WindWinCache extends AbstractWindCache { public function __construct() { if (!function_exists('wincache_ucache_get')) { - throw new WindException('The wincache extension must be loaded !'); + throw new WindCacheException('The wincache extension must be loaded !'); } } diff --git a/wind/component/cache/strategy/WindXCache.php b/wind/component/cache/strategy/WindXCache.php index 4da86c85..d01396bf 100644 --- a/wind/component/cache/strategy/WindXCache.php +++ b/wind/component/cache/strategy/WindXCache.php @@ -7,10 +7,12 @@ * @version 2011-7-26 xiaoxiao */ class WindXCache extends AbstractWindCache { + private $authUser = ''; + private $authPwd = ''; public function __construct() { - if (!function_exists('xcache_get')) { - throw new WindException('The xcache extension must be loaded !'); + if (!extension_loaded('xcache')) { + throw new WindCacheException('The xcache extension must be loaded !'); } } @@ -39,11 +41,49 @@ protected function deleteValue($key) { * @see AbstractWindCache#clear() */ public function clear() { - $max = xcache_count(XC_TYPE_VAR); + //xcache_clear_cache需要验证权限 + $this->checkAuthor(); + + //如果配置中xcache.var_count > 0 则不能用xcache_clear_cache(XC_TYPE_VAR, 0)的方式删除 + $max = xcache_count(XC_TYPE_VAR); for ($i = 0; $i < $max; $i++) { xcache_clear_cache(XC_TYPE_VAR, $i); } + + //恢复之前的权限 + $this->checkAuthor(true); + return true; } + + /** + * 设置验证权限 + * @param boolean $recover 是否恢复设置 + */ + private function checkAuthor($recover = false) { + static $tmp = array(); + if (!$recover) { + $tmp['user'] = isset($_SERVER['PHP_AUTH_USER']) ? null : $_SERVER['PHP_AUTH_USER']; + $tmp['pwd'] = isset($_SERVER['PHP_AUTH_PW']) ? null : $_SERVER['PHP_AUTH_PW']; + $_SERVER['PHP_AUTH_USER'] = $this->authUser; + $_SERVER['PHP_AUTH_PW'] = $this->authPwd; + return true; + } + $_SERVER['PHP_AUTH_USER'] = $tmp['user']; + $_SERVER['PHP_AUTH_PW'] = $tmp['pwd']; + unset($tmp); + return true; + } + + /* + * (non-PHPdoc) + * @see AbstractWindCache::setConfig() + */ + public function setConfig($config = array()) { + if (!$config) return false; + parent::setConfig($config); + $this->authUser = $this->getConfig('user'); + $this->authPwd = $this->getConfig('pwd'); + } } \ No newline at end of file diff --git a/wind/component/cache/strategy/WindZendCache.php b/wind/component/cache/strategy/WindZendCache.php index cb875cb7..dd36c252 100644 --- a/wind/component/cache/strategy/WindZendCache.php +++ b/wind/component/cache/strategy/WindZendCache.php @@ -10,7 +10,7 @@ class WindZendCache extends AbstractWindCache { public function __construct() { if (!function_exists('zend_shm_cache_fetch')) { - throw new WindException('The zend cache extension must be loaded !'); + throw new WindCacheException('The zend cache extension must be loaded !'); } } From 3ba75cef4b2ef3da84f61e46559ffee6de01241e Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 1 Aug 2011 09:27:34 +0000 Subject: [PATCH 0225/1065] =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2285 18ba2127-5a84-46d4-baec-3457e417f034 --- .../http/request/WindHttpRequest.php | 133 ++++++++---------- .../http/response/WindHttpResponse.php | 62 +++----- wind/component/utility/WindHtmlHelper.php | 42 ++++++ wind/component/viewer/WindView.php | 52 ++++--- .../compiler/WindTemplateCompilerEcho.php | 20 ++- wind/core/web/WindErrorHandler.php | 104 -------------- wind/core/web/WindFrontController.php | 67 ++++++++- wind/core/web/WindSystemConfig.php | 16 ++- 8 files changed, 230 insertions(+), 266 deletions(-) create mode 100644 wind/component/utility/WindHtmlHelper.php diff --git a/wind/component/http/request/WindHttpRequest.php b/wind/component/http/request/WindHttpRequest.php index cbc18c41..38bfcb61 100644 --- a/wind/component/http/request/WindHttpRequest.php +++ b/wind/component/http/request/WindHttpRequest.php @@ -497,23 +497,6 @@ public function getAcceptLanguage() { return $this->_language; } - /** - * 获得返回信息 - * @return WindHttpResponse - */ - public function getResponse() { - if ($this->_response === null) { - $this->_response = new WindHttpResponse(); - if ($this->getIsAjaxRequest()) { - $this->_response->addHeader('Content-type', 'text/xml;charset=utf-8'); - $this->_response->setIsAjax(true); - } else{ - $this->_response->addHeader('Content-type', 'text/html;charset=utf-8'); - } - } - return $this->_response; - } - /** * 返回访问的IP地址 * @@ -529,10 +512,8 @@ private function _getClientIp() { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); - if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || - (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || - (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { - $this->_clientIp = long2ip($ip); + if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { + $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); @@ -587,61 +568,59 @@ private function _initScriptUrl() { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; - } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && - basename($_scriptName) === $scriptName) { - $this->_scriptUrl = $_scriptName; - } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { - $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; - } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && - ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && - strpos($_scriptName, $_documentRoot) === 0) { - $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); - } else - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); - } + } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { + $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; + } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( + 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { + $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } - /** - * 获得主机信息,包含协议信息,主机名,访问端口信息 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_hostInfo = http://www.phpwind.net/ - * $this->_hostInfo = http://www.phpwind.net:80/ - * $this->_hostInfo = https://www.phpwind.net:443/ - * - * @throws WindException - * @return - */ - private function _initHostInfo() { - $http = $this->isSecure() ? 'https' : 'http'; - if (($httpHost = $this->getServer('HTTP_HOST')) != null) - $this->_hostInfo = $http . '://' . $httpHost; - elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { - $this->_hostInfo = $http . '://' . $httpHost; - if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; - } else - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); - } + /** + * 获得主机信息,包含协议信息,主机名,访问端口信息 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_hostInfo = http://www.phpwind.net/ + * $this->_hostInfo = http://www.phpwind.net:80/ + * $this->_hostInfo = https://www.phpwind.net:443/ + * + * @throws WindException + * @return + */ + private function _initHostInfo() { + $http = $this->isSecure() ? 'https' : 'http'; + if (($httpHost = $this->getServer('HTTP_HOST')) != null) + $this->_hostInfo = $http . '://' . $httpHost; + elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { + $this->_hostInfo = $http . '://' . $httpHost; + if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } - /** - * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 - * - * @throws WindException - * @return - */ - private function _initPathInfo() { - $requestUri = urldecode($this->getRequestUri()); - $scriptUrl = $this->getScriptUrl(); - $baseUrl = $this->getBaseUrl(); - if (strpos($requestUri, $scriptUrl) === 0) - $pathInfo = substr($requestUri, strlen($scriptUrl)); - elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) - $pathInfo = substr($requestUri, strlen($baseUrl)); - elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) - $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); - else - throw new WindException(''); - if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); - $this->_pathInfo = trim($pathInfo, '/'); - } - } \ No newline at end of file + /** + * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 + * + * @throws WindException + * @return + */ + private function _initPathInfo() { + $requestUri = urldecode($this->getRequestUri()); + $scriptUrl = $this->getScriptUrl(); + $baseUrl = $this->getBaseUrl(); + if (strpos($requestUri, $scriptUrl) === 0) + $pathInfo = substr($requestUri, strlen($scriptUrl)); + elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) + $pathInfo = substr($requestUri, strlen($baseUrl)); + elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) + $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); + else + throw new WindException(''); + if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); + $this->_pathInfo = trim($pathInfo, '/'); + } +} \ No newline at end of file diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index 8dbc3c5e..35ccef65 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -23,8 +23,6 @@ class WindHttpResponse implements IWindResponse { private $_status = ''; - private $_isAjax = false; - private $_data = array(); /* @@ -302,12 +300,10 @@ class WindHttpResponse implements IWindResponse { * @param string $value 响应头的字段取值 */ public function setHeader($name, $value, $replace = false) { - if (!$name || !$value) - return; + if (!$name || !$value) return; $name = $this->_normalizeHeader($name); foreach ($this->_headers as $key => $one) { - ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, - 'replace' => $replace); + ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); } } @@ -318,8 +314,7 @@ public function setHeader($name, $value, $replace = false) { * @param string $value 响应头的字段取值 */ public function addHeader($name, $value, $replace = false) { - if ($name == '' || $value == '') - return; + if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } @@ -331,8 +326,7 @@ public function addHeader($name, $value, $replace = false) { * @param string $message */ public function setStatus($status, $message = '') { - if (!is_int($status) || $status < 100 || $status > 505) - return; + if (!is_int($status) || $status < 100 || $status > 505) return; $this->_status = (int) $status; } @@ -344,10 +338,9 @@ public function setStatus($status, $message = '') { * @param string $name */ public function setBody($content, $name = null) { - if (!$content) - return; + if (!$content) return; !$name && $name = 'default'; - array_unshift($this->_bodyIndex, $name); + array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } @@ -367,9 +360,8 @@ public function addCookie(Cookie $cookie) { * @param string $message */ public function sendError($status = self::SC_NOT_FOUND, $message = '') { - if (!is_int($status) || $status < 400 || $status > 505) - return; - $this->setBody($message); + if (!is_int($status) || $status < 400 || $status > 505) return; + $this->setBody($message, 'error'); $this->setStatus($status); } @@ -379,8 +371,7 @@ public function sendError($status = self::SC_NOT_FOUND, $message = '') { * @param string $location */ public function sendRedirect($location, $status = 302) { - if (!is_int($status) || $status < 300 || $status > 399) - return; + if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); @@ -401,8 +392,7 @@ public function sendResponse() { * 发送响应头部信息 */ public function sendHeaders() { - if ($this->isSendedHeader()) - return; + if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } @@ -443,8 +433,8 @@ public function getBody($name = false) { */ public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); - if ($throw && $sended) - throw new WindException(__CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); + if ($throw && $sended) throw new WindException( + __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } @@ -485,28 +475,12 @@ private function _normalizeHeader($name) { return $filtered; } - /** - * @return the $_isAjax - */ - public function getIsAjax() { - return $this->_isAjax; - } - - /** - * @param field_type $_isAjax - */ - public function setIsAjax($_isAjax) { - $this->_isAjax = $_isAjax; - } - /** * @return array */ - public function getData($key1 = '', $key2 = '') { - if (!$key1) - return $this->_data; - if (!$key2) - return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; + public function getData($key1 = '', $key2 = '', $encode = false) { + if (!$key1) return $this->_data; + if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } @@ -518,10 +492,8 @@ public function setData($data, $key = '') { $this->_data[$key] = $data; return; } - if (is_object($data)) - $data = get_object_vars($data); - if (is_array($data)) - $this->_data += $data; + if (is_object($data)) $data = get_object_vars($data); + if (is_array($data)) $this->_data += $data; } } \ No newline at end of file diff --git a/wind/component/utility/WindHtmlHelper.php b/wind/component/utility/WindHtmlHelper.php new file mode 100644 index 00000000..582c2299 --- /dev/null +++ b/wind/component/utility/WindHtmlHelper.php @@ -0,0 +1,42 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHtmlHelper { + + /** + * Convert special characters to HTML entities + * + * @param string $text | + * @return string | string The converted string + */ + public static function encode($text) { + return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getWindSystemConfig()->getCharset()); + } + + /** + * Convert special characters to HTML entities + * + * @param array $data + * @return array + */ + public static function encodeArray($data) { + $_tmp = array(); + foreach ($data as $key => $value) { + if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, + Wind::getApp()->getWindSystemConfig()->getCharset()); + if (is_string($value)) + $value = htmlspecialchars($value, ENT_QUOTES, Wind::getApp()->getWindSystemConfig()->getCharset()); + elseif (is_array($value)) + $value = self::encodeArray($value); + $_tmp[$key] = $value; + } + return $_tmp; + } + +} + +?> \ No newline at end of file diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index a2278dd9..d0935d9c 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -17,11 +17,6 @@ * @package */ class WindView extends WindModule { - /* 视图配置信息 */ - const TEMPLATE_DIR = 'template-dir'; - const TEMPLATE_EXT = 'template-ext'; - const COMPILE_DIR = 'compile-dir'; - const IS_CACHE = 'is-cache'; /** * 模板路径信息 * @@ -46,6 +41,13 @@ class WindView extends WindModule { * @var boolean */ protected $isCache = false; + + /** + * 是否对模板变量进行html字符过滤 + * + * @var boolean + */ + protected $htmlspecialchars = false; /** * 编译目录 * @@ -79,12 +81,9 @@ public function render($forward, $router, $display = false) { return; } $this->setTemplateName($_templateName); - if ($_ext = $forward->getTemplateExt()) - $this->setTemplateExt($_ext); - if ($_path = $forward->getTemplatePath()) - $this->setTemplateDir($_path); - if ($_layout = $forward->getLayout()) - $this->setLayout($_layout); + if ($_ext = $forward->getTemplateExt()) $this->setTemplateExt($_ext); + if ($_path = $forward->getTemplatePath()) $this->setTemplateDir($_path); + if ($_layout = $forward->getLayout()) $this->setLayout($_layout); $viewResolver = $this->getViewResolver(); $viewResolver->windAssign($forward->getVars(), $_templateName); @@ -124,12 +123,9 @@ public function getCompileFile($template = '', $ext = '') { * @param $path */ private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) { - if (!$fileName) - $fileName = $this->getTemplateName(); - if (!$fileExt) - $fileExt = $this->getTemplateExt(); - if (strrpos($path, ':') === false) - $path = Wind::getAppName() . ':' . $path; + if (!$fileName) $fileName = $this->getTemplateName(); + if (!$fileExt) $fileExt = $this->getTemplateExt(); + if (strrpos($path, ':') === false) $path = Wind::getAppName() . ':' . $path; if ($ifCheckPath) { $dir = Wind::getRealDir($path); if (!is_dir($dir)) { @@ -147,10 +143,10 @@ private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) * @return */ public function init() { - $this->setTemplateDir($this->getConfig(self::TEMPLATE_DIR)); - $this->setCompileDir($this->getConfig(self::COMPILE_DIR)); - $this->setTemplateExt($this->getConfig(self::TEMPLATE_EXT)); - $this->setIsCache($this->getConfig(self::IS_CACHE)); + $this->setTemplateDir($this->getConfig('template-dir')); + $this->setCompileDir($this->getConfig('compile-dir')); + $this->setTemplateExt($this->getConfig('template-ext')); + $this->setIsCache($this->getConfig('is-cache')); } /** @@ -237,6 +233,20 @@ public function setLayout($layout) { $this->layout = $layout; } + /** + * @return the $htmlspecialchars + */ + public function getHtmlspecialchars() { + return $this->htmlspecialchars; + } + + /** + * @param boolean $htmlspecialchars + */ + public function setHtmlspecialchars($htmlspecialchars) { + $this->htmlspecialchars = $htmlspecialchars; + } + /** * @return WindViewerResolver */ diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index 902fb8a8..af095ccd 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -1,8 +1,11 @@ a|false} + * {@templateName:var} * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu @@ -18,7 +21,10 @@ public function compile($key, $content) { $_output = $content; $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $_output); $_output = $this->compileVarShare($_output); - return ''; + if ($this->windViewerResolver->getWindView()->getHtmlspecialchars() === true) + return ''; + else + return ''; } /** @@ -26,11 +32,11 @@ public function compile($key, $content) { * @return string */ private function compileVarShare($input) { - $input = trim($input); - if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) return $input; - list($templateName, $var) = explode(':', $input); - $input = '$this->getResponse()->getData(\'' . $templateName . '\', \'' . $var .'\')'; - return $input; + $input = trim($input); + if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) return $input; + list($templateName, $var) = explode(':', $input); + $input = '$this->getResponse()->getData(\'' . $templateName . '\', \'' . $var . '\')'; + return $input; } } diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php index 964f1761..5682083b 100644 --- a/wind/core/web/WindErrorHandler.php +++ b/wind/core/web/WindErrorHandler.php @@ -33,108 +33,4 @@ public function run() { $this->setTemplatePath('COM:viewer.errorPage'); } - /** - * @param string $errno - * @param string $errstr - * @param string $errfile - * @param string $errline - */ - final public function errorHandle($errno, $errstr, $errfile, $errline) { - if ($errno & error_reporting()) { - $header = $message = $trace = ''; - $header = $errstr; - if (IS_DEBUG) { - $message = $errstr . '(' . $errfile . ' : ' . $errline . ')'; - $_trace = debug_backtrace(); - foreach ($_trace as $key => $value) { - if (!isset($value['file']) || !isset($value['line']) || !isset($value['function'])) - continue; - $trace .= "#$key {$value['file']}({$value['line']}): "; - if (isset($value['object']) && is_object($value['object'])) - $trace .= get_class($value['object']) . '->'; - $trace .= "{$value['function']}()\r\n"; - } - } - $this->buildMessage($header, $message, $trace); - } - } - - /** - * 异常处理句柄 - * @param Exception $exception - */ - final public function exceptionHandle($exception) { - $header = $message = $trace = ''; - $header = $exception->getMessage(); - if (IS_DEBUG) { - $message = $exception->getMessage() . '(' . $exception->getFile() . ' : ' . $exception->getLine() . ')'; - $trace = $exception->getTraceAsString(); - } - $this->buildMessage($header, $message, $trace); - } - - /** - * @param string $header - * @param string $message - * @param string $trace - */ - public function buildMessage($header, $message = '', $trace = '') { - $_tmp = "

$header

"; - $_tmp .= "

$message

"; - $_tmp .= "
$trace
"; - $this->getResponse()->sendError(500, $_tmp); - } - - /** - * @param $string $errno - */ - private function errnoMap($errno) { - $_tmp = ''; - switch ($errno) { - case E_ERROR: - $_tmp = "Error"; - break; - case E_WARNING: - $_tmp = "Warning"; - break; - case E_PARSE: - $_tmp = "Parse Error"; - break; - case E_NOTICE: - $_tmp = "Notice"; - break; - case E_CORE_ERROR: - $_tmp = "Core Error"; - break; - case E_CORE_WARNING: - $_tmp = "Core Warning"; - break; - case E_COMPILE_ERROR: - $_tmp = "Compile Error"; - break; - case E_COMPILE_WARNING: - $_tmp = "Compile Warning"; - break; - case E_USER_ERROR: - $_tmp = "User Error"; - break; - case E_USER_WARNING: - $_tmp = "User Warning"; - break; - case E_USER_NOTICE: - $_tmp = "User Notice"; - break; - case E_STRICT: - $_tmp = "Strict Notice"; - break; - case E_RECOVERABLE_ERROR: - $_tmp = "Recoverable Error"; - break; - default: - $_tmp = "Unknown error ($errno)"; - break; - } - return $_tmp; - } - } \ No newline at end of file diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 1ccc50e4..7a6c9421 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -39,6 +39,8 @@ class WindFrontController implements IWindFrontController { * @param WindFactory $windFactory */ public function __construct($config = '') { + $this->request = new WindHttpRequest(); + $this->response = new WindHttpResponse(); $this->config = $config; } @@ -80,26 +82,79 @@ protected function getFilterChain() { */ protected function beforeProcess() { try { - $this->request = new WindHttpRequest(); - $this->response = $this->request->getResponse(); + ob_start(); $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); $this->windFactory = new WindFactory(@include ($configPath)); $this->windSystemConfig = new WindSystemConfig($this->config, Wind::getAppName(), $this->windFactory); - set_error_handler(array(new WindErrorHandler(), 'errorHandle')); - set_exception_handler(array(new WindErrorHandler(), 'exceptionHandle')); + set_error_handler(array($this, 'errorHandle')); + set_exception_handler(array($this, 'exceptionHandle')); } catch (Exception $e) { Wind::log('System failed to initialize. (' . $e->getMessage() . ')', WindLogger::LEVEL_INFO, 'wind.core'); throw new WindException('System failed to initialize.' . $e->getMessage()); } } + /** + * 错误处理句柄 + * @param string $errno + * @param string $errstr + * @param string $errfile + * @param string $errline + */ + final public function errorHandle($errno, $errstr, $errfile, $errline) { + if ($errno & error_reporting()) { + restore_error_handler(); + restore_exception_handler(); + $header = $message = $trace = ''; + $header = $errstr; + if (IS_DEBUG) { + $message = $errstr . '(' . $errfile . ' : ' . $errline . ')'; + $_trace = debug_backtrace(); + foreach ($_trace as $key => $value) { + if (!isset($value['file']) || !isset($value['line']) || !isset($value['function'])) continue; + $trace .= "#$key {$value['file']}({$value['line']}): "; + if (isset($value['object']) && is_object($value['object'])) $trace .= get_class($value['object']) . '->'; + $trace .= "{$value['function']}()\r\n"; + } + } + $this->displayMessage($header, $message, $trace); + } + } + + /** + * 异常处理句柄 + * @param Exception $exception + */ + final public function exceptionHandle($exception) { + restore_error_handler(); + restore_exception_handler(); + $header = $message = $trace = ''; + $header = $exception->getMessage(); + if (IS_DEBUG) { + $message = $exception->getMessage() . '(' . $exception->getFile() . ' : ' . $exception->getLine() . ')'; + $trace = $exception->getTraceAsString(); + } + $this->displayMessage($header, $message, $trace); + } + + /** + * @param string $header + * @param string $message + * @param string $trace + */ + public function displayMessage($header, $message = '', $trace = '') { + $_tmp = "

$header

"; + $_tmp .= "

$message

"; + $_tmp .= "
$trace
"; + $this->getResponse()->sendError(500, $_tmp); + } + /** * 后处理Process方法 */ protected function afterProcess() { + ob_end_flush(); $this->response->sendResponse(); - restore_error_handler(); - restore_exception_handler(); } /** diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 25cee0d6..b719c276 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -25,8 +25,7 @@ public function __construct($config, $appName, $factory) { public function setConfig($config, $factory = null) { if (is_string($config)) { $config = $this->parseConfig($config, 'config', '', $factory); - if (isset($config[$this->appName])) - $this->_config = $config[$this->appName]; + if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = (array) $config; } @@ -45,6 +44,13 @@ public function getAppClass() { return $this->getConfig('class', '', COMPONENT_WEBAPP); } + /** + * 返回应用编码信息 + */ + public function getCharset() { + return $this->getConfig('charset', '', 'utf-8'); + } + /** * 返回配置定义中定义的过滤链列表 * 如果定义$name则返回在filters定义标签内对应的属性值 @@ -191,11 +197,9 @@ public function getDbConfig($dbName = '') { * @param factory */ private function parseConfig($config, $key = 'config', $append = true, $factory = null) { - if (!$config) - return array(); + if (!$config) return array(); - if ($factory === null) - $factory = $this->getSystemFactory(); + if ($factory === null) $factory = $this->getSystemFactory(); $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); $append === true && $append = $this->appName . '_config'; $config = $configParser->parse($config, $this->appName . '_' . $key, $append, From 4e873edc537f96dcc9eed861737832b61cac5b0f Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 2 Aug 2011 03:42:38 +0000 Subject: [PATCH 0226/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2286 18ba2127-5a84-46d4-baec-3457e417f034 --- .../WindTemplateCompilerComponent.php | 194 +++++++++--------- 1 file changed, 95 insertions(+), 99 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php index f6182575..27c9cdc3 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php @@ -20,6 +20,8 @@ class WindTemplateCompilerComponent extends AbstractWindTemplateCompiler { protected $appConfig = ''; //组件的配置文件 + protected $appConfigSuffix = 'php';//配置文件的缺省格式 + protected $componentPath = ''; //组件的入口地址 @@ -37,11 +39,11 @@ public function compile($key, $content) { private function getScript($content) { $params = $this->matchConfig($content); if (!isset($params['name']) || !isset($params['componentPath'])) throw new WindException('组件编译错误!'); - $content = "rebuildConfig($params) . (isset($params['args']) ? $this->registerUrlParams($params) : '') . - "\$componentPath = Wind::getRealDir('" . $params['componentPath'] . "');\r\n" . - "Wind::register(\$componentPath, '" . $params['name'] . "');\r\n" . "Wind::run('" . $params['name'] . - "', \$config);\r\n?>"; + $content = "rebuildConfig($params) . + (isset($params['args']) ? $this->registerUrlParams($params) : '') . + "\$componentPath = Wind::getRealDir('" . $params['componentPath'] . "');\r\n" . + "Wind::register(\$componentPath, '" . $params['name'] . "');\r\n" . + "Wind::run('" . $params['name'] . "', \$config);\r\n?>"; return $content; } @@ -51,103 +53,97 @@ private function getScript($content) { * @return array */ private function rebuildConfig($params) { - $temp = "\$configParser = new WindConfigParser();\r\n" . "\$configPath = Wind::getRealPath('" . - $params['appConfig'] . "');\r\n"; - $temp .= "\$config = \$configParser->parse(\$configPath, '" . $params['name'] . "');\r\n"; - if (!isset($params['templateDir'])) return $temp; - if (isset($params['args']['m'])) - $temp .= "\$config['web-apps']['" . $params['name'] . "']['modules']['" . $params['args']['m'] . - "']['view']['config']['template-dir']['value'] = '" . $params['templateDir'] . "';\r\n"; - else { - $temp .= "foreach(\$config['web-apps']['" . $params['name'] . - "']['modules'] as \$key => \$value) {\r\n" . "\t\$config['web-apps']['" . $params['name'] . - "']['modules'][\$key]['view']['config']['template-dir']['value'] = '" . $params['templateDir'] . - "';\r\n" . "}\r\n"; - } - return $temp; - } + $temp = "\$configParser = new WindConfigParser();\r\n" . + "\$configPath = Wind::getRealPath('" . $params['appConfig'] . "', '" . $params['suffix'] . "');\r\n" . + "\$config = \$configParser->parse(\$configPath);\r\n" . + "\$config = \$config['" . $params['name'] . "'];\r\n"; + if (!isset($params['templateDir'])) return $temp; + if (isset($params['args']['m'])) + $temp .= "\$config['modules']['" . $params['args']['m'] . "']['view']['config']['template-dir'] = '" . $params['templateDir'] . "';\r\n"; + else { + $temp .= "foreach(\$config['modules'] as \$key => \$value) {\r\n" . + "\t\$config['modules'][\$key]['view']['config']['template-dir'] = '" . $params['templateDir'] . "';\r\n" . + "}\r\n"; + } + return $temp; + } - /** - * 注册变量信息 - * - * @param array $params - */ - private function registerUrlParams($params) { - $temp = ''; - $temp = "\$mKey = isset(\$config['web-apps']['" . $params['name'] . - "']['router']['config']['module']['url-param']) ? \$config['web-apps']['" . $params['name'] . - "']['router']['config']['module']['url-param'] : 'm';\r\n" . "\$cKey = isset(\$config['web-apps']['" . - $params['name'] . "']['router']['config']['controller']['url-param']) ? \$config['web-apps']['" . - $params['name'] . "']['router']['config']['controller']['url-param'] : 'c';\r\n" . - "\$aKey = isset(\$config['web-apps']['" . $params['name'] . - "']['router']['config']['action']['url-param']) ? \$config['web-apps']['" . $params['name'] . - "']['router']['config']['action']['url-param'] : 'a';\r\n" . "\$_GET[\$mKey] = '" . - $params['args']['m'] . "';\r\n" . "\$_GET[\$cKey] = '" . $params['args']['c'] . "';\r\n" . - "\$_GET[\$aKey] = '" . $params['args']['a'] . "';\r\n"; - unset($params['args']['a'], $params['args']['c'], $params['args']['m']); - foreach ($params['args'] as $key => $value) { - $temp .= is_array($value) ? "\$_GET['" . $key . "'] = " . $value . ";\r\n" : "\$_GET['" . $key . - "'] = '" . $value . "';\r\n"; - } - return $temp; - } + /** + * 注册变量信息 + * + * @param array $params + */ + private function registerUrlParams($params) { + $temp = "\$routerConfig = \$config['router']['config'];\r\n" . + "\$mKey = isset(\$routerConfig['module']['url-param']) ? \$routerConfig['module']['url-param'] : 'm';\r\n" . + "\$cKey = isset(\$routerConfig['controller']['url-param']) ? \$routerConfig['controller']['url-param'] : 'c';\r\n" . + "\$aKey = isset(\$routerConfig['action']['url-param']) ? \$routerConfig['action']['url-param'] : 'a';\r\n" . + "\$_GET[\$mKey] = '" . $params['args']['m'] . "';\r\n" . + "\$_GET[\$cKey] = '" . $params['args']['c'] . "';\r\n" . + "\$_GET[\$aKey] = '" . $params['args']['a'] . "';\r\n"; + unset($params['args']['a'], $params['args']['c'], $params['args']['m']); + foreach ($params['args'] as $key => $value) { + $temp .= "\$_GET['" . $key . "'] = " . (is_array($value) ? $value : "'" . $value . "'" ) . ";\r\n"; + } + return $temp; + } - /** - * 匹配配置信息 - * - * @param string $content - * @return array - */ - private function matchConfig($content) { - preg_match_all('/(\w+=[\'|"]?[\w|.|:]+[\'|"]?)/', $content, $mathcs); - list($config, $key, $val) = array(array(), '', ''); - foreach ($mathcs[0] as $value) { - list($key, $val) = explode('=', $value); - if (!in_array($key, $this->getProperties()) || !$val) continue; - switch ($key) { - case 'args': - $config['args'] = $this->compileArgs(trim($val, '\'"')); - break; - default: - $config[$key] = trim($val, '\'"'); - break; - } - } - return $config; - } + /** + * 匹配配置信息 + * + * @param string $content + * @return array + */ + private function matchConfig($content) { + preg_match_all('/(\w+=[\'|"]?[\w|.|:]+[\'|"]?)/', $content, $mathcs); + list($config, $key, $val) = array(array(), '', ''); + foreach ($mathcs[0] as $value) { + list($key, $val) = explode('=', $value); + if (!in_array($key, $this->getProperties()) || !$val) continue; + switch ($key) { + case 'args': + $config['args'] = $this->compileArgs(trim($val, '\'"')); + break; + default: + $config[$key] = trim($val, '\'"'); + break; + } + } + return $config; + } - /** - * 解析传递给url的参数信息 - * - * @param string $arg - * @return array - */ - private function compileArgs($arg) { - $args = explode(':', $arg); - $urlParams = array(); - list($urlParams['a'], $urlParams['c'], $urlParams['m']) = array('', '', ''); - switch (count($args)) { - case 1: - $urlParams['a'] = $args[0]; - break; - case 2: - list($urlParams['c'], $urlParams['a']) = $args; - break; - case 3: - list($urlParams['m'], $urlParams['c'], $urlParams['a']) = $args; - break; - default: - break; - } - return $urlParams; - } + /** + * 解析传递给url的参数信息 + * + * @param string $arg + * @return array + */ + private function compileArgs($arg) { + $args = explode(':', $arg); + $urlParams = array(); + list($urlParams['a'], $urlParams['c'], $urlParams['m']) = array('', '', ''); + switch (count($args)) { + case 1: + $urlParams['a'] = $args[0]; + break; + case 2: + list($urlParams['c'], $urlParams['a']) = $args; + break; + case 3: + list($urlParams['m'], $urlParams['c'], $urlParams['a']) = $args; + break; + default: + break; + } + return $urlParams; + } - /* (non-PHPdoc) + /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::getProperties() */ - protected function getProperties() { - return array('name', 'templateDir', 'appConfig', 'args', 'componentPath'); - } - } - - ?> \ No newline at end of file + protected function getProperties() { + return array('name', 'templateDir', 'appConfig', 'args', 'componentPath', 'suffix'); + } +} + +?> \ No newline at end of file From 0f71f6e280c2351e9a35c9f1d16af29755999156 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 2 Aug 2011 05:42:50 +0000 Subject: [PATCH 0227/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2287 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/ini/wind_config.ini | 63 +++++++----- docs/configtemplate/php/wind_config.php | 97 ++++++++++--------- .../properties/wind_config.properties | 63 +++++++----- 3 files changed, 127 insertions(+), 96 deletions(-) diff --git a/docs/configtemplate/ini/wind_config.ini b/docs/configtemplate/ini/wind_config.ini index 513531af..67a006df 100644 --- a/docs/configtemplate/ini/wind_config.ini +++ b/docs/configtemplate/ini/wind_config.ini @@ -1,44 +1,57 @@ ;应用配置 -[web-apps] +[default] ;default:为应用的name -default.class=windWebApp -default.root-path= - -;工厂配置 -default.factory.class-definition=components -default.factory.class=WIND:core.factory.WindComponentFactory +class=windWebApp +charset=utf-8 ;过滤链配置 -default.filters.class=WIND:core.filter.WindFilterChain -default.filters.filter1.class=WIND:core.web.filter.WindLoggerFilter -default.filters.filter2.class=WIND:core.web.filter.WindUrlFilter +filters.class=WIND:core.filter.WindFilterChain +filters.filter1.class=WIND:core.web.filter.WindLoggerFilter +filters.filter2.class=WIND:core.web.filter.WindUrlFilter ;配置default应用的路由配置信息, -default.router.class=urlBasedRouter +router.class=urlBasedRouter ;module配置 -default.router.config.module.url-param=m -default.router.config.module.default-value=default +router.config.module.url-param=m +router.config.module.default-value=default ;controller配置 -default.router.config.controller.url-param=c -default.router.config.controller.default-value=index +router.config.controller.url-param=c +router.config.controller.default-value=index ;action配置 -default.router.config.action.url-param=a -default.router.config.action.default-value=run +router.config.action.url-param=a +router.config.action.default-value=run -;配置default应用的模块 ;如下,配置了一个名为default的模块,及该default模块下该有的一些配置项信息 ;default模块的路径信息 -default.modules.default.path=controller +modules.default.controller-path=controller ;default模块的controller后缀信息 -default.modules.default.controller-suffix.value=Controller +modules.default.controller-suffix=Controller ;default模块的error controller类 -default.modules.default.error-handler.class=WIND:core.web.WindErrorHandler +modules.default.error-handler=WIND:core.web.WindErrorHandler ;default模块的视图配置 -default.modules.default.view.class=windView +modules.default.view.class=windView ;模板文件路径 -default.modules.default.view.config.template-dir.value=template +modules.default.view.config.template-dir=template ;模板后缀 -default.modules.default.view.config.template-ext.value=htm +modules.default.view.config.template-ext=htm ;模板编译文件保存路径 -default.modules.default.view.config.compile-dir.value=compile.template \ No newline at end of file +modules.default.view.config.compile-dir=compile.template + +;数据库的配置信息 +;采用外联引入的方式 +;db.resource=db_config.php +;或是直接配置 +db.conn1.class=COM:db.WindConnection +db.conn1.dsn=mysql:host=localhost;dbname=test +db.conn1.user=root +db.conn1.pwd=root +db.conn1.charset=utf-8 +db.conn1.tablePrefix=pw_ +;可以同时配置多组 +db.conn2.class=COM:db.WindConnectionManage +db.conn2.config.c1.dsn=mysql:host=localhost;dbname=test +db.conn2.config.c1.user=root +db.conn2.config.c1.pwd=root +db.conn2.config.c1.charset=utf-8 +db.conn2.config.c1.tablePrefix=pw_ \ No newline at end of file diff --git a/docs/configtemplate/php/wind_config.php b/docs/configtemplate/php/wind_config.php index 07501248..99477c99 100644 --- a/docs/configtemplate/php/wind_config.php +++ b/docs/configtemplate/php/wind_config.php @@ -6,65 +6,70 @@ * @license */ return array( - 'web-apps' => array( /*配置应用项名为default*/ - 'default' => array( - 'class' => 'windWebApp', - 'root-path' => '', - 'factory' => array( - 'class-definition' => 'components', - 'class' => 'WIND:core.factory.WindComponentFactory', - ), - 'filters' => array( - 'class' => 'WIND:core.filter.WindFilterChain', - 'filter1' => array('class' => 'WIND:core.web.filter.WindLoggerFilter'), - 'filter2' => array('class' => 'WIND:core.web.filter.WindUrlFilter'), - ), + 'default' => array( + 'class' => 'windWebApp', + 'filters' => array( + 'class' => 'WIND:core.filter.WindFilterChain', + 'filter1' => array('class' => 'WIND:core.web.filter.WindLoggerFilter'), + 'filter2' => array('class' => 'WIND:core.web.filter.WindUrlFilter'), + ), /*配置default应用的路由规则*/ - 'router' => array( - 'class' => 'urlBasedRouter', - 'config' => array( - /*配置路径中module的规则*/ - 'module' => array( - 'url-param' => 'm', - 'default-value' => 'default', - ), - /*配置路径中controller的规则*/ - 'controller' => array( - 'url-param' => 'c', - 'default-value' => 'index', - ), - /*配置路径中action的规则*/ - 'action' => array( - 'url-param' => 'a', - 'default-value' => 'run', - ), - ), - ), + 'router' => array( + 'class' => 'urlBasedRouter', + 'config' => array( + /*配置路径中module的规则*/ + 'module' => array( + 'url-param' => 'm', + 'default-value' => 'default', + ), + /*配置路径中controller的规则*/ + 'controller' => array( + 'url-param' => 'c', + 'default-value' => 'index', + ), + /*配置路径中action的规则*/ + 'action' => array( + 'url-param' => 'a', + 'default-value' => 'run', + ), + ), + ), /*配置default应用的模块配置*/ - 'modules' => array( + 'modules' => array( /*配置default模块*/ - 'default' => array( - /*default模块的路径*/ - 'path' => 'controller', + 'default' => array( + /*default模块的路径*/ + 'controller-path' => 'controller', /*default模块的中controller的后缀*/ - 'controller-suffix' => array('value' => 'Controller',), + 'controller-suffix' => 'Controller', /*default模块中处理error的Action controller路径*/ - 'error-handler' => array('class' => 'WIND:core.web.WindErrorHandler',), + 'error-handler' => 'WIND:core.web.WindErrorHandler', /*default模块的试图配置*/ - 'view' => array( - 'class' => 'windView', - 'config' => array( + 'view' => array( + 'class' => 'windView', + 'config' => array( /*模板路径*/ - 'template-dir' => array('value' => 'template',), + 'template-dir' => 'template', /*模板后缀*/ - 'template-ext' => array('value' => 'htm',), + 'template-ext' => 'htm', /*模板编译路径*/ - 'compile-dir' => array('value' => 'compile.template',), - ), + 'compile-dir' => 'compile.template', ), ), ), ), + /*db配置*/ + 'db' => array( + // 'resource' => 'db_config.php', + 'conn1' => array( + 'class' => 'COM:db.WindConnection', + 'dsn' => 'mysql:host=localhost;dbname=test', + 'user' => 'root', + 'pwd' => 'root', + 'charset' => 'utf8', + 'tablePrefix' => 'pw_' + ), + ), ), ); \ No newline at end of file diff --git a/docs/configtemplate/properties/wind_config.properties b/docs/configtemplate/properties/wind_config.properties index 927586eb..93e37ce5 100644 --- a/docs/configtemplate/properties/wind_config.properties +++ b/docs/configtemplate/properties/wind_config.properties @@ -1,44 +1,57 @@ #应用配置 -[web-apps] +[default] #default:为应用的name -default.class=windWebApp -default.root-path= - -#工厂配置 -default.factory.class-definition=components -default.factory.class=WIND:core.factory.WindComponentFactory +class=windWebApp +charset=utf-8 #过滤链配置 -default.filters.class=WIND:core.filter.WindFilterChain -default.filters.filter1.class=WIND:core.web.filter.WindLoggerFilter -default.filters.filter2.class=WIND:core.web.filter.WindUrlFilter +filters.class=WIND:core.filter.WindFilterChain +filters.filter1.class=WIND:core.web.filter.WindLoggerFilter +filters.filter2.class=WIND:core.web.filter.WindUrlFilter #配置default应用的路由配置信息, -default.router.class=urlBasedRouter +router.class=urlBasedRouter #module配置 -default.router.config.module.url-param=m -default.router.config.module.default-value=default +router.config.module.url-param=m +router.config.module.default-value=default #controller配置 -default.router.config.controller.url-param=c -default.router.config.controller.default-value=index +router.config.controller.url-param=c +router.config.controller.default-value=index #action配置 -default.router.config.action.url-param=a -default.router.config.action.default-value=run +router.config.action.url-param=a +router.config.action.default-value=run -#配置default应用的模块 #如下,配置了一个名为default的模块,及该default模块下该有的一些配置项信息 #default模块的路径信息 -default.modules.default.path=controller +modules.default.controller-path=controller #default模块的controller后缀信息 -default.modules.default.controller-suffix.value=Controller +modules.default.controller-suffix=Controller #default模块的error controller类 -default.modules.default.error-handler.class=WIND:core.web.WindErrorHandler +modules.default.error-handler=WIND:core.web.WindErrorHandler #default模块的视图配置 -default.modules.default.view.class=windView +modules.default.view.class=windView #模板文件路径 -default.modules.default.view.config.template-dir.value=template +modules.default.view.config.template-dir=template #模板后缀 -default.modules.default.view.config.template-ext.value=htm +modules.default.view.config.template-ext=htm #模板编译文件保存路径 -default.modules.default.view.config.compile-dir.value=compile.template \ No newline at end of file +modules.default.view.config.compile-dir=compile.template + +#数据库的配置信息 +#采用外联引入的方式 +#db.resource=db_config.php +#或是直接配置 +db.conn1.class=COM:db.WindConnection +db.conn1.dsn=mysql:host=localhost;dbname=test +db.conn1.user=root +db.conn1.pwd=root +db.conn1.charset=utf-8 +db.conn1.tablePrefix=pw_ +#可以同时配置多组 +db.conn2.class=COM:db.WindConnectionManage +db.conn2.config.c1.dsn=mysql:host=localhost;dbname=test +db.conn2.config.c1.user=root +db.conn2.config.c1.pwd=root +db.conn2.config.c1.charset=utf-8 +db.conn2.config.c1.tablePrefix=pw_ \ No newline at end of file From 3e9d7ee2c235a6d0e3c168ba7669f691e037d86a Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 2 Aug 2011 08:32:58 +0000 Subject: [PATCH 0228/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=20=20=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2288 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 5 ++--- wind/component/cache/strategy/WindFileCache.php | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index 25d3e0ad..34ba49a8 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -93,7 +93,7 @@ public abstract function clear(); */ public function set($key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { try { - $data = array(self::DATA => $value, self::EXPIRE => $expires, self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); + $data = array(self::DATA => $value, self::EXPIRE => $expires ? $expires : $this->getExpire(), self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); if (null != $denpendency) { $denpendency->injectDependent(); $data[self::DEPENDENCY] = serialize($denpendency); @@ -179,13 +179,12 @@ protected function formatData($key, $value) { protected function hasChanged($key, array $data) { if (isset($data[self::DEPENDENCY]) && $data[self::DEPENDENCY]) { $dependency = unserialize($data[self::DEPENDENCY]); - if (!$dependency->hasChanged()) return false; + if (!$dependency->hasChanged($this)) return false; } elseif (isset($data[self::EXPIRE]) && $data[self::EXPIRE]) { $_overTime = $data[self::EXPIRE] + $data[self::STORETIME]; if ($_overTime >= time()) return false; } else return false; - $this->delete($key); return true; } diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 4b1fe9d8..9232e65d 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -25,7 +25,7 @@ class WindFileCache extends AbstractWindCache { * 缓存多级目录。最好不要超3层目录 * @var int */ - private $cacheDirectoryLevel = ''; + private $cacheDirectoryLevel = 0; /** * 保存操作的路径信息, 存储使用过的key路径 @@ -51,8 +51,8 @@ protected function getValue($key) { /* (non-PHPdoc) * @see AbstractWindCache::deleteValue() */ - protected function deleteValue($cacheFile) { - return WindFile::write($cacheFile, ''); + protected function deleteValue($key) { + return WindFile::write($key, ''); } /* (non-PHPdoc) @@ -144,6 +144,7 @@ public function setConfig($config) { parent::setConfig($config); $this->setCacheDir($this->getConfig('dir')); $this->setCacheFileSuffix($this->getConfig('suffix', '', 'txt')); + $this->setCacheDirectoryLevel($this->getConfig('level', '', 0)); } } \ No newline at end of file From e876ed471d19d63855375cda1a81afe3c4e40271 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 2 Aug 2011 11:24:27 +0000 Subject: [PATCH 0229/1065] =?UTF-8?q?view=E8=AF=95=E5=9B=BE=E9=9D=99?= =?UTF-8?q?=E6=80=81=E9=A1=B5=E9=9D=A2=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2289 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindView.php | 61 ++++++++++++++++--- .../viewer/listener/WindViewCacheListener.php | 21 +++++-- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index d0935d9c..705c18d9 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -42,6 +42,13 @@ class WindView extends WindModule { */ protected $isCache = false; + /** + * 缓存策略 + * + * @var string + */ + protected $cacheClass; + /** * 是否对模板变量进行html字符过滤 * @@ -60,6 +67,11 @@ class WindView extends WindModule { * @var WindViewerResolver */ protected $viewResolver = null; + /** + * 试图缓存 + * @var AbstractWindCache + */ + protected $viewCache = null; /** * 布局文件 * @@ -147,6 +159,7 @@ public function init() { $this->setCompileDir($this->getConfig('compile-dir')); $this->setTemplateExt($this->getConfig('template-ext')); $this->setIsCache($this->getConfig('is-cache')); + $this->setCacheClass($this->getConfig('cache-class')); } /** @@ -176,7 +189,7 @@ public function getTemplateExt() { public function getTemplateName() { return $this->templateName; } - + /** * @return boolean */ @@ -191,6 +204,13 @@ public function getLayout() { return $this->layout; } + /** + * @return string + */ + public function getCacheClass() { + return $this->cacheClass; + } + /** * @param string $templateDir */ @@ -223,7 +243,7 @@ public function setTemplateName($templateName) { * @param boolean $isCache */ public function setIsCache($isCache) { - $this->isCache = $isCache; + $this->isCache = (strtolower($isCache) == 'true' || $isCache == '1'); } /** @@ -232,6 +252,13 @@ public function setIsCache($isCache) { public function setLayout($layout) { $this->layout = $layout; } + + /** + * @param string $class + */ + public function setCacheClass($class) { + $this->cacheClass = $class; + } /** * @return the $htmlspecialchars @@ -246,17 +273,35 @@ public function getHtmlspecialchars() { public function setHtmlspecialchars($htmlspecialchars) { $this->htmlspecialchars = $htmlspecialchars; } + + /** + * @return WindViewerCache + */ + public function getViewCache() { + if ($this->viewCache === null) { + $this->_getViewCache(); + } + return $this->viewCache; + } + + /** + * @param AbstractWindCache $viewCache + */ + public function setViewCache($viewCache) { + $this->viewCache = $viewCache; + } /** * @return WindViewerResolver */ public function getViewResolver() { - if ($this->viewResolver === null) { - $this->_getViewResolver(); - $this->viewResolver->setWindView($this); - /*$this->viewResolver->setDelayAttributes( - array('windView' => array(WindClassDefinition::REF => COMPONENT_VIEW)));*/ - } + if (null !== $this->viewResolver) return $this->viewResolver; + $this->_getViewResolver(); + $this->viewResolver->setWindView($this); + if (!$this->getIsCache()) return $this->viewResolver; + $this->viewResolver = new WindClassProxy($this->viewResolver); + $listener = Wind::import('COM:viewer.listener.WindViewCacheListener'); + $this->viewResolver->registerEventListener('windFetch', new $listener($this)); return $this->viewResolver; } diff --git a/wind/component/viewer/listener/WindViewCacheListener.php b/wind/component/viewer/listener/WindViewCacheListener.php index a2476660..ea5c73b7 100644 --- a/wind/component/viewer/listener/WindViewCacheListener.php +++ b/wind/component/viewer/listener/WindViewCacheListener.php @@ -18,7 +18,7 @@ class WindViewCacheListener extends WindHandlerInterceptor { * Enter description here ... * @param WindView $windView */ - function __construct($windView) { + public function __construct($windView) { $this->windView = $windView; } @@ -26,15 +26,28 @@ function __construct($windView) { * @see WindHandlerInterceptor::preHandle() */ public function preHandle() { - //print_r($this->windView); - //TODO 读缓存 + $data = $this->windView->getViewCache()->get($this->getKey()); + $data = !$data ? null : $data; + return $data; + } + + /** + * 获得保存的key值 + */ + private function getKey() { + $host = Wind::getApp()->getRequest()->getHostInfo(); + $uri = Wind::getApp()->getRequest()->getRequestUri(); + return md5($host.$uri . '/' . $this->windView->getTemplateName() . '.' . $this->windView->getTemplateExt()); } /* (non-PHPdoc) * @see WindHandlerInterceptor::postHandle() */ public function postHandle() { - //TODO 写缓存 + $args = func_get_args(); + $result = end($args); + $cache = $this->windView->getViewCache(); + $cache->set($this->getKey(), $result); } } From 6f5fee460f110c89274780ed819e6185b5a6b758 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 2 Aug 2011 11:24:44 +0000 Subject: [PATCH 0230/1065] =?UTF-8?q?=E4=BB=A3=E7=90=86=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2290 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/proxy/WindClassProxy.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/wind/core/factory/proxy/WindClassProxy.php b/wind/core/factory/proxy/WindClassProxy.php index df5dce07..a383e601 100644 --- a/wind/core/factory/proxy/WindClassProxy.php +++ b/wind/core/factory/proxy/WindClassProxy.php @@ -9,7 +9,7 @@ * @package */ class WindClassProxy implements IWindClassProxy { - private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; + private $_interceptorChain = 'COM:filter.WindHandlerInterceptorChain'; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; @@ -128,11 +128,9 @@ protected function initClassProxy($targetObject, $args = array()) { * @return */ private function _getInterceptorChain($event = '') { - $interceptorChain = WindFactory::createInstance($this->_interceptorChain); + $chain = Wind::import($this->_interceptorChain); + $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { - $interceptorChain->setAttribute($this->_getAttribute()); - $interceptorChain->setAttribute('instance', $this->_getInstance()); - $interceptorChain->setAttribute('event', array($this->_getClassName(), $event)); return $interceptorChain; } else throw new WindException('unable to create interceptorChain.'); From 15086ecace1e28716110b33880b55a3d3bd4e4b4 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 2 Aug 2011 11:25:00 +0000 Subject: [PATCH 0231/1065] =?UTF-8?q?=E8=BF=87=E6=BB=A4=E9=93=BE=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2291 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/filter/WindHandlerInterceptor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/filter/WindHandlerInterceptor.php b/wind/component/filter/WindHandlerInterceptor.php index c6ca0890..cf104e57 100644 --- a/wind/component/filter/WindHandlerInterceptor.php +++ b/wind/component/filter/WindHandlerInterceptor.php @@ -34,7 +34,7 @@ public function handle() { } else { $this->result = $this->interceptorChain->execute(); } - call_user_func_array(array($this, 'postHandle'), $args); + call_user_func_array(array($this, 'postHandle'), $args + (array)$this->result); return $this->result; } From 5d8cc2d7783deea515cfa54cd89fe907abb78653 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 3 Aug 2011 02:16:41 +0000 Subject: [PATCH 0232/1065] =?UTF-8?q?=E8=A7=A3=E6=9E=90=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20=E6=B7=BB=E5=8A=A0=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E6=98=AFdebug=E7=8A=B6=E6=80=81=E5=88=99=E4=B8=8D=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2292 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/parser/WindConfigParser.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index 01d7807e..072b02bc 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -79,6 +79,7 @@ private function setCache($alias, $append, $cache, $data) { * @return array */ private function getCache($alias, $append, $cache) { + if (IS_DEBUG) return array(); if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); From 59b4a4e375831bbee001df29053f1d54dda124d2 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 3 Aug 2011 05:43:02 +0000 Subject: [PATCH 0233/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=20=20=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2293 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindDbCache.php | 86 +++++-------------- 1 file changed, 21 insertions(+), 65 deletions(-) diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php index a229ea08..56d8f5d4 100644 --- a/wind/component/cache/strategy/WindDbCache.php +++ b/wind/component/cache/strategy/WindDbCache.php @@ -10,16 +10,10 @@ class WindDbCache extends AbstractWindCache { /** - * 分布式管理 + * 链接句柄 * @var AbstractWindDbAdapter */ private $connection; - - /** - * 链接配置信息 - * @var array - */ - private $dbConfig; /** * 缓存表 @@ -46,7 +40,7 @@ class WindDbCache extends AbstractWindCache { private $expireField = 'expire'; /** - * 缓存表过期时间字段 + * 配置文件 * @var string */ private $dbConfigName = ''; @@ -60,12 +54,6 @@ public function __construct(WindConnection $connection = null, $config = array() * @see AbstractWindCache#setValue() */ protected function setValue($key, $value, $expire = 0) { - (mt_rand(100, 1000000) % 100 == 0) && $this->deleteExpiredCache(); - $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =?' ; - $data = $this->getConnection()->createStatement($sql)->getOne(array($key)); - if ($data) { - return $this->update($key, $value, $expire); - } return $this->store($key, $value, $expire); } @@ -120,14 +108,6 @@ public function clear() { return $this->getConnection()->execute('DELETE FROM ' . $this->getTableName()); } - /** - * 删除过期数据 - */ - public function deleteExpiredCache() { - $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->expireField . '`>0 AND `' . $this->expireField . '` <'.time(); - return $this->getConnection()->execute($sql); - } - /* (non-PHPdoc) * @see WindModule::setConfig() */ @@ -140,6 +120,14 @@ public function setConfig($config) { $this->dbConfigName = $this->getConfig('dbconfig-name', '', '', $config); } + /** + * 设置链接对象 + * @param WindConnection $connection + */ + public function setConnection($connection) { + if ($connection instanceof WindConnection) $this->connection = $connection; + } + /** * 返回表名 * @return string @@ -147,22 +135,20 @@ public function setConfig($config) { private function getTableName() { return $this->table; } - - /** - * 析构函数 - */ - public function __destruct() { - if (null !== $this->getConnection()) { - $this->deleteExpiredCache(); - } - } /** - * 设置链接对象 - * @param WindConnection $connection + * 存储数据 + * @param string $key + * @param string $value + * @param int $expires + * @param IWindCacheDependency $denpendency + * @return boolean */ - public function setConnection($connection) { - if ($connection instanceof WindConnection) $this->connection = $connection; + private function store($key, $value, $expires = 0) { + ($expires > 0) ? $expires += time() : $expire=0; + $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires); + $sql = 'REPLACE INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db); + return $this->getConnection()->createStatement($sql)->update(); } /** @@ -182,34 +168,4 @@ private function getConnection() { } return $this->connection; } - - /** - * 存储数据 - * @param string $key - * @param string $value - * @param int $expires - * @param IWindCacheDependency $denpendency - * @return boolean - */ - private function store($key, $value, $expires = 0) { - ($expires > 0) ? $expires += time() : $expire=0; - $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires); - $sql = 'INSERT INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db); - return $this->getConnection()->createStatement($sql)->update(); - } - - /** - * 更新数据 - * @param string $key - * @param int $value - * @param int $expires - * @param IWindCacheDependency $denpendency - * @return boolean - */ - private function update($key, $value, $expires = 0) { - ($expires > 0) ? $expires += time() : $expire=0; - $db = array($this->valueField => $value, $this->expireField => $expires); - $sql = "UPDATE " . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db) . ' WHERE `' . $this->keyField . '`=?'; - return $this->getConnection()->createStatement($sql)->update(array($key), true); - } } \ No newline at end of file From e2df09e372b395e7090f28450fb735784c66db3a Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 3 Aug 2011 05:43:23 +0000 Subject: [PATCH 0234/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=20=20=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2294 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/WindCache.php | 132 ----------------------------- 1 file changed, 132 deletions(-) delete mode 100644 wind/component/cache/WindCache.php diff --git a/wind/component/cache/WindCache.php b/wind/component/cache/WindCache.php deleted file mode 100644 index 615b261c..00000000 --- a/wind/component/cache/WindCache.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindCache extends WindModule { - - private $caches = array(); - - const DB = 'db'; - const APC = 'apc'; - const FILE = 'file'; - const EAC = 'eaccelerator'; - const MEMCACHE = 'mem'; - const WINCACHE = 'win'; - const XCACHE = 'XCache'; - const ZEND = 'ZendCache'; - - /** - * 保存数据 - * - * @param string $type 缓存类型 - * @param string $key - * @param mixed $value - * @param int $expires - * @param AbstractWindCacheDependency $denpendency - * @return mixed - */ - public function set($type, $key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { - $cache = $this->getCache($type); - return $cache->set($key, $value, $expires, $denpendency); - } - - /** - * 获取数据 - * - * @param string $type 缓存类型 - * @param string $key - * @return mixed - */ - public function get($type, $key) { - $cache = $this->getCache($type); - return $cache->get($key); - } - - /** - * 删除缓存数据 - * - * @param string $type 缓存类型 - * @param string $key 获取缓存数据的标识,即键 - * @return mixed - */ - public function delete($type, $key) { - $cache = $this->getCache($type); - return $cache->delete($key); - } - - /** - * 批量获取数据 - * - * @param string $type - * @param string $keys - * @return array - */ - public function batchGet($type, array $keys) { - $cache = $this->getCache($type); - return $cache->batchGet($keys); - } - - /** - * 通过key批量删除缓存数据 - * - * @param string $type - * @param array $keys - * @return boolean - */ - public function batchDelete($type, array $keys) { - $cache = $this->getCache($type); - return $cache->batchDelete($keys); - } - - /** - * 通过key批量删除缓存数据 - * - * @param string $type - * @return boolean - */ - public function clear($type = '') { - if ($type) { - $cache = $this->getCache($type); - return $cache->clear(); - } - foreach ($this->caches as $key => $cache) { - $cache->clear(); - } - return true; - } - - /** - * 获得缓存类型 - * - * @param string $type - * @return AbstractWindCache - */ - public function getCache($type) { - $className = $this->getCacheMap($type); - if (!$className) - throw new WindException('The cache strategy \'' . $type . '\' is not exists!'); - if (isset($this->caches[$className])) - return $this->caches[$className]; - Wind::import('WIND:component.cache.strategy.' . $className); - $cache = new $className(); - $config = $this->getSystemConfig()->getCacheConfig($type); - if ($config) - $cache->setConfig($config); - $this->caches[$className] = $cache; - return $cache; - } - - /** - * 对应类型对应的缓存 - * - * @param string $type - */ - private function getCacheMap($type) { - $types = array(self::DB => 'WindDbCache', self::APC => 'WindApcCache', self::FILE => 'WindFileCache', self::EAC => 'WindEacceleratorCache', self::MEMCACHE => 'WindMemCache', self::WINCACHE => 'WindWinCache', self::XCACHE => 'WindXCache', self::ZEND => 'WindZendCache'); - return isset($types[$type]) ? $types[$type] : null; - } -} \ No newline at end of file From b771360316a8937ba6ca36b9bf03d1ef09843170 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 3 Aug 2011 06:22:49 +0000 Subject: [PATCH 0235/1065] =?UTF-8?q?cache=E7=BC=93=E5=AD=98=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=20=20=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2295 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindFileCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index 9232e65d..a2e5b70a 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -144,7 +144,7 @@ public function setConfig($config) { parent::setConfig($config); $this->setCacheDir($this->getConfig('dir')); $this->setCacheFileSuffix($this->getConfig('suffix', '', 'txt')); - $this->setCacheDirectoryLevel($this->getConfig('level', '', 0)); + $this->setCacheDirectoryLevel($this->getConfig('dir-level', '', 0)); } } \ No newline at end of file From 19fbfcd679b8f4e7bf98d74f263af8168b21d200 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 3 Aug 2011 06:24:11 +0000 Subject: [PATCH 0236/1065] =?UTF-8?q?DB=E8=B0=83=E6=95=B4=EF=BC=8C?= =?UTF-8?q?=E9=80=82=E5=90=88WindConnectionManager=E7=9A=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2296 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDao.php | 11 +++-- wind/component/db/WindConnectionManager.php | 50 +++++++++++++++------ 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php index e568c236..abae1e17 100644 --- a/wind/component/dao/WindDao.php +++ b/wind/component/dao/WindDao.php @@ -30,7 +30,7 @@ class WindDao extends WindModule { * @var object */ protected $connection = null; - private $cacheHandler = null; + protected $cacheHandler = null; /** * 获得需要缓存的处理的方法名称数组 @@ -42,10 +42,15 @@ public function getCacheMethods() { } /** + * 根据用户配置决定配置是采用配置链接管理 * @return WindConnection */ - public function getConnection() { - return $this->_getConnection(); + public function getConnection($name = '') { + $this->_getConnection(); + if ($this->connection instanceof WindConnectionManager) { + return $this->connection->getConnection($name); + } + return $this->connection; } /** diff --git a/wind/component/db/WindConnectionManager.php b/wind/component/db/WindConnectionManager.php index 9594e90b..abd2f013 100644 --- a/wind/component/db/WindConnectionManager.php +++ b/wind/component/db/WindConnectionManager.php @@ -1,5 +1,25 @@ 'COM:db.WindConnectionManager', + 'db1' => array( + 'user' => 'xxx', + 'pwd' => 'xxx', + 'dsn' => 'mysql:host=localhost;dbname=test', + 'charset' => 'UTF8', + 'tablePrefix' => 'xx_', //新旧表前缀替换,前一个替换|之后的前缀 + ), + 'db2' => array( + 'user' => 'xxx', + 'pwd' => 'xxx', + 'dsn' => 'mysql:host=localhost;dbname=test', + 'charset' => 'UTF8', + 'tablePrefix' => 'xx_', //新旧表前缀替换,前一个替换|之后的前缀 + ), + ), + */ /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu @@ -14,7 +34,14 @@ class WindConnectionManager extends WindModule { * @var array */ private $connections = array(); - + + /** + * 初始化操作,将配置中的class的配置项删除 + */ + public function init() { + unset($this->_config['class']); + } + /** * 根据链接名称返回链接句柄,name为空则返回随机返回一个俩接句柄 * @param unknown_type $name @@ -22,17 +49,11 @@ class WindConnectionManager extends WindModule { */ public function getConnection($name = '') { if (isset($this->connections[$name])) return $this->connections[$name]; - $configs = $this->getConfig(); - if (!is_array($configs) || empty($configs)) { - throw new WindDbException('[component.db.WindConnectionManager.getConnection] empty config.'); - } $config = array(); if ($name !== '') { - foreach ($configs as $value) { - if ($value['name'] == $name) { - $config = $value; - break; - } + $config = $this->getConfig($name); + if (!is_array($config) || empty($config)) { + throw new WindDbException('[component.db.WindConnectionManager.getConnection] empty config.'); } } else { $config = $this->getCurrentConnection(); @@ -46,10 +67,13 @@ public function getConnection($name = '') { } /** - * 返回当前连接句柄的配置信息 + * 随机返回当前连接句柄的配置信息 + * @return array */ - protected function getCurrentConnection() { + private function getCurrentConnection() { $configs = $this->getConfig(); - return count($configs) > 1 ? $configs[rand(0, count($configs) - 1)] : $configs[0]; + $keys = array_keys($configs); + $key = count($keys) > 1 ? $keys[rand(0, count($keys) - 1)] : $keys[0]; + return $configs[$key]; } } \ No newline at end of file From b873e37b4860dd0e3b9d8435887930ffac24f37e Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 4 Aug 2011 02:23:36 +0000 Subject: [PATCH 0237/1065] =?UTF-8?q?=E8=BE=93=E5=87=BA=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=20=20=20=20=20=20=20=20=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E8=BE=93=E5=87=BA=E7=9A=84=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E4=B8=8E=E5=90=A6=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2297 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindView.php | 2 +- .../compiler/WindTemplateCompilerEcho.php | 41 +++++++++++++------ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 705c18d9..675d3cff 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -54,7 +54,7 @@ class WindView extends WindModule { * * @var boolean */ - protected $htmlspecialchars = false; + protected $htmlspecialchars = true; /** * 编译目录 * diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index af095ccd..5db9ad7a 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -2,10 +2,11 @@ Wind::import('COM:viewer.AbstractWindTemplateCompiler'); Wind::import('COM:utility.WindHtmlHelper'); /** - * 变量输出解析 - * {$var|false} - * {@$var->a|false} - * {@templateName:var} + * 变量输出解析 + * 变量名称|变量格式(html,text) + * {$var|html} //不执行编译 + * {@$var->a|text} //执行编译 + * {@templateName:var|html} * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu @@ -18,27 +19,41 @@ class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { * @see AbstractWindTemplateCompiler::compile() */ public function compile($key, $content) { - $_output = $content; - $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $_output); - $_output = $this->compileVarShare($_output); - if ($this->windViewerResolver->getWindView()->getHtmlspecialchars() === true) + $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content); + list($_output, $type) = $this->doCompile($_output); + if ($this->windViewerResolver->getWindView()->getHtmlspecialchars() === true && $type == 'text') return ''; else return ''; } + /** + * 处理变量 + * @param string $var + * @return array + */ + private function doCompile($var) { + $vars = explode('|', $var, 2); + $type = isset($vars[1]) ? strtolower($vars[1]) : 'text'; + !in_array($type, $this->getType()) && $type = 'text'; + return array($this->compileVarShare($vars[0]), $type); + } /** * @param string $input * @return string */ private function compileVarShare($input) { - $input = trim($input); if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) return $input; list($templateName, $var) = explode(':', $input); - $input = '$this->getResponse()->getData(\'' . $templateName . '\', \'' . $var . '\')'; - return $input; + return '$this->getResponse()->getData(\'' . $templateName . '\', \'' . $var . '\')'; + } + + /** + * 获得变量后的|之后的值 + * @return array + */ + private function getType() { + return array('html', 'text'); } - } - ?> \ No newline at end of file From bdcc3dfcf5aa7888784ca30468bf87f5082b6358 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 4 Aug 2011 02:26:11 +0000 Subject: [PATCH 0238/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2298 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/compiler/WindTemplateCompilerAction.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerAction.php b/wind/component/viewer/compiler/WindTemplateCompilerAction.php index 18a4ba68..cf734b8f 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerAction.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerAction.php @@ -28,8 +28,7 @@ public function compile($key, $content) { * @return string */ public function getScript() { - $_tmp = ''; - $_tmp .= '$_tpl_forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD);' . + $_tmp = '$_tpl_forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD);' . '$_tpl_forward->setDisplay(true);' . '$_tpl_forward->forwardAnotherAction(\'' . $this->action . '\', \'' . $this->controller . '\');' . '$_tpl_app = $this->getSystemFactory()->getInstance(COMPONENT_WEBAPP);'. From 60318e6003f7f0b5bc3938ed70fc7a53ae74b036 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 4 Aug 2011 02:27:13 +0000 Subject: [PATCH 0239/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2299 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/configtemplate/db_config.xml | 12 ++++++++- docs/configtemplate/filecache_config.xml | 1 - docs/configtemplate/ini/db_config.ini | 12 +++++++-- docs/configtemplate/ini/dbcache_config.ini | 23 ++++++---------- docs/configtemplate/ini/filecache_config.ini | 18 +++++-------- docs/configtemplate/ini/memcache.ini | 27 +++++++++---------- docs/configtemplate/memcache_config.xml | 10 +++---- docs/configtemplate/php/db_config.php | 22 +++++++++++---- docs/configtemplate/php/dbcache_config.php | 19 ++++++------- docs/configtemplate/php/filecache_config.php | 14 +++++----- docs/configtemplate/php/memcache.php | 24 ++++++++++++----- .../properties/db_config.properties | 9 +++++++ .../properties/dbcache_config.properties | 23 ++++++---------- .../properties/filecache_config.properties | 18 +++++-------- .../properties/memcache.properties | 25 ++++++++--------- 15 files changed, 136 insertions(+), 121 deletions(-) diff --git a/docs/configtemplate/db_config.xml b/docs/configtemplate/db_config.xml index 16c20920..e91f7deb 100644 --- a/docs/configtemplate/db_config.xml +++ b/docs/configtemplate/db_config.xml @@ -1,4 +1,4 @@ - + @@ -9,4 +9,14 @@ utf8 pw_ + + COM:db.WindConnectionManager + + mysql:host=localhost;dbname=test + root + root + utf8 + pw_ + + \ No newline at end of file diff --git a/docs/configtemplate/filecache_config.xml b/docs/configtemplate/filecache_config.xml index 4794b8ad..1a186d83 100644 --- a/docs/configtemplate/filecache_config.xml +++ b/docs/configtemplate/filecache_config.xml @@ -14,5 +14,4 @@ php 0 - diff --git a/docs/configtemplate/ini/db_config.ini b/docs/configtemplate/ini/db_config.ini index 0caf4e56..98993491 100644 --- a/docs/configtemplate/ini/db_config.ini +++ b/docs/configtemplate/ini/db_config.ini @@ -1,7 +1,15 @@ -;dbConfig的配置信息 - +;dbconfig的配置 +[conn1] +class='COM:db.WindConnection' dsn='mysql:host=localhost;dbname=test' user=root pwd=root charset=utf8 tablePrefix=pw_ +[manage] +class='COM:db.WindConnectionManager' +db1.dsn='mysql:host=localhost;dbname=test' +db1.user=root +db1.pwd=root +db1.charset=utf8 +db1.tablePrefix=pw_ \ No newline at end of file diff --git a/docs/configtemplate/ini/dbcache_config.ini b/docs/configtemplate/ini/dbcache_config.ini index bf5b66f8..20e40af9 100644 --- a/docs/configtemplate/ini/dbcache_config.ini +++ b/docs/configtemplate/ini/dbcache_config.ini @@ -1,17 +1,10 @@ ;数据库缓存的配置信息 - +expires=0 +key-prefix='' +security-code='' ;配置数据缓存表 -[cache-table] -table-name.value=pw_cache -field-key.value=name -field-value.value=cache -field-expire.value=time -expirestrage.value=true - -;缓存key是否经过安全处理 -[security] -value=true - -;缓存过期时间 -[expires] -value=20 \ No newline at end of file +dbconfig-name=test +table-name=pw_cache +field-key=key +field-value=value +field-expire=expire \ No newline at end of file diff --git a/docs/configtemplate/ini/filecache_config.ini b/docs/configtemplate/ini/filecache_config.ini index 8ff58ec0..f2d0ac00 100644 --- a/docs/configtemplate/ini/filecache_config.ini +++ b/docs/configtemplate/ini/filecache_config.ini @@ -1,12 +1,8 @@ ;文件缓存配置 - -;缓存文件的保存路径(支持命名空间的方式配置该路径) -cache-dir.value=WEB:compile -;缓存的级别 -cache-level.value=0 -;缓存文件的后缀 -cache-suffix.value=php -;缓存文件的key值是否经过安全处理 -security.value=true -;缓存文件的过期时间 -expires.value=20 \ No newline at end of file +expires=0 +key-prefix='' +security-code='' +;配置数据缓存表 +dir=WIND:_compile +suffix=php +dir-level=0 \ No newline at end of file diff --git a/docs/configtemplate/ini/memcache.ini b/docs/configtemplate/ini/memcache.ini index fce4a4e2..e1b844bf 100644 --- a/docs/configtemplate/ini/memcache.ini +++ b/docs/configtemplate/ini/memcache.ini @@ -1,21 +1,18 @@ ;memcache配置 - +expires=0 +key-prefix='' +security-code='' +compress=2 ;memcache服务器相关配置 可以配置多个 [servers] phpwind.host=127.0.0.1 phpwind.port=11211 - +phpwind.pconn=0 +phpwind.weight=1 +phpwind.timeout=15 +phpwind.retry=15 +phpwind.status=1 +phpwind.fcallback='' +;第二个服务器配置 cac.host=127.0.0.1 -cac.port=11212 - -;压缩的级次 -[compress] -value=2 - -;缓存key是否经过安全过滤 -[security] -value=true - -;缓存过期时间 -[expires] -value=20 \ No newline at end of file +cac.port=11212 \ No newline at end of file diff --git a/docs/configtemplate/memcache_config.xml b/docs/configtemplate/memcache_config.xml index 9dd2554d..b8eee033 100644 --- a/docs/configtemplate/memcache_config.xml +++ b/docs/configtemplate/memcache_config.xml @@ -1,15 +1,15 @@ - + 0 - + - + - + 2 @@ -35,4 +35,4 @@ 11212 - + diff --git a/docs/configtemplate/php/db_config.php b/docs/configtemplate/php/db_config.php index 094ebbf0..61256a05 100644 --- a/docs/configtemplate/php/db_config.php +++ b/docs/configtemplate/php/db_config.php @@ -10,9 +10,21 @@ * 可以配置多个链接,多个链接的时候必需指定每个链接的type类型是master/slave,当配置一个的时候可以不配置type项 */ return array( - 'dsn' => 'mysql:host=localhost;dbname=test', - 'user' => 'root', - 'pwd' => 'root', - 'charset' => 'utf8', - 'tablePrefix' => 'pw_' + 'conn1' => array( + 'dsn' => 'mysql:host=localhost;dbname=test', + 'user' => 'root', + 'pwd' => 'root', + 'charset' => 'utf8', + 'tablePrefix' => 'pw_' + ), + 'manage' => array( + 'class' => 'COM:db.WindConnectionManager', + 'db1' => array( + 'dsn' => 'mysql:host=localhost;dbname=test', + 'user' => 'root', + 'pwd' => 'root', + 'charset' => 'utf8', + 'tablePrefix' => 'pw_' + ), + ), ); \ No newline at end of file diff --git a/docs/configtemplate/php/dbcache_config.php b/docs/configtemplate/php/dbcache_config.php index 11f42238..a525989e 100644 --- a/docs/configtemplate/php/dbcache_config.php +++ b/docs/configtemplate/php/dbcache_config.php @@ -10,16 +10,13 @@ * 数据库缓存的配置信息 */ return array( + 'expires' => '0', + 'key-prefix' => '', + 'security-code' => '', /*配置数据缓存表*/ - 'cache-table' => array( - 'table-name' => array('value' => 'pw_cache'), - 'field-key' => array('value' => 'name'), - 'field-value' => array('value' => 'cache'), - 'field-expire' => array('value' => 'time'), - 'expirestrage' => array('value' => 'true'), - ), - /*缓存key是否经过安全处理*/ - 'security' => array('value' => 'true'), - /*缓存过期时间*/ - 'expires' => array('value' => '20'), + 'dbconfig-name' => 'test', + 'table-name' => 'pw_cache', + 'field-key' => 'key', + 'field-value' => 'value', + 'field-expire' => 'expire', ); \ No newline at end of file diff --git a/docs/configtemplate/php/filecache_config.php b/docs/configtemplate/php/filecache_config.php index 1afeae2d..bbcf946b 100644 --- a/docs/configtemplate/php/filecache_config.php +++ b/docs/configtemplate/php/filecache_config.php @@ -10,14 +10,12 @@ * 文件缓存的配置 */ return array( + 'expires' => '0', + 'key-prefix' => '', + 'security-code' => '', /*缓存文件的保存路径(支持命名空间的方式配置该路径)*/ - 'cache-dir' => array('value' => 'WEB:compile'), - /*缓存的级别*/ - 'cache-level' => array('value' => '0'), + 'dir' => 'WIND:_compile', /*缓存文件的后缀*/ - 'cache-suffix' => array('value' => 'php'), - /*缓存文件的key值是否经过安全处理*/ - 'security' => array('value' => 'true'), - /*缓存文件的过期时间*/ - 'expires' => array('value' => '20'), + 'suffix' => 'php', + 'dir-level' => '0', ); \ No newline at end of file diff --git a/docs/configtemplate/php/memcache.php b/docs/configtemplate/php/memcache.php index 9828ef04..ea7ef8f3 100644 --- a/docs/configtemplate/php/memcache.php +++ b/docs/configtemplate/php/memcache.php @@ -10,14 +10,24 @@ * memcache配置 */ return array( + 'expires' => '0', + 'key-prefix' => '', + 'security-code' => '', + /*压缩的级次*/ + 'compress' => '2', /*memcache服务器相关配置 可以配置多个*/ 'servers' => array( - 'phpwind' => array('host' => '127.0.0.1', 'port' => '11211'), + 'phpwind' => array( + 'host' => '127.0.0.1', + 'port' => '11211', + 'pconn' => true, + 'weight' => 1, + 'timeout' => 15, + 'retry' => 15, + 'status' => true, + 'fcallback' => '', + ), 'cac' => array('host' => '127.0.0.1', 'port' => '11212') ), - /*压缩的级次*/ - 'compress' => array('value' => '2'), - /*缓存key是否经过安全过滤*/ - 'security' => array('value' => 'true'), - /*缓存过期时间*/ - 'expires' => array('value' => '20')); \ No newline at end of file +); + \ No newline at end of file diff --git a/docs/configtemplate/properties/db_config.properties b/docs/configtemplate/properties/db_config.properties index bbb147a2..c3e28921 100644 --- a/docs/configtemplate/properties/db_config.properties +++ b/docs/configtemplate/properties/db_config.properties @@ -1,6 +1,15 @@ #dbconfig的配置 +[conn1] +class='COM:db.WindConnection' dsn='mysql:host=localhost;dbname=test' user=root pwd=root charset=utf8 tablePrefix=pw_ +[manage] +class='COM:db.WindConnectionManager' +db1.dsn='mysql:host=localhost;dbname=test' +db1.user=root +db1.pwd=root +db1.charset=utf8 +db1.tablePrefix=pw_ \ No newline at end of file diff --git a/docs/configtemplate/properties/dbcache_config.properties b/docs/configtemplate/properties/dbcache_config.properties index b4e194fa..96959ccd 100644 --- a/docs/configtemplate/properties/dbcache_config.properties +++ b/docs/configtemplate/properties/dbcache_config.properties @@ -1,17 +1,10 @@ #数据库缓存的配置信息 - +expires=0 +key-prefix='' +security-code='' #配置数据缓存表 -[cache-table] -table-name.value=pw_cache -field-key.value=name -field-value.value=cache -field-expire.value=time -expirestrage.value=true - -#缓存key是否经过安全处理 -[security] -value=true - -#缓存过期时间 -[expires] -value=20 \ No newline at end of file +dbconfig-name=test +table-name=pw_cache +field-key=key +field-value=value +field-expire=expire diff --git a/docs/configtemplate/properties/filecache_config.properties b/docs/configtemplate/properties/filecache_config.properties index da3399fe..c4fdd5ba 100644 --- a/docs/configtemplate/properties/filecache_config.properties +++ b/docs/configtemplate/properties/filecache_config.properties @@ -1,12 +1,8 @@ #文件缓存配置 - -#缓存文件的保存路径(支持命名空间的方式配置该路径) -cache-dir.value=WEB:compile -#缓存的级别 -cache-level.value=0 -#缓存文件的后缀 -cache-suffix.value=php -#缓存文件的key值是否经过安全处理 -security.value=true -#缓存文件的过期时间 -expires.value=20 \ No newline at end of file +expires=0 +key-prefix='' +security-code='' +#配置数据缓存表 +dir=WIND:_compile +suffix=php +dir-level=0 \ No newline at end of file diff --git a/docs/configtemplate/properties/memcache.properties b/docs/configtemplate/properties/memcache.properties index cd5949fd..fb050edd 100644 --- a/docs/configtemplate/properties/memcache.properties +++ b/docs/configtemplate/properties/memcache.properties @@ -1,21 +1,18 @@ #memcache配置 - +expires=0 +key-prefix='' +security-code='' +compress=2 #memcache服务器相关配置 可以配置多个 [servers] phpwind.host=127.0.0.1 phpwind.port=11211 - +phpwind.pconn=0 +phpwind.weight=1 +phpwind.timeout=15 +phpwind.retry=15 +phpwind.status=1 +phpwind.fcallback='' +#第二个服务器配置 cac.host=127.0.0.1 cac.port=11212 - -#压缩的级次 -[compress] -value=2 - -#缓存key是否经过安全过滤 -[security] -value=true - -#缓存过期时间 -[expires] -value=20 \ No newline at end of file From ff2657555b93b5b1ceb6bc7919b126c832a9093e Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 4 Aug 2011 07:20:39 +0000 Subject: [PATCH 0240/1065] =?UTF-8?q?ftp=E4=B8=8A=E4=BC=A0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2300 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/ftp/AbstractWindFtp.php | 181 ++++++++++++ wind/component/ftp/WindFtp.php | 186 +++++++++++++ wind/component/ftp/WindSocketFtp.php | 274 +++++++++++++++++++ wind/component/upload/AbstractWindUpload.php | 180 +++++++++++- wind/component/upload/WindFormUpload.php | 165 +---------- wind/component/upload/WindFtpUpload.php | 56 ++++ 6 files changed, 880 insertions(+), 162 deletions(-) create mode 100644 wind/component/ftp/AbstractWindFtp.php create mode 100644 wind/component/ftp/WindFtp.php create mode 100644 wind/component/ftp/WindSocketFtp.php create mode 100644 wind/component/upload/WindFtpUpload.php diff --git a/wind/component/ftp/AbstractWindFtp.php b/wind/component/ftp/AbstractWindFtp.php new file mode 100644 index 00000000..22a68b2a --- /dev/null +++ b/wind/component/ftp/AbstractWindFtp.php @@ -0,0 +1,181 @@ + + * @author xiaoxiao + * @version 2011-8-1 xiaoxiao + */ +abstract class AbstractWindFtp { + protected $server = ''; + protected $port = 21; + protected $user = ''; + protected $pwd = ''; + protected $dir = ''; + protected $timeout = 10; + protected $rootPath = ''; + + protected $conn = null; + /** + * 初始化配置信息 + * @param array $config + * @return bool + */ + public function initConfig($config) { + if (!$config || !is_array($config)) return false; + isset($config['server']) && $this->server = $config['server']; + isset($config['port']) && $this->port = $config['port']; + isset($config['user']) && $this->user = $config['user']; + isset($config['pwd']) && $this->pwd = $config['pwd']; + isset($config['dir']) && $this->dir = $config['dir']; + isset($config['timeout']) && $this->timeout = $config['timeout']; + return true; + } + + /** + * 重命名文件 + * @param string $oldName + * @param string $newName + * @return boolean + */ + abstract public function rename($oldName, $newName); + /** + * 删除文件 + * @param string $filename + * @return boolean + */ + abstract public function delete($filename); + /** + * 上传文件 + * @param string $sourceFile + * @param string $desFile + * @param string $mode + * @return mixed + */ + abstract public function upload($sourceFile, $desFile, $mode); + /** + * 下载文件 + * @param string $filename + * @param string $localname + * @param string $mode + * @return string + */ + abstract public function download($filename); + /** + * 列出文件列表 + * @param string $dir + * @return array + */ + abstract public function fileList($dir = ''); + /** + * 关闭链接 + * @return boolean + */ + abstract public function close(); + + /** + * 传建文件夹 + * @param string $dir + * @return boolean + */ + abstract public function mkdir($dir); + + /** + * 更改当前目录 + * @param string $dir + * @return boolean + */ + abstract public function changeDir($dir); + + /** + * 获得文件大小 + * @param string $file + * @return boolean + */ + abstract public function size($file); + + /** + * 获得当前路径 + * @return string + */ + abstract protected function pwd(); + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::mkdir() + */ + public function mkdirs($dir, $permissions = 0777) { + $dir = explode('/', WindSecurity::escapeDir($dir)); + $dirs = ''; + $result = false; + $count = count($dir); + for ($i = 0; $i < $count; $i++) { + if (strpos($dir[$i], '.') === 0) continue; + $result = $this->mkdir($dir[$i], $permissions); + $this->changeDir($this->rootPath . $dirs . $dir[$i]); + $dirs .= "$dir[$i]/"; + } + $this->changeDir($this->rootPath); + return $result; + } + + + /** + * 检查文件是否存在 + * @param string $filename + * @return boolean + */ + public function file_exists($filename) { + $directory = substr($filename, 0, strrpos($filename, '/')); + $filename = str_replace("$directory/", '', $filename); + if ($directory) { + $directory = $this->rootPath . $directory . '/'; + } else { + $directory = $this->rootPath; + } + $this->changeDir($directory); + $list = $this->fileList(); + $this->changeDir($this->rootPath); + if (!empty($list) && in_array($filename, $list)) return true; + return false; + } + + + protected function initRootPath() { + $this->rootPath = $this->pwd(); + if ($this->dir) { + $this->rootPath .= trim(str_replace('\\', '/', $this->dir), '/') . '/'; + } + $this->changeDir($this->rootPath); + } + + /** + * 检查文件 + * @param string $filename + * @return boolean + */ + protected function checkFile($filename) { + return (str_replace(array('..', '.php.'), '', $filename) != $filename || preg_match('/\.php$/i', $filename)); + } + + /** + * 获得文件后缀 + * + * @param string + * @return string + */ + protected function getExt($filename){ + if (false === strpos($filename, '.')) return 'txt'; + $x = explode('.', $filename); + return strtolower(end($x)); + } + + /** + * 显示错误信息 + * @param string $str + */ + protected function showError($str, $close = true) { + $close && $this->close(); + exit($str); + } +} \ No newline at end of file diff --git a/wind/component/ftp/WindFtp.php b/wind/component/ftp/WindFtp.php new file mode 100644 index 00000000..49756a6d --- /dev/null +++ b/wind/component/ftp/WindFtp.php @@ -0,0 +1,186 @@ + + * author xiaoxiao + * version 2011-7-29 xiaoxiao + */ +class WindFtp extends AbstractWindFtp { + + /** + * 被动模式是否开启 + * var boolean + */ + private $isPasv = true; + + public function __construct($config = array()) { + $this->connection($config); + } + + private function connection($config = array()) { + $this->initConfig($config); + if (false === ($this->conn = ftp_connect($this->server, $this->port, $this->timeout))) { + $this->showError('The ftp ' . $this->server . ' cann\'t connection!'); + } + if (false == ftp_login($this->conn, $this->user, $this->pwd)) { + $this->showError('Login error: ' . $this->user); + } + if ($this->isPasv) { + ftp_pasv($this->conn, true); + } + $this->initRootPath(); + return true; + } + + /** + * 获得链接 + * return object + */ + private function getFtp() { + if (is_resource($this->conn)) return $this->conn; + $this->connection(); + return $this->conn; + } + + /** + * (non-PHPdoc) + * see AbstractWindFtp::rename() + */ + public function rename($oldName, $newName) { + return ftp_rename($this->getFtp(), $oldName, $newName); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::delete() + */ + public function delete($filename) { + return ftp_delete($this->getFtp(), $filename); + } + + /** + * (non-PHPdoc) + * see AbstractWindFtp::upload() + */ + public function upload($sourceFile, $desFile, $mode = 'auto') { + $mode = $this->getMode($sourceFile, $mode); + if (!in_array(($savedir = dirname($desFile)), array('.', '/'))) { + $this->mkdirs($savedir); + } + $desFile = $this->rootPath . WindSecurity::escapeDir($desFile); + $result = ftp_put($this->getFtp(), $desFile, $sourceFile, $mode); + if (false === $result) return false; + $this->chmod($desFile, 0644); + return $this->size($desFile); + } + + /** + * 从服务器上将文件$filename读取到本地的localname文件中 + * (non-PHPdoc) + * see AbstractWindFtp::download() + */ + public function download($filename, $localname = '', $mode = 'auto') { + $mode = $this->getMode($filename, $mode); + return ftp_get($this->getFtp(), $localname, $filename, $mode); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::fileList() + */ + public function fileList($dir = '') { + return ftp_nlist($this->getFtp(), $dir); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::close() + */ + public function close() { + is_resource($this->conn) && ftp_close($this->conn); + $this->conn = null; + return true; + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::initConfig() + */ + public function initConfig($config) { + if (!$config || !is_array($config)) return false; + parent::initConfig($config); + isset($config['ispasv']) && $this->isPasv = $config['ispasv']; + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::mkdir() + */ + public function mkdir($dir, $permissions = 0777) { + $result = ftp_mkdir($this->getFtp(), $dir); + if (!$result) return false; + return $this->chmod($result, $permissions); + } + + /** + * 赋权限 + * param string $file + * param int $permissions + * return boolean + */ + private function chmod($file, $permissions = 0777) { + return ftp_chmod($this->getFtp(), $permissions, $file); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::pwd() + */ + protected function pwd() { + return ftp_pwd($this->getFtp()) . '/'; + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::changeDir() + */ + public function changeDir($dir) { + return ftp_chdir($this->getFtp(), $dir); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::size() + */ + public function size($file) { + return ftp_size($this->getFtp(), $file); + } + + /** + * 获得后缀和模式 + * param string $filename + * param string $mode + * return string + */ + private function getMode($filename, $mode) { + $ext = $this->getExt($filename); + $mode = strtolower($mode); + if ($mode == 'auto') { + $ext = $this->getExt($filename); + $mode = $this->getModeMap($ext); + } + return (strtolower($mode) == 'ascii') ? FTP_ASCII : FTP_BINARY; + } + + /** + * 获得文件操作模式 + * param string + * return string + */ + private function getModeMap($ext){ + $exts = array('txt', 'text', 'php', 'phps', 'php4', 'js', 'css', + 'htm', 'html', 'phtml', 'shtml', 'log', 'xml'); + return (in_array($ext, $exts)) ? 'ascii' : 'binary'; + } +} \ No newline at end of file diff --git a/wind/component/ftp/WindSocketFtp.php b/wind/component/ftp/WindSocketFtp.php new file mode 100644 index 00000000..1d92e6c5 --- /dev/null +++ b/wind/component/ftp/WindSocketFtp.php @@ -0,0 +1,274 @@ + + * author xiaoxiao + * version 2011-7-29 xiaoxiao + */ +@set_time_limit(1000); +class WindSocketFtp extends AbstractWindFtp { + private $tmpConnection; + + public function __construct($config = array()) { + $this->getConnection($config); + } + + /** + * 获得ftp链接 + * @param array $config + */ + private function getConnection($config) { + $this->initConfig($config); + $errno = 0; + $errstr = ''; + $this->conn = fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout); + if (!$this->conn || !$this->checkcmd()) { + $this->showError('ftp_connect_failed'); + } + stream_set_timeout($this->conn, $this->timeout); + + if (!$this->sendcmd('USER', $this->user)) { + $this->showError('ftp_user_failed'); + } + if (!$this->sendcmd('PASS', $this->pwd)) { + $this->showError('ftp_pass_failed'); + } + + $this->initRootPath(); + return true; + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::pwd() + */ + protected function pwd() { + $this->sendcmd('PWD', '', false); + if (!($path = $this->checkcmd(true)) || !preg_match("/^[0-9]{3} \"(.+?)\"/", $path, $matchs)) { + return '/'; + } + return $matchs[1] . ((substr($matchs[1], -1) == '/') ? '' : '/'); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::upload() + */ + public function upload($localfile, $remotefile, $mode = 'I') { + if ($this->checkFile($localfile)) { + $this->showError("Error:illegal file type!({$localfile})"); + } + if ($this->checkFile($remotefile)) { + $this->showError("Error:illegal file type!({$remotefile})"); + } + if (!in_array(($savedir = dirname($remotefile)), array('.', '/'))) { + $this->mkdirs($savedir); + } + $remotefile = $this->rootPath . WindSecurity::escapeDir($remotefile); + if (!($fp = fopen($localfile, 'rb'))) { + $this->showError("Error:Cannot read file \"$localfile\""); + } + // 'I' == BINARY mode + // 'A' == ASCII mode + $mode != 'I' && $mode = 'A'; + $this->delete($remotefile); + if (!$this->sendcmd('TYPE', $mode)) { + $this->showError('Error:TYPE command failed'); + } + $this->openTmpConnection(); + $this->sendcmd('STOR', $remotefile); + while (!feof($fp)) { + fwrite($this->tmpConnection, fread($fp, 4096)); + } + fclose($fp); + $this->closeTmpConnection(); + + if (!$this->checkcmd()) { + $this->showError('Error:PUT command failed'); + } else { + $this->sendcmd('SITE CHMOD', base_convert(0644, 10, 8) . " $remotefile"); + } + return $this->size($remotefile); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::download() + */ + public function download($localfile, $remotefile = '', $mode = 'I') { + if ($this->checkFile($localfile)) { + $this->showError("Error:illegal file type!({$localfile})"); + } + if ($this->checkFile($remotefile)) { + $this->showError("Error:illegal file type!({$remotefile})"); + } + $mode != 'I' && $mode = 'A'; + if (!$this->sendcmd('TYPE', $mode)) { + $this->showError('Error:TYPE command failed'); + } + $this->openTmpConnection(); + if (!$this->sendcmd('RETR', $remotefile)) { + $this->closeTmpConnection(); + return false; + } + if (!($fp = fopen($localfile, 'wb'))) { + $this->showError("Error:Cannot read file \"$localfile\""); + } + while (!feof($this->tmpConnection)) { + fwrite($fp, fread($this->tmpConnection, 4096)); + } + fclose($fp); + $this->closeTmpConnection(); + + if (!$this->checkcmd()) $this->showError('Error:GET command failed'); + return true; + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::size() + */ + public function size($file) { + $this->sendcmd('SIZE', $file, false); + if (!($size_port = $this->checkcmd(true))) { + $this->showError('Error:Check SIZE command failed'); + } + return preg_replace("/^[0-9]{3} ([0-9]+)\r\n/", "\\1", $size_port); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::delete() + */ + public function delete($file) { + return $this->sendcmd('DELE', $this->rootPath . WindSecurity::escapeDir($file)); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::rename() + */ + public function rename($oldname, $newname) { + if (!in_array(($savedir = dirname($newname)), array('.', '/'))) { + $this->mkdirs($savedir); + } + $oldname = $this->rootPath . WindSecurity::escapeDir($oldname); + $this->sendcmd('RNFR', $oldname); + return $this->sendcmd('RNTO', $newname); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::mkdir() + */ + public function mkdir($dir) { + $base777 = base_convert(0777, 10, 8); + $result = $this->sendcmd('MKD', $dir); + return $this->sendcmd('SITE CHMOD', "$base777 $dir"); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::changeDir() + */ + public function changeDir($dir) { + $dir = (($dir[0] != '/') ? '/' : '') . $dir; + if ($dir !== '/' && substr($dir, -1) == '/') { + $dir = substr($dir, 0, -1); + } + if (!$this->sendcmd('CWD', $dir)) { + $this->showError('ftp_cwd_failed'); + } + return true; + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::fileList() + */ + public function fileList($dir = '') { + $this->openTmpConnection(); + $this->sendcmd('NLST', $dir); + $list = array(); + while (!feof($this->tmpConnection)) { + $list[] = preg_replace('/[\r\n]/', '', fgets($this->tmpConnection, 512)); + } + $this->closeTmpConnection(); + if (!$this->checkcmd(true)) $this->showError('Error:LIST command failed'); + return $list; + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::close() + */ + public function close() { + if (!$this->conn) return false; + if (!$this->sendcmd('QUIT') || !fclose($this->conn)) $this->showError('Error:QUIT command failed', false); + return true; + } + + /** + * 发送命令 + * @param string $cmd + * @param string $args + * @param boolean $check + * @return boolean + */ + private function sendcmd($cmd, $args = '', $check = true) { + !empty($args) && $cmd .= " $args"; + fputs($this->conn, "$cmd\r\n"); + if ($check === true && !$this->checkcmd()) return false; + return true; + } + + /** + * 检查命令状态 + * @param boolean $return + * @return boolean + */ + private function checkcmd($return = false) { + $resp = $rcmd = ''; + $i = 0; + do { + $rcmd = fgets($this->conn, 512); + $resp .= $rcmd; + } while (++$i < 20 && !preg_match('/^\d{3}\s/is', $rcmd)); + + if (!preg_match('/^[123]/', $rcmd)) return false; + return $return ? $resp : true; + } + + /** + * 链接临时句柄 + * @return boolean + */ + private function openTmpConnection() { + $this->sendcmd('PASV', '', false); + if (!($ip_port = $this->checkcmd(true))) { + $this->showError('Error:Check PASV command failed'); + } + if (!preg_match('/[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+/', $ip_port, $temp)) { + $this->showError("Error:Illegal ip-port format($ip_port)"); + } + $temp = explode(',', $temp[0]); + $server_ip = "$temp[0].$temp[1].$temp[2].$temp[3]"; + $server_port = $temp[4] * 256 + $temp[5]; + if (!$this->tmpConnection = fsockopen($server_ip, $server_port, $errno, $errstr, $this->timeout)) { + $this->showError("Error:Cannot open data connection to $server_ip:$server_port
Error:$errstr ($errno)"); + } + stream_set_timeout($this->tmpConnection, $this->timeout); + return true; + } + + /** + * 关闭临时链接对象 + * @return boolean + */ + private function closeTmpConnection() { + return fclose($this->tmpConnection); + } +} +?> \ No newline at end of file diff --git a/wind/component/upload/AbstractWindUpload.php b/wind/component/upload/AbstractWindUpload.php index fc5d0da1..88831130 100644 --- a/wind/component/upload/AbstractWindUpload.php +++ b/wind/component/upload/AbstractWindUpload.php @@ -15,7 +15,23 @@ */ abstract class AbstractWindUpload { + /** + * 是否有错误产生 + * @var boolean + */ protected $hasError = false; + + /** + * 错误信息 + * @var array + */ + protected $errorInfo = array('type' => array(), 'size' => array(), 'upload' => array()); + + /** + * 允许的类型 + * @var array + */ + protected $allowType = array();//允许上传的类型及对应的大小,array(ext=>size); /** * 上传文件 @@ -24,7 +40,56 @@ abstract class AbstractWindUpload { * @param array $allowType 格式为 array(ext=>size) size单位为b * @return array|string */ - public abstract function upload($saveDir, $fileName = '', $allowType = array()); + public function upload($saveDir, $preFileName = '', $allowType = array()) { + $this->setAllowType($allowType); + $uploaddb = array(); + foreach ($_FILES as $key => $value) { + if (is_array($value['name'])) { + $temp = $this->multiUpload($key, $saveDir, $preFileName); + $uploaddb[$key] = isset($uploaddb[$key]) ? array_merge((array)$uploaddb[$key], $temp) : $temp; + } else { + $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName); + } + } + return 1 == count($uploaddb) ? array_shift($uploaddb) : $uploaddb; + } + + /** + * 单个控件 + * 一个表单中只有一个上传文件的控件 + */ + private function simpleUpload($key, $saveDir, $preFileName = '') { + return $this->doUp($key, $_FILES[$key], $saveDir, $preFileName); + } + + /** + * 多个控件 + * 一个表单中拥有多个上传文件的控件 + */ + private function multiUpload($key, $saveDir, $preFileName = '') { + $uploaddb = array(); + $files = $_FILES[$key]; + $num = count($files['name']); + for($i = 0; $i < $num; $i ++) { + $one = array(); + $one['name'] = $files['name'][$i]; + $one['tmp_name'] = $files['tmp_name'][$i]; + $one['error'] = $files['error'][$i]; + $one['size'] = $files['size'][$i]; + $one['type'] = $files['type'][$i]; + if (!($upload = $this->doUp($key, $one, $saveDir, $preFileName))) continue; + $uploaddb[] = $upload; + } + return $uploaddb; + } + + /** + * 执行上传操作 + * @param string $tmp_name + * @param string $filename + * @return bool + */ + abstract protected function postUpload($tmp_name, $filename); /** * 返回是否含有错误 @@ -39,18 +104,93 @@ public function hasError() { * @param string $errorType * @return string|mixed */ - public abstract function getErrorInfo($errorType = ''); + public function getErrorInfo($errorType = '') { + return isset($this->errorInfo[$errorType]) ? $this->errorInfo[$errorType] : $this->errorInfo; + } + + /** + * 设置允许上传的类型 + * @param array $allowType + * @return + */ + public function setAllowType($allowType) { + $allowType && $this->allowType = $allowType; + } /** * 檢查文件是否允許上傳 * @param string $ext - * @param array $allowType * @return bool */ - protected function checkAllowType($ext, $allowType) { - return $allowType ? in_array($ext, (array)$allowType) : true; + protected function checkAllowType($ext) { + $allowType = array_keys((array)$this->allowType); + return $allowType ? in_array($ext, $allowType) : true; } + /** + * 检查上传文件的大小 + * @param string $type + * @param string $uploadSize + * @return bool + */ + protected function checkAllowSize($type, $uploadSize) { + if ($uploadSize < 0) return false; + if (!$this->allowType || !$this->allowType[$type]) return true; + return $uploadSize < $this->allowType[$type]; + } + + + /** + * 获得文件名字 + * @param array $attInfo + * @param string $preFileName + * @return string + */ + protected function getFileName($attInfo, $preFileName = '') { + $fileName = mt_rand(1, 10) . time() . substr(md5(time() . $attInfo['attname'] . mt_rand(1, 10)), 10, 15) . '.' . $attInfo['ext']; + return $preFileName ? $preFileName . $fileName : $fileName; + } + + /** + * 获得保存路径 + * @param string $fileName + * @param string $saveDir + * @return string + */ + protected function getSavePath($fileName, $saveDir) { + return $saveDir ? trim($saveDir, '\\/') . '/' . $fileName : $fileName; + } + + /** + * 判断是否有上传文件 + * @param string $tmp_name + * @return boolean + */ + protected function isUploadFile($tmp_name) { + if (!$tmp_name || $tmp_name == 'none') { + return false; + } elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmp_name) && !is_uploaded_file(str_replace('\\\\', '\\', $tmp_name))) { + return false; + } else { + return true; + } + } + + /** + * 初始化上传的文件信息 + * @param string $key + * @param string $value + * @param string $preFileName 前缀 + */ + protected function initUploadInfo($key, $value, $preFileName, $saveDir) { + $arr = array('attname' => $key, 'name' => $value['name'], 'size' => $value['size'], 'type' => $value['type'], 'ifthumb' => 0, 'fileuploadurl' => ''); + $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1)); + $arr['filename'] = $this->getFileName($arr, $preFileName); + $arr['fileuploadurl'] = $this->getSavePath($arr['filename'], $saveDir); + return $arr; + } + + /** * 判断是否使图片,如果使图片则返回 * @param string $ext; @@ -76,4 +216,34 @@ protected function createFolder($path) { } return true; } + + /** + * 执行上传操作 + * + * @param array $value + * @return array + */ + protected function doUp($key, $value, $saveDir, $preFileName) { + if (!$this->isUploadFile($value['tmp_name'])) return array(); + $upload = $this->initUploadInfo($key, $value, $preFileName, $saveDir); + + if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'])) { + $this->errorInfo['type'][$key][] = $upload; + $this->hasError = true; + return array(); + } + if (!$this->checkAllowSize($upload['ext'], $upload['size'])) { + $upload['maxSize'] = $this->allowType[$upload['ext']]; + $this->errorInfo['size'][$key][] = $upload; + $this->hasError = true; + return array(); + } + if (!($uploadSize = $this->postUpload($value['tmp_name'], $upload['fileuploadurl']))) { + $this->errorInfo['upload'][$key][] = $upload; + $this->hasError = true; + return array(); + } + $upload['size'] = intval($uploadSize); + return $upload; + } } \ No newline at end of file diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index 4e85ef7a..5a9431b3 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -8,134 +8,32 @@ * @package */ class WindFormUpload extends AbstractWindUpload { - private $errorInfo = array('type' => array(), 'size' => array(), 'upload' => array()); - - private $allowType = array();//允许上传的类型及对应的大小,array(ext=>size); public function __construct($allowType = array()) { - $allowType && $this->allowType = $allowType; - } - - /* - * (non-PHPdoc) - * @see AbstractWindUpload::upload() - */ - public function upload($saveDir, $preFileName = '', $allowType = array()) { - $allowType && $this->allowType = (array)$allowType; - $uploaddb = array(); - foreach ($_FILES as $key => $value) { - if (is_array($value['name'])) { - $temp = $this->multiUpload($key, $saveDir, $preFileName); - $uploaddb[$key] = isset($uploaddb[$key]) ? array_merge((array)$uploaddb[$key], $temp) : $temp; - } else { - $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName); - } - } - return 1 == count($uploaddb) ? array_shift($uploaddb) : $uploaddb;/*array($uploaddb, $errorType, $errorSize, $uploadError)*/; - } - - /** - * 单个控件 - * 一个表单中只有一个上传文件的控件 - */ - public function simpleUpload($key, $saveDir, $preFileName = '') { - return $this->doUp($key, $_FILES[$key], $saveDir, $preFileName); - } - - /** - * 多个空间 - * 一个表单中拥有多个上传文件的控件 - */ - public function multiUpload($key, $saveDir, $preFileName = '') { - $uploaddb = array(); - $files = $_FILES[$key]; - $num = count($files['name']); - for($i = 0; $i < $num; $i ++) { - $one = array(); - $one['name'] = $files['name'][$i]; - $one['tmp_name'] = $files['tmp_name'][$i]; - $one['error'] = $files['error'][$i]; - $one['size'] = $files['size'][$i]; - $one['type'] = $files['type'][$i]; - if (!($upload = $this->doUp($key, $one, $saveDir, $preFileName))) continue; - $uploaddb[] = $upload; - } - return $uploaddb; - } - - - /** - * 执行上传操作 - * - * @param array $value - * @return array - */ - private function doUp($key, $value, $saveDir, $preFileName) { - $atc_attachment = ''; - if (!$this->hasUploadedFile($value['tmp_name'])) return array(); - $atc_attachment = $value['tmp_name']; - $upload = $this->initCurrUpload($key, $value); - - if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'], array_keys($this->allowType))) { - $this->errorInfo['type'][$key][] = $upload; - $this->hasError = true; - return array(); - } - if ($upload['size'] < 1 || ($this->allowType && $upload['size'] > $this->allowType[$upload['ext']])) { - $upload['maxSize'] = $this->allowType[$upload['ext']]; - $this->errorInfo['size'][$key][] = $upload; - $this->hasError = true; - return array(); - } - $fileName = $this->getFileName($upload, $preFileName); - $upload['filename'] = $fileName; - $source = $this->getSavePath($fileName, $saveDir); - - if (!$this->postUpload($atc_attachment, $source)) { - $upload['fileuploadurl'] = $source; - $this->errorInfo['upload'][$key][] = $upload; - $this->hasError = true; - return array(); - } - $upload['size'] = ceil(filesize($source) / 1024); - $upload['fileuploadurl'] = $source; - return $upload; + $this->setAllowType($allowType); } - /** + /* * (non-PHPdoc) - * @see AbstractWindUpload::getErrorInfo() + * @see AbstractWindUpload::postUpload() */ - public function getErrorInfo($type = 'all') { - return isset($this->errorInfo[$type]) ? $this->errorInfo[$type] : $this->errorInfo; - } - - /** - * 设置允许上传的类型 - * @param array $allowType - * @return - */ - public function setAllowType($allowType) { - $allowType && $this->allowType = $allowType; - } - - /** - * 执行上传操作 - */ - private function postUpload($tmp_name, $filename) { - if (strpos($filename, '..') !== false || strpos($filename, '.php.') !== false || preg_match("/\.php$/", $filename)) { + protected function postUpload($tmp_name, $filename) { + if (strpos($filename, '..') !== false || strpos($filename, '.php.') !== false || preg_match('/\.php$/', $filename)) { exit('illegal file type!'); } $this->createFolder(dirname($filename)); if (function_exists("move_uploaded_file") && @move_uploaded_file($tmp_name, $filename)) { + @unlink($tmp_name); @chmod($filename, 0777); return true; } elseif (@copy($tmp_name, $filename)) { + @unlink($tmp_name); @chmod($filename, 0777); return true; } elseif (is_readable($tmp_name)) { Wind::import('WIND:component.utility.WindFile'); WindFile::write($filename, WindFile::read($tmp_name)); + @unlink($tmp_name); if (file_exists($filename)) { @chmod($filename, 0777); return true; @@ -144,51 +42,4 @@ private function postUpload($tmp_name, $filename) { return false; } - /** - * 获得保存路径 - * @param string $fileName - * @param string $saveDir - * @return string - */ - private function getSavePath($fileName, $saveDir) { - return rtrim($saveDir, '\\/') . '/' . $fileName; - } - - /** - * 获得文件名字 - * @param array $info - * @param string $preFileName - * @return string - */ - private function getFileName($info, $preFileName = '') { - $fileName = mt_rand(1, 10) . time() . substr(md5(time() . $info['attname'] . mt_rand(1, 10)), 10, 15) . '.' . $info['ext']; - return $preFileName ? $preFileName . $fileName : $fileName; - } - - /** - * 判断是否有上传文件 - * @param string $tmp_name - * @return boolean - */ - private function hasUploadedFile($tmp_name) { - if (!$tmp_name || $tmp_name == 'none') { - return false; - } elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmp_name) && !is_uploaded_file(str_replace('\\\\', '\\', $tmp_name))) { - return false; - } else { - return true; - } - } - - /** - * 初始化上传的文件信息 - * @param string $key - * @param string $value - */ - private function initCurrUpload($key, $value) { - $arr = array('attname' => $key, 'name' => $value['name'], 'size' => intval($value['size']), 'type' => 'zip', 'ifthumb' => 0, 'fileuploadurl' => ''); - $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1)); - return $arr; - } - } \ No newline at end of file diff --git a/wind/component/upload/WindFtpUpload.php b/wind/component/upload/WindFtpUpload.php new file mode 100644 index 00000000..a44f712c --- /dev/null +++ b/wind/component/upload/WindFtpUpload.php @@ -0,0 +1,56 @@ + + * @author xiaoxiao + * @version 2011-7-29 xiaoxiao + */ +class WindFtpUpload extends AbstractWindUpload { + private $config = array(); + + private $ftp = null; + + public function __construct($config) { + $this->setConfig($config); + } + + /** + * (non-PHPdoc) + * @see AbstractWindUpload::postUpload() + */ + protected function postUpload($tmp_name, $filename) { + $ftp = $this->getFtpConnection(); + if (!($size = $ftp->upload($tmp_name, $filename))) return false; + @unlink($tmp_name); + return $size; + } + + /** + * 设置配置文件 + * @param array $config + * @return bool + */ + public function setConfig($config) { + if (!is_array($config)) return false; + $this->config = $config; + return true; + } + + /** + * 获得ftp链接对象 + * @return AbstractWindFtp + */ + private function getFtpConnection() { + if (is_object($this->ftp)) return $this->ftp; + if (function_exists('ftp_connect')) { + Wind::import("COM:ftp.WindFtp"); + $this->ftp = new WindFtp($this->config); + return $this->ftp; + } + Wind::import("COM:ftp.WindSocketFtp"); + $this->ftp = new WindSocketFtp($this->config); + return $this->ftp; + } +} \ No newline at end of file From b297c579fe50eb85928e9300dbb9bb7ae3c269cd Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 4 Aug 2011 07:26:07 +0000 Subject: [PATCH 0241/1065] =?UTF-8?q?ftp=E4=B8=8A=E4=BC=A0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2301 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/AbstractWindUpload.php | 2 +- wind/component/upload/WindFormUpload.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wind/component/upload/AbstractWindUpload.php b/wind/component/upload/AbstractWindUpload.php index 88831130..baf5a346 100644 --- a/wind/component/upload/AbstractWindUpload.php +++ b/wind/component/upload/AbstractWindUpload.php @@ -158,7 +158,7 @@ protected function getFileName($attInfo, $preFileName = '') { * @return string */ protected function getSavePath($fileName, $saveDir) { - return $saveDir ? trim($saveDir, '\\/') . '/' . $fileName : $fileName; + return $saveDir ? rtrim($saveDir, '\\/') . '/' . $fileName : $fileName; } /** diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php index 5a9431b3..1d7d1445 100644 --- a/wind/component/upload/WindFormUpload.php +++ b/wind/component/upload/WindFormUpload.php @@ -25,18 +25,18 @@ protected function postUpload($tmp_name, $filename) { if (function_exists("move_uploaded_file") && @move_uploaded_file($tmp_name, $filename)) { @unlink($tmp_name); @chmod($filename, 0777); - return true; + return filesize($filename); } elseif (@copy($tmp_name, $filename)) { @unlink($tmp_name); @chmod($filename, 0777); - return true; + return filesize($filename); } elseif (is_readable($tmp_name)) { Wind::import('WIND:component.utility.WindFile'); WindFile::write($filename, WindFile::read($tmp_name)); @unlink($tmp_name); if (file_exists($filename)) { @chmod($filename, 0777); - return true; + return filesize($filename); } } return false; From 0ad9aeebb1ca84ccbe66f075db6e77e7f52d1a1a Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 5 Aug 2011 03:50:49 +0000 Subject: [PATCH 0242/1065] =?UTF-8?q?=E4=BB=A3=E7=90=86=E7=B1=BB=EF=BC=9A?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E9=93=BE=E9=87=8D=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2302 18ba2127-5a84-46d4-baec-3457e417f034 --- .../filter/WindHandlerInterceptorChain.php | 14 +++++++++++++- wind/core/factory/proxy/WindClassProxy.php | 16 ++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/wind/component/filter/WindHandlerInterceptorChain.php b/wind/component/filter/WindHandlerInterceptorChain.php index 55ec188d..e95a8861 100644 --- a/wind/component/filter/WindHandlerInterceptorChain.php +++ b/wind/component/filter/WindHandlerInterceptorChain.php @@ -9,7 +9,7 @@ class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); - private $_state = true; + protected $_state = true; /** * 设置回调方法 @@ -72,5 +72,17 @@ public function addInterceptors($interceptors) { else $this->_interceptors[] = $interceptors; } + + /** + * 重置初始化信息 + * @return boolean + */ + public function reset() { + $this->_interceptors = array(); + $this->_callBack = null; + $this->_args = array(); + $this->_state = true; + return true; + } } ?> \ No newline at end of file diff --git a/wind/core/factory/proxy/WindClassProxy.php b/wind/core/factory/proxy/WindClassProxy.php index a383e601..03430529 100644 --- a/wind/core/factory/proxy/WindClassProxy.php +++ b/wind/core/factory/proxy/WindClassProxy.php @@ -10,6 +10,7 @@ */ class WindClassProxy implements IWindClassProxy { private $_interceptorChain = 'COM:filter.WindHandlerInterceptorChain'; + private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; @@ -128,12 +129,15 @@ protected function initClassProxy($targetObject, $args = array()) { * @return */ private function _getInterceptorChain($event = '') { - $chain = Wind::import($this->_interceptorChain); - $interceptorChain = WindFactory::createInstance($chain); - if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { - return $interceptorChain; - } else - throw new WindException('unable to create interceptorChain.'); + if (null === $this->_interceptorChainObj) { + $chain = Wind::import($this->_interceptorChain); + $interceptorChain = WindFactory::createInstance($chain); + if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { + $this->_interceptorChainObj = $interceptorChain; + } else throw new WindException('unable to create interceptorChain.'); + } + $this->_interceptorChainObj->reset(); + return $this->_interceptorChainObj; } /** From 5b34fab7b36d6380c1483f00c93f0e46e7c7e982 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 8 Aug 2011 03:31:07 +0000 Subject: [PATCH 0243/1065] =?UTF-8?q?ftp=E4=B8=8A=E4=BC=A0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2303 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/ftp/AbstractWindFtp.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/wind/component/ftp/AbstractWindFtp.php b/wind/component/ftp/AbstractWindFtp.php index 22a68b2a..31ef366c 100644 --- a/wind/component/ftp/AbstractWindFtp.php +++ b/wind/component/ftp/AbstractWindFtp.php @@ -100,9 +100,11 @@ abstract public function size($file); */ abstract protected function pwd(); - /* - * (non-PHPdoc) - * @see AbstractWindFtp::mkdir() + /** + * 级联创建文件夹 + * @param string $dir + * @param string $permissions + * @return boolean */ public function mkdirs($dir, $permissions = 0777) { $dir = explode('/', WindSecurity::escapeDir($dir)); @@ -140,7 +142,9 @@ public function file_exists($filename) { return false; } - + /** + * 初始化根目录信息 + */ protected function initRootPath() { $this->rootPath = $this->pwd(); if ($this->dir) { From 6d6f0b0a7c26e5fcc6894d72f27970a68538b4b4 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 9 Aug 2011 07:05:37 +0000 Subject: [PATCH 0244/1065] =?UTF-8?q?RESOLVED=20-=20bug=20153:=20bstractWi?= =?UTF-8?q?ndRouter->doParse()=20bug:=E5=BD=93=E4=BD=BF=E7=94=A8=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E9=85=8D=E7=BD=AE=E7=9A=84module=E6=98=AF=E6=8C=87?= =?UTF-8?q?=E5=90=91=E9=94=99=E8=AF=AF=E7=9A=84module=E9=85=8D=E7=BD=AE=20?= =?UTF-8?q?http://bugs.phpwind-inc.com/show=5Fbug.cgi=3Fid=3D153?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2304 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindSystemConfig.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index b719c276..ddff8e4f 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -130,7 +130,7 @@ public function getModules($name = '') { */ public function getModuleViewClassByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('view', 'class', $default, $module); + return $module ? $this->getConfig('view', 'class', $default, $module) : ''; } /** @@ -140,7 +140,7 @@ public function getModuleViewClassByModuleName($name, $default = '') { */ public function getModuleViewConfigByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('view', 'config', $default, $module); + return $module ? $this->getConfig('view', 'config', $default, $module) : ''; } /** @@ -151,7 +151,7 @@ public function getModuleViewConfigByModuleName($name, $default = '') { */ public function getModuleErrorHandlerByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('error-handler', '', $default, $module); + return $module ? $this->getConfig('error-handler', '', $default, $module) : ''; } /** @@ -161,7 +161,7 @@ public function getModuleErrorHandlerByModuleName($name, $default = '') { */ public function getModuleControllerPathByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('controller-path', '', $default, $module); + return $module ? $this->getConfig('controller-path', '', $default, $module) : ''; } /** @@ -171,7 +171,7 @@ public function getModuleControllerPathByModuleName($name, $default = '') { */ public function getModuleControllerSuffixByModuleName($name, $default = '') { $module = $this->getConfig('modules', $name); - return $this->getConfig('controller-suffix', '', $default, $module); + return $module ? $this->getConfig('controller-suffix', '', $default, $module) : ''; } /** From d4fa477ba87b1ffdcc188e6aa7407417b2c8642c Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 9 Aug 2011 07:53:42 +0000 Subject: [PATCH 0245/1065] =?UTF-8?q?NEW=20-=20bug=20154:=20=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=BA=94=E7=94=A8=E9=85=8D=E7=BD=AE=E4=B8=AD=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E7=9A=84=E8=B7=AF=E7=94=B1=E9=85=8D=E7=BD=AE=E4=B8=8D?= =?UTF-8?q?=E8=B5=B7=E4=BD=9C=E7=94=A8=20http://bugs.phpwind-inc.com/show?= =?UTF-8?q?=5Fbug.cgi=3Fid=3D154?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2305 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/AbstractWindRouter.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/wind/component/router/AbstractWindRouter.php b/wind/component/router/AbstractWindRouter.php index 29b90dca..8a64b376 100644 --- a/wind/component/router/AbstractWindRouter.php +++ b/wind/component/router/AbstractWindRouter.php @@ -63,6 +63,9 @@ public function doParse() { $this->reParse = false; } $_moduleName = $this->getModule(); + if (!$this->getSystemConfig()->getModules($_moduleName)) { + throw new WindException('[core.roter.AbstractWindRouter.doParse] module error: error module :' . $_moduleName); + } if (!strcasecmp($this->getController(), 'windError')) { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log( @@ -169,5 +172,15 @@ public function setController($controller) { public function reParse() { $this->reParse = true; } + + /* + * (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); + $usrConfig && $config = array_merge($config, $usrConfig); + parent::setConfig($config); + } } \ No newline at end of file From bca0709696d4a3f831f46b6833f159ee565fd497 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 9 Aug 2011 08:28:51 +0000 Subject: [PATCH 0246/1065] urlRewrite git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2306 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/WindUrlBasedRouter.php | 8 +- wind/core/web/WindUrlHelper.php | 447 +++++++++---------- 2 files changed, 213 insertions(+), 242 deletions(-) diff --git a/wind/component/router/WindUrlBasedRouter.php b/wind/component/router/WindUrlBasedRouter.php index 2256706d..b34ee305 100644 --- a/wind/component/router/WindUrlBasedRouter.php +++ b/wind/component/router/WindUrlBasedRouter.php @@ -27,6 +27,8 @@ class WindUrlBasedRouter extends AbstractWindRouter { * @see AbstractWindRouter::parse() */ public function parse() { + $urlHelper = $this->getSystemFactory()->getInstance(COMPONENT_URLHELPER); + $urlHelper->parseUrl(); $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->getModule())); $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->getController())); $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->getAction())); @@ -36,9 +38,9 @@ public function parse() { * @see AbstractWindRouter::buildUrl() */ public function buildUrl() { - $module = $this->getUrlParamValue(self::URL_RULE_MODULE); - $controller = $this->getUrlParamValue(self::URL_RULE_CONTROLLER); - $action = $this->getUrlParamValue(self::URL_RULE_ACTION); + $module = $this->getConfig(self::URL_RULE_MODULE, self::URL_PARAM); + $controller = $this->getConfig(self::URL_RULE_CONTROLLER, self::URL_PARAM); + $action = $this->getConfig(self::URL_RULE_ACTION, self::URL_PARAM); $url = '?' . $module . '=' . $this->getModule(); $url .= '&' . $controller . '=' . $this->getController(); $url .= '&' . $action . '=' . $this->getAction(); diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php index 15671f8c..4ac12cf2 100644 --- a/wind/core/web/WindUrlHelper.php +++ b/wind/core/web/WindUrlHelper.php @@ -6,19 +6,14 @@ * @package */ class WindUrlHelper extends WindModule { - const URL_PATTERN = 'url-pattern'; - const ROUTE_SUFFIX = 'route-suffix'; - const ROUTE_PARAM = 'route-param'; - const REWRITE = false; - const ROUTE_SEPARATOR = '_'; - protected $routeSuffix = ''; - protected $routeParam = ''; - protected $urlPattern = ''; - protected $windRouter = null; - - public function isRewrite() { - return self::REWRITE; - } + private $urlPatttern = ''; + private $keyValueSep = ''; + private $separator = ''; + private $suffix = ''; + private $isRewrite = 0; + private $keyPrefix = ''; + private $baseUrl = ''; + private $patterns = array(); /** * 解析Url @@ -28,15 +23,33 @@ public function isRewrite() { * 同时设置到超全局变量$_GET中 */ public function parseUrl() { - if ((($uri = $this->request->getServer('QUERY_STRING')) == '') || !$this->isRewrite()) return; - if (($pattern = $this->getUrlPattern()) == '') return; - $seperator = isset($pattern[1]) ? $pattern[1] : $pattern[0]; - $uri = explode($seperator, $uri); - if (strcasecmp($pattern, "=&") != 0) $params = $this->parseUrlToParams($uri, $seperator, $pattern[0]); - $_GET = array_merge($_GET, $params); - $this->matchRouter(array_pop($uri)); + if (!$this->isRewrite()) return; + $url = array(); + if ($this->getRequest()->getServer('SERVER_PROTOCOL')) {//http协议 + $pathInfo = $this->getRequest()->getServer('PATH_INFO'); + if ($pathInfo && !empty($pathInfo)) { + $url = rtrim($pathInfo, $this->suffix); + } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { + $scriptName = $this->getRequest()->getScriptUrl(); + if (0 === strpos($url, $scriptName)) { + $url = substr($url, strlen($scriptName)); + } + $url = rtrim($url, $this->suffix); + } + $url && $params = $this->doParserUrl(trim($url, '?/')); + } else {// 命令行下 + $i = 0; + $args = $this->getRequest()->getServer('argv', array()); + while (isset($args[$i]) && isset($args[$i + 1])) { + $params[$args[$i]] = $args[$i + 1]; + $i += 2; + } + } + foreach ($params as $k => $v) { + !isset($_GET[$k]) && $_GET[$k] = $v; + } } - + /** * 构造返回Url地址 * @@ -48,100 +61,165 @@ public function parseUrl() { * @return string */ public function createUrl($action, $controller, $params = array()) { - $action && $this->getWindRouter()->setAction($action); - list($_c, $_m) = WindHelper::resolveController($controller); - $_c && $this->getWindRouter()->setController($_c); - $_m && $this->getWindRouter()->setModule($_m); - $url = $this->getWindRouter()->buildUrl(); - $server = $this->getUrlServer(); - if ($this->isRewrite()) { - $server = substr($server, 0, strrpos($server, '/')); - $url = $server . $this->buildRewriteURL($params, $url); - } else { - $url = $server . $url . '&' . $this->buildUrl($params); + list($controller, $module) = WindHelper::resolveController($controller); + $urlRouter = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); + if (!$this->isRewrite()) { + $urlRouter->setAction($action); + $urlRouter->setController($controller); + $urlRouter->setModule($module); + return $this->baseUrl . '/' . $urlRouter->buildUrl() . '&' . http_build_query($params, '', '&'); } - return $url; + $m = $urlRouter->getConfig('module', WindUrlBasedRouter::URL_PARAM); + $c = $urlRouter->getConfig('controller', WindUrlBasedRouter::URL_PARAM); + $a = $urlRouter->getConfig('action', WindUrlBasedRouter::URL_PARAM); + $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); + return $this->buildRewriteUrl($params); } - - /** - * 返回域名及请求路径 - * - * @param boolean $hasPath 是否含有路径信息 - * @return string + + /** + * 构造重写的url + * @param string $m + * @param string $c + * @param string $action + * @param string $params + * @return string + */ + private function buildRewriteUrl($params) { + $url = $this->urlPatttern; + foreach ($this->patterns as $key => $value) { + if ('*' == $value[0]) { + $url = str_replace($value, $this->buildCommonKeys($params), $url); + } else { + $url = $this->buildVars($value, $params, $url); + } + } + return $this->baseUrl . '/' . $url . $this->suffix; + } + + /** + * 构建变量 不是* + * + * @param string $value + * @param array $params + * @param string $url + * @return string + */ + private function buildVars($value, &$params, $url) { + $keys = explode($this->keyValueSep, $value); + $values = array(); + foreach ($keys as $v) { + if (!isset($params[$v])) continue; + $values[] = $params[$v]; + unset($params[$v]); + } + return str_replace($keys, $values, $url); + } + + /** + * 构建rewriteurl的参数部分 + * @param array $params + * @param string $parentKey + * @param boolean $first 只有第一级的变量才加前缀 + * @return string */ - private function getUrlServer($hasPath = true) { - list($protocol, ) = explode('/', $this->request->getProtocol()); - $protocol = strtolower($protocol) . '://' . $this->request->getServer('SERVER_NAME'); - ($hasPath) && $protocol .= $this->request->getServer('PHP_SELF'); - return $protocol; + private function buildCommonKeys($params, $parentKey = '', $first = true) { + $tmp = array(); + foreach ($params as $k => $v) { + if (is_int($k) && $this->keyPrefix != null && $first) { + $k = urlencode($this->keyPrefix . $k); + } + if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; + if (is_array($v)) { + array_push($tmp, $this->buildCommonKeys($v, $k, false)); + } else { + array_push($tmp, $k . $this->keyValueSep . urlencode($v)); + } + } + return implode($this->separator, $tmp); } + /** * 执行匹配 + * patterns中的匹配模式去匹配url中的信息 + * urlPatterns中可以根据需求将mca进行组合配置。 + * + m-c-a/* + htm + / + - + myvar_ + 1 + + * url-pattern中:*匹配表示其他的变量信息 + * 用户也可以将自己的其他信息添加到格式中比如m/c-a/tid/* + * suffix : url的后缀 + * separator: 变量分隔符 + * key-value-sep: key和value的分隔符,默认和separator一致 + * key-prefix: 数字索引的前缀 + * is-rewrite: 是否采用rewrite机制 * - * 获得匹配的结果 - * 对于路由信息, - * 如果没有路由信息,则表示缺省 - * 如果路由中只有一个值,则代表缺省的是m和a - * 如果路由中只有两个值,则代表缺省的是m + * 遍历url模式:采用separator配置的分隔符获得该模式数组 + * 如果模式是*,则代表该位置开始往后为为传递的变量信息 + * 如果模式不是*,则代表该位置为特殊模式。 + * 如果含有key-value-sep配置的分隔符: 则分别对url中相同key下的值和模式中的值分别做分割,对应的模式下获得的数组作为key,url中获得数组作为value + * 如果不含:则该值就作为Key,url对应位置上的值作为value * - * @param string 待分析匹配的路由信息 + * @param string 待分析匹配的路径信息 + * @return array */ - private function matchRouter($mca) { - if (strrpos($mca, '.' . $this->getRouteSuffix()) === false) return; - $mca = trim(rtrim($mca, '.' . $this->getRouteSuffix())); - if ($mca == '') return; - $mca = explode(self::ROUTE_SEPARATOR, $mca); - $m = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_MODULE); - $c = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_CONTROLLER); - $a = $this->getUrlParamConfig(WindUrlBasedRouter::URL_RULE_ACTION); - if (count($mca) == 1) { - $_GET[$c] = $mca[0]; - } elseif (count($mca) == 2) { - $_GET[$c] = $mca[0]; - $_GET[$a] = $mca[1]; - } else { - ($mca[0]) && $_GET[$m] = $mca[0]; - ($mca[1]) && $_GET[$c] = $mca[1]; - ($mca[2]) && $_GET[$a] = $mca[2]; + private function doParserUrl($url) { + if (is_string($url)) { + if (!$url || false === strrpos($url, $this->separator)) return array(); + $url = explode($this->separator, trim($url, $this->separator)); + } + + $vars = array(); + foreach ($this->patterns as $key => $value) { + if ('*' == $value[0]) $this->parseCommonKey($key, $url, $vars); + else { + if (!isset($url[$key])) continue; + if (false === strrpos($value, $this->keyValueSep)) { + $vars[$value] = $url[$key]; + continue; + } + $keys = explode($this->keyValueSep, $value); + $values = explode($this->keyValueSep, $url[$key]); + $vars = array_merge($vars, array_combine($keys, $values)); + } } - return; + return $vars; } - - /** - * 解析uri参数成key-value关联数组形式 - * - * 如果key-value和参数之间,两种的分隔符相同,则采用配对匹配的模式,如果不相同,则对每一对key-value的值进行再次解析 - * - * 如果key是字符串,则直接赋值, - * 如果key是数组: - * 如果key的数组没有键值,则采用数组索引自增的方式 - * 如果key的数组拥有键值,则将该键值作为key来传递 - * - * @param array $url - * @param string $seprator - * @param string $keyAsValue - * @return array + + /** + * 解析url普通参数 + * 如果separator和key-value-sep配置相同:则采用每两个元素为一对key-value的规则获得变量 + * 如果不相同:则将会以每个元素为key-value的组合,之间的分隔符以key-value-sep划分,如果没有该分隔符,则默认该值的索引为数字索引。 + * 如果为没有分隔符:则该值索引以数字索引给出,同时该数字索引将会根据用户是否配置key前缀key-prefix来给出key。 + * 如果有分隔符:则该值将会用分隔符分割获得的两个值来分别作为key和value. + * @param int $key + * @param array $urlParams + * @param array $params */ - private function parseUrlToParams($url, $seprator = '', $keyAsValue = '=') { - $params = array(); - if ($seprator == $keyAsValue) { - $n = count($url); - for ($i = 0; $i < $n / 2; $i++) { - $k = 2 * $i; - $v = $k + 1; - if (isset($url[$v])) { - $this->parseKey($params, $url[$k], $url[$v]); + private function parseCommonKey($key, $urlParams, &$params) { + $pos = 0; + while (isset($urlParams[$key])) { + if ($this->separator == $this->keyValueSep) { + if (isset($urlParams[$key+1])) { + $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); + $key += 2; } + continue; } - return $params; - } - foreach ((array) $url as $key => $value) { - if (strpos($value, $keyAsValue) === false) continue; - list($key, $value) = explode($keyAsValue, $value); - $this->parseKey($params, $key, $value); + if (false === strrpos($urlParams[$key], $this->keyValueSep)) { + $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); + $pos ++; + } else { + list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); + $this->parseKey($params, $k, urldecode($v)); + } + $key += 1; } - return $params; } /** @@ -171,89 +249,6 @@ private function parseKey(&$params, $key, $value) { } } - /** - * 获得配置 - * - * 获得用户对于module controller action的对应配置(url-parmar) - * - * @param string $type 查找类型(module,controller,action); - * @param string $type 返回用户对应的设置,如果不存在则返回本身 - */ - private function getUrlParamConfig($type) { - $_config = $this->getWindRouter()->getConfig(WindUrlBasedRouter::URL_RULE); - if ($_param = $this->getConfig($type, WindUrlBasedRouter::URL_PARAM, $_config)) { - return $_param; - } - return $type; - } - - /** - * 获得分割符 - * - * @return array array(key-value分割符,参数之间分隔符) - */ - private function getSeparator() { - (($pattern = $this->getUrlPattern()) == '') && $pattern = '=&'; - $separator = isset($pattern[1]) ? $pattern[1] : $pattern[0]; - return array($pattern[0], $separator); - } - - /** - * 构造重写的url - * - * @param array $params - * @param string $routerInfo - * @return string 返回重写后的url - */ - private function buildRewriteURL($params, $routerInfo) { - $routerInfo = $this->parseUrlToParams(explode('&', trim($routerInfo, '?')), '&', '='); - $routerInfo = implode(self::ROUTE_SEPARATOR, $routerInfo) . '.' . $this->getRouteSuffix(); - $separator = $this->getSeparator(); - if (empty($params)) return $separator[1] . $routerInfo; - $url = ''; - foreach ((array) $params as $key => $value) { - $url .= $this->buildKey($key, $value, $separator[0], $separator[1]) . $separator[1]; - } - return $separator[1] . $url . $routerInfo; - } - - /** - * 构造url的辅助函数 - * - * 支持数组的传递(建议最多传递一维) - * - * @param string $parentKey key - * @param string $parentValue key对应的值 - * @param string $keyAsValue key-value的分隔符 - * @param string $separator 参数之间的分割符 - * @param boolean $flag 标志 - * @return string - */ - private function buildKey($parentKey, $parentValue, $keyAsValue, $separator, $flag = false) { - $flag && $parentKey = is_numeric($parentKey) ? '[]' : '[' . $parentKey . ']'; - if (!is_array($parentValue)) return $parentKey . $keyAsValue . urlencode($parentValue); - $keys = array(); - foreach ($parentValue as $key => $value) { - $keys[] = $parentKey . $this->buildKey($key, $value, $keyAsValue, $separator, true); - } - return implode($separator, $keys); - } - - /** - * 构造普通的url - * - * @param array $params - * @return string - */ - private function buildUrl($params) { - if (empty($params)) return ''; - $url = ''; - foreach ((array) $params as $key => $value) { - $url .= $this->buildKey($key, $value, '=', '&', false) . '&'; - } - return trim($url, '&'); - } - /** * 检查Url地址的正确性,并返回正确的URL地址 * @@ -268,70 +263,44 @@ public function checkUrl($url) { if (false === $pos1) return $protocal . '://' . ltrim($url, '/'); return $url; } - - /** - * @return the $routeSuffix - */ - public function getRouteSuffix() { - if ($this->routeSuffix === '') { - $this->routeSuffix = $this->getConfig(self::ROUTE_SUFFIX, WindSystemConfig::VALUE); - } - return $this->routeSuffix; - } - - /** - * @return the $routeParam - */ - public function getRouteParam() { - if ($this->routeParam === '') { - $this->routeParam = $this->getConfig(self::ROUTE_PARAM, WindSystemConfig::VALUE); - } - return $this->routeParam; - } - - /** - * @return the $urlPattern - */ - public function getUrlPattern() { - if ($this->urlPattern === '') { - $this->urlPattern = $this->getConfig(self::URL_PATTERN, WindSystemConfig::VALUE); - } - return $this->urlPattern; - } - - /** - * @param field_type $routeSuffix - */ - public function setRouteSuffix($routeSuffix) { - $this->routeSuffix = $routeSuffix; - } - - /** - * @param field_type $routeParam - */ - public function setRouteParam($routeParam) { - $this->routeParam = $routeParam; - } - - /** - * @param field_type $urlPattern + + /* + * (non-PHPdoc) + * @see WindModule::setConfig() */ - public function setUrlPattern($urlPattern) { - $this->urlPattern = $urlPattern; + public function setConfig($config) { + $usrConfig = $this->getSystemConfig()->getConfig('router', 'rewrite'); + $usrConfig && $config = array_merge($config, $usrConfig); + parent::setConfig($config); + $this->urlPatttern = $this->getConfig('url-pattern'); + $this->separator = $this->getConfig('separator'); + $this->keyValueSep = $this->getConfig('key-value-sep'); + $this->keyValueSep == "" && $this->keyValueSep = $this->separator; + $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); + $this->isRewrite = $this->getConfig('is-rewrite'); + $this->keyPrefix = $this->getConfig('key-prefix'); + $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); + $this->getBaseUrl(); } - + /** - * @return AbstractWindRouter $windRouter + * 返回域名及请求路径 + * + * @return string */ - public function getWindRouter() { - return $this->windRouter; + private function getBaseUrl() { + $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); + if (!$this->isRewrite()) + $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } - + /** - * @param field_type $windRouter + * 是否开启重写 + * + * @return boolean */ - public function setWindRouter($windRouter) { - $this->windRouter = $windRouter; + public function isRewrite() { + return $this->isRewrite == '1' || $this->isRewrite == 'true'; } } ?> \ No newline at end of file From 48143e6c4ebe102cb9d21d25f9280bdbb2b1066a Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 9 Aug 2011 08:38:25 +0000 Subject: [PATCH 0247/1065] urlRewrite git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2307 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 46 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 1c377efe..30b6ddbe 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -35,15 +35,19 @@
- - - - + - - - + + m/c-a/* + + htm + + / + + - + + myvar_ + 1 @@ -54,8 +58,8 @@ template htm compile.template - false - + true + viewCache @@ -69,7 +73,7 @@ + scope='prototype'> @@ -79,12 +83,26 @@ - - + + + compile + default + + cache + + key + + value + + expire + + - data + compile.cache + php + 10 From 360a899fe0bfb85e9c4373b835a8415b0c1e0f10 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 9 Aug 2011 08:45:07 +0000 Subject: [PATCH 0248/1065] =?UTF-8?q?urlRewrite=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2308 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindUrlHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php index 4ac12cf2..7870d283 100644 --- a/wind/core/web/WindUrlHelper.php +++ b/wind/core/web/WindUrlHelper.php @@ -170,7 +170,7 @@ private function buildCommonKeys($params, $parentKey = '', $first = true) { */ private function doParserUrl($url) { if (is_string($url)) { - if (!$url || false === strrpos($url, $this->separator)) return array(); + if (!$url) return array(); $url = explode($this->separator, trim($url, $this->separator)); } From f6d5e7c90a68a29bf15c4116333a58b73a1b66a3 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 10 Aug 2011 09:48:15 +0000 Subject: [PATCH 0249/1065] =?UTF-8?q?mca=E4=B8=BA=E7=A9=BA=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5=E4=B8=8B=EF=BD=9E=E9=9C=80=E8=A6=81=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2309 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/WindUrlBasedRouter.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/component/router/WindUrlBasedRouter.php b/wind/component/router/WindUrlBasedRouter.php index b34ee305..ed06ef14 100644 --- a/wind/component/router/WindUrlBasedRouter.php +++ b/wind/component/router/WindUrlBasedRouter.php @@ -57,7 +57,8 @@ public function buildUrl() { private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, self::URL_PARAM)) { $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE, $defaultValue); - return $this->getRequest()->getRequest($_param, $defaultValue); + $tmp = $this->getRequest()->getRequest($_param, $defaultValue); + return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } From 4d9c3640524053937dd643ce61226d1d1aabc641 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 10 Aug 2011 11:17:19 +0000 Subject: [PATCH 0250/1065] =?UTF-8?q?urlRewrite=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2310 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindUrlHelper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php index 7870d283..1b6ccc39 100644 --- a/wind/core/web/WindUrlHelper.php +++ b/wind/core/web/WindUrlHelper.php @@ -36,7 +36,8 @@ public function parseUrl() { } $url = rtrim($url, $this->suffix); } - $url && $params = $this->doParserUrl(trim($url, '?/')); + $url = trim($url, '?/'); + $url && $params = $this->doParserUrl($url); } else {// 命令行下 $i = 0; $args = $this->getRequest()->getServer('argv', array()); From 7123b7a81faa659a0339dafe4127de7cf82e4432 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 10 Aug 2011 11:17:56 +0000 Subject: [PATCH 0251/1065] =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=B1=BB=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=B0=B4=E5=8D=B0=EF=BC=8C?= =?UTF-8?q?=E7=95=A5=E7=BC=A9=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2311 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/utility/WindImage.php | 303 +++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 wind/component/utility/WindImage.php diff --git a/wind/component/utility/WindImage.php b/wind/component/utility/WindImage.php new file mode 100644 index 00000000..25935081 --- /dev/null +++ b/wind/component/utility/WindImage.php @@ -0,0 +1,303 @@ + + * @author xiaoxiao + * @version 2011-8-10 xiaoxiao + */ +class WindImage { + + /** + * 生成略缩图 + * + * @param string $srcFile 源图片 + * @param string $dstFile 略缩图保存位置 + * @param int $dstW 略缩图宽度 + * @param string $dstH 略缩图高度 + * @param string $isProportion 略缩图是否等比略缩 + * @return array|boolean + */ + public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { + if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; + list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); + if (!$imagecreate) return false; + $imgwidth = $minitemp['width']; + $imgheight = $minitemp['height']; + + $srcX = $srcY = $dstX = $dstY =0; + if (!$isProportion) { + $dsDivision = $imgheight / $imgwidth; + $fixDivision = $dstH / $dstW; + if ($dsDivision > $fixDivision) { + $tmp = $imgwidth * $fixDivision; + $srcY = round(($imgheight - $tmp) / 2); + $imgheight = $tmp; + } else { + $tmp = $imgheight / $fixDivision; + $srcX = round(($imgwidth - $tmp) / 2); + $imgwidth = $tmp; + } + } + $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); + + if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { + $black = imagecolorallocate($thumb, 0, 0, 0); + imagecolortransparent($thumb, $black); + } + $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); + self::makeImg($minitemp['type'], $thumb, $dstFile); + imagedestroy($thumb); + return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); + } + + /** + * 给图片制作水印 + * 水印的位置可以为: + * array(0 => '随机位置', 1 => '顶部居左', 2 => '顶部居中', 3 => '顶部居右', 4 => '底部居左', 5 => '底部居中', 6 => '底部居右', 7 => '中心位置') + * + * @param string $source + * @param int|array $waterPos 水印的位置 + * @param string $waterImg 图片水印:水印图片的位置 + * @param string $waterText 水印的文字 + * @param array $attribute 文字水印的属性,只对文字水印有效 + * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小') + * + * @param string $waterPct 水印透明度,从0到100,0完全透明,100完全不透明 + * @param string $waterQuality 图片质量--jpeg + * @param string $dstsrc 目标文件位置 + * @return boolean + */ + public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { + $sourcedb = $waterdb = array(); + if (false === ($sourcedb = self::getImgInfo($source))) return false; + if (!$waterImg && !$waterText) return false; + imagealphablending($sourcedb['source'], true); + if ($waterImg) { + $waterdb = self::getImgInfo($waterImg); + list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); + if ($waterdb['type'] == 'png') { + $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); + imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); + imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); + $sourcedb['source'] = $tmp; + } else { + imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); + } + } elseif ($waterText) { + list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); + empty($waterFont) && $waterFont = 12; + $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); //取得使用 TrueType 字体的文本的范围 + $waterdb['width'] = $temp[2] - $temp[6]; + $waterdb['height'] = $temp[3] - $temp[7]; + unset($temp); + list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); + if (strlen($color) != 7) return false; + $R = hexdec(substr($color, 1, 2)); + $G = hexdec(substr($color, 3, 2)); + $B = hexdec(substr($color, 5)); + self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); + imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); + } + $dstsrc && $source = $dstsrc; + self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); + isset($waterdb['source']) && imagedestroy($waterdb['source']); + imagedestroy($sourcedb['source']); + return true; + } + + /** + * 文字水印的属性设置过滤 + * 返回为: + * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小') + * @param array $attribute + * @return array + */ + private static function checkAttribute($attribute) { + $attribute = is_string($attribute) ? array($attribute) : $attribute; + if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; + if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; + if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; + return $attribute; + } + + /** + * 判断是否需要转编码, + * 判断依据为,编码格式为utf-8 + * + * @param string $charset + * @return boolean + */ + private static function changeCharset($charset) { + $charset = strtolower($charset); + return !in_array($charset, array('utf8', 'utf-8')); + } + + /** + * 获得打水印的位置 + * 如果传入的是数组,则两个元素分别为水印的宽度x和高度y + * + * @param int|array $pos + * @param array $sourcedb + * @param array $waterdb + * @param int $markType 水印类型,1为图片水印,2为文字水印 + * @return array + */ + private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { + if (is_array($waterPos)) return $waterPos; + $wX = $wY = 0; + switch (intval($waterPos)) { + case 0 : + $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); + $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); + break; + case 1 : + $wX = 5; + $wY = $markType == 1 ? 5 : $waterdb['height']; + break; + case 2: + $wX = ($sourcedb['width'] - $waterdb['width']) / 2; + $wY = $markType == 1 ? 5 : $waterdb['height']; + break; + case 3: + $wX = $sourcedb['width'] - $waterdb['width'] - 5; + $wY = $markType == 1 ? 5 : $waterdb['height']; + break; + case 4: + $wX = 5; + $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; + break; + case 5: + $wX = ($sourcedb['width'] - $waterdb['width']) / 2; + $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; + break; + case 6: + $wX = $sourcedb['width'] - $waterdb['width'] - 5; + $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; + break; + default: + $wX = ($sourcedb['width'] - $waterdb['width']) / 2; + $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; + break; + } + return array($wX, $wY); + } + + /** + * 获得略缩图的信息 + * + * @param string $srcFile 源文件 + * @param int $dstW 目标文件的宽度 + * @param int $dstH 目标文件的高度 + * @param boolean $isProportion 是否定比略缩 + * @return array|boolean + */ + private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { + if (false === ($imgdata = self::getImgInfo($srcFile))) return false; + if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; + + $imgdata['dstW'] = $dstW; + $imgdata['dstH'] = $dstH; + if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { + $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); + } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { + $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); + } elseif ($dstW > 0 && $dstH > 0) { + if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { + $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); + } + if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { + $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); + } + } else { + $imgdata = false; + } + return $imgdata; + } + + /** + * 获得图片的信息,返回图片的源及图片的高度和宽度 + * + * @param string $srcFile 图像地址 + * @return array|boolean + */ + public static function getImgInfo($srcFile) { + if (false === ($imgdata = self::getImgSize($srcFile))) return false; + $imgdata['type'] = self::getTypes($imgdata['type']); + if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; + $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; + $imgdata['source'] = $imagecreatefromtype($srcFile); + !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); + !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); + return $imgdata; + } + + /** + * 获得图片的类型及宽高 + *
+	 * 图片type:
+	 * 1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,
+	 * 11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
+	 * 
+ * @param string $srcFile 图像地址 + * @param string $srcExt 图像后缀 + * @return array|boolean 返回图像的类型及高度和宽度 + */ + private static function getImgSize($srcFile, $srcExt = null) { + empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); + $srcdata = array(); + $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); + in_array($srcExt, $exts) && $srcdata['type'] = 2; + if (false === ($info = getimagesize($srcFile))) return false; + list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; + if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; + return $srcdata; + } + + /** + * 获得创建图像的方法 + * + * @param string $imagetype 图片类型 + * @return array + */ + private static function getImgcreate($imagetype) { + if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { + return array('imagecreatetruecolor', 'imagecopyresampled'); + } + if (function_exists('imagecreate') && function_exists('imagecopyresized')) { + return array('imagecreate', 'imagecopyresized'); + } + return array('', ''); + } + + /** + * 创建图像 + * + * @param string $type 图像类型 + * @param resource $image 图像源 + * @param string $filename 图像保存名字 + * @param int $quality 创建jpeg的时候用到 + * @return boolean + */ + private static function makeImg($type, $image, $filename, $quality = '75') { + $makeimage = 'image' . $type; + if (!function_exists($makeimage)) return false; + if ($type == 'jpeg') { + $makeimage($image, $filename, $quality); + } else { + $makeimage($image, $filename); + } + return true; + } + + /** + * 图片的对应类型 + * + * @param int $id 图片类型ID + * @return string + */ + private static function getTypes($id) { + $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); + return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; + } +} \ No newline at end of file From a50f94912983760084732aab50720906efd492e3 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 11 Aug 2011 02:29:57 +0000 Subject: [PATCH 0252/1065] =?UTF-8?q?urlRewrite=E9=87=8D=E6=9E=84,bug?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2312 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindUrlHelper.php | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php index 1b6ccc39..ae1a0732 100644 --- a/wind/core/web/WindUrlHelper.php +++ b/wind/core/web/WindUrlHelper.php @@ -62,8 +62,8 @@ public function parseUrl() { * @return string */ public function createUrl($action, $controller, $params = array()) { - list($controller, $module) = WindHelper::resolveController($controller); $urlRouter = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); + list($module, $controller, $action) = $this->resolveMvc($urlRouter, $action, $controller); if (!$this->isRewrite()) { $urlRouter->setAction($action); $urlRouter->setController($controller); @@ -77,6 +77,22 @@ public function createUrl($action, $controller, $params = array()) { return $this->buildRewriteUrl($params); } + /** + * 解析module, controller, action + * 如果不存在该值,则采用配置的默认值 + * + * @param AbstractWindRouter $urlRouter + * @param string $action + * @param string $controller + * @return array + */ + private function resolveMvc($urlRouter, $action, $controller) { + list($controller, $module) = WindHelper::resolveController($controller); + !$module && $module = $urlRouter->getConfig('module', WindUrlBasedRouter::DEFAULT_VALUE); + !$controller && $controller = $urlRouter->getConfig('controller', WindUrlBasedRouter::DEFAULT_VALUE); + !$action && $action = $urlRouter->getConfig('action', WindUrlBasedRouter::DEFAULT_VALUE); + return array($module, $controller, $action); + } /** * 构造重写的url * @param string $m @@ -170,11 +186,10 @@ private function buildCommonKeys($params, $parentKey = '', $first = true) { * @return array */ private function doParserUrl($url) { + if (!$url) return array(); if (is_string($url)) { - if (!$url) return array(); $url = explode($this->separator, trim($url, $this->separator)); } - $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseCommonKey($key, $url, $vars); @@ -186,7 +201,9 @@ private function doParserUrl($url) { } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); - $vars = array_merge($vars, array_combine($keys, $values)); + foreach($keys as $pos =>$key) { + isset($values[$pos]) && $vars[$key] = $values[$pos]; + } } } return $vars; From f0fddf8d08877c7379774756c82c2c1d64a33943 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 02:31:28 +0000 Subject: [PATCH 0253/1065] =?UTF-8?q?cache=E8=BF=94=E5=9B=9E=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=EF=BC=8C=E5=A6=82=E6=9E=9C=E8=8E=B7=E5=8F=96=E5=80=BC?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E5=88=99=E8=BF=94=E5=9B=9Efalse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2313 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index 34ba49a8..d9aafc96 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -157,16 +157,16 @@ public function batchDelete(array $keys) { } /** - * 格式化输出 + * 格式化输出,如果没有数据~则返回false * * @param string $value - * @return array + * @return string|boolean */ protected function formatData($key, $value) { $data = unserialize($value); - if (!is_array($data)) return array(); - if ($this->hasChanged($key, $data)) return array(); - return isset($data[self::DATA]) ? $data[self::DATA] : array(); + if (!is_array($data)) return false; + if ($this->hasChanged($key, $data)) return false; + return isset($data[self::DATA]) ? $data[self::DATA] : false; } /** From a98e404d9006fdfd1071360698e89d935174bf47 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 12 Aug 2011 03:14:25 +0000 Subject: [PATCH 0254/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2314 18ba2127-5a84-46d4-baec-3457e417f034 --- .../component/cache/strategy/WindMemCache.php | 153 ++++++++---------- 1 file changed, 64 insertions(+), 89 deletions(-) diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php index 274912a0..f66981e3 100644 --- a/wind/component/cache/strategy/WindMemCache.php +++ b/wind/component/cache/strategy/WindMemCache.php @@ -1,111 +1,86 @@ -'localhost', + * 'port'=>11211 + * 'pconn'=>true + * ), + * array( + * 'host'=>'localhost', + * 'port'=>11212 + * 'pconn'=>false + * ) * * the last known user to change this file in the repository * @author xiaoxiao * @version 2011-7-26 xiaoxiao - */ -class WindMemCache extends AbstractWindCache { - + */ +class WindMemCache extends AbstractWindCache { + /** * memcache缓存操作句柄 * @var WindMemcache - */ - protected $memcache = null; - + */ + protected $memcache = null; + /** * 是否对缓存采取压缩存储 * @var int - */ - protected $compress = 0; - - public function __construct() { - if (!extension_loaded('Memcache')) { - throw new WindCacheException('WindMemCache requires PHP `Memcache` extension to be loaded !'); - } - $this->memcache = new Memcache(); - } - + */ + protected $compress = 0; + + public function __construct() { + if (!extension_loaded('Memcache')) { + throw new WindCacheException('WindMemCache requires PHP `Memcache` extension to be loaded !'); + } + $this->memcache = new Memcache(); + } + /* * @see AbstractWindCache::setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return $this->memcache->set($key, $value, $this->compress, (int) $expire); - } - + */ + protected function setValue($key, $value, $expire = 0) { + return $this->memcache->set($key, $value, $this->compress, (int) $expire); + } + /* * @see AbstractWindCache::getValue() - */ - protected function getValue($key) { - return $this->memcache->get($key); - } - + */ + protected function getValue($key) { + return $this->memcache->get($key); + } + /* * @see AbstractWindCache::deleteValue() - */ - protected function deleteValue($key) { - return $this->memcache->delete($key); - } - + */ + protected function deleteValue($key) { + return $this->memcache->delete($key); + } + /* * @see AbstractWindCache::clear() - */ - public function clear() { - return $this->memcache->flush(); - } - + */ + public function clear() { + return $this->memcache->flush(); + } + /* (non-PHPdoc) * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->compress = $this->getConfig('compress', '', '0'); - $this->setServers($this->getConfig('servers')); - } - - /** - * 设置配置信息 - * - * @param array $servers - * @example - * $server = array( - * array( - * 'host'=>'localhost', - * 'port'=>11211 - * 'pconn'=>true - * ), - * array( - * 'host'=>'localhost', - * 'port'=>11212 - * 'pconn'=>false - * ) - * @throws WindCacheException - */ - private function setServers($servers) { - foreach ($servers as $server) { - if (!is_array($server)) { - throw new WindCacheException('The memcache config is incorrect'); - } - $this->setServer($server); - } - } - - /** - * 设置配置信息 - * - * @throws WindCacheException - */ - private function setServer($server) { - if (!isset($server['host'])) { - throw new WindCacheException('The memcache server ip address is not exist'); - } - if (!isset($server['port'])) { - throw new WindCacheException('The memcache server port is not exist'); - } - $defaultServer = array('host' => '', 'port' => '', 'pconn' => true, 'weight' => 1, - 'timeout' => 15, 'retry' => 15, 'status' => true, 'fcallback' => null); - list($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback) = array_values(array_merge($defaultServer, $server)); - $this->memcache->addServer($host, $port, $pconn, $weight, $timeout, $retry, $status, $fcallback); - } + */ + public function setConfig($config) { + parent::setConfig($config); + $this->compress = $this->getConfig('compress', '', '0'); + $servers = $this->getConfig('servers', '', array()); + $defaultServer = array('host' => '', 'port' => '', 'pconn' => true, 'weight' => 1, 'timeout' => 15, + 'retry' => 15, 'status' => true, 'fcallback' => null); + foreach ((array) $servers as $server) { + if (!is_array($server)) throw new WindException('The memcache config is incorrect'); + if (!isset($server['host'])) throw new WindException('The memcache server ip address is not exist'); + if (!isset($server['port'])) throw new WindException('The memcache server port is not exist'); + call_user_func_array(array($this->memcache, 'addServer'), array_merge($defaultServer, $server)); + } + } + } \ No newline at end of file From 4d47c01cf63bf8e93570122efb2bc98b5ec705a1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 12 Aug 2011 03:15:55 +0000 Subject: [PATCH 0255/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8CsetConfig=E6=96=B9=E6=B3=95=E4=BC=98=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E5=9C=A8=E7=B1=BB=E7=9A=84=E8=AE=BE=E8=AE=A1=E9=87=8C=E9=9D=A2?= =?UTF-8?q?=EF=BC=8C=E5=B0=BD=E9=87=8F=E9=81=BF=E5=85=8D=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E5=B0=8F=E7=9A=84=E3=80=81=E9=9B=B6=E6=95=A3=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=B0=81=E8=A3=85=EF=BC=8C=E4=BC=9A=E8=AE=A9=E7=B1=BB?= =?UTF-8?q?=E7=9A=84=E9=98=85=E8=AF=BB=E5=8F=98=E5=BE=97=E5=9B=B0=E9=9A=BE?= =?UTF-8?q?=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2315 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindMemCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php index f66981e3..5b672af2 100644 --- a/wind/component/cache/strategy/WindMemCache.php +++ b/wind/component/cache/strategy/WindMemCache.php @@ -32,7 +32,7 @@ class WindMemCache extends AbstractWindCache { protected $compress = 0; public function __construct() { - if (!extension_loaded('Memcache')) { + if (!extension_loaded('Memcache')) { throw new WindCacheException('WindMemCache requires PHP `Memcache` extension to be loaded !'); } $this->memcache = new Memcache(); From e62d8a39d1dc58e6dfb7eb8abd76ccc879676d44 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 12 Aug 2011 05:16:37 +0000 Subject: [PATCH 0256/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2316 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindXCache.php | 30 ++++---------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/wind/component/cache/strategy/WindXCache.php b/wind/component/cache/strategy/WindXCache.php index d01396bf..d07fa7ba 100644 --- a/wind/component/cache/strategy/WindXCache.php +++ b/wind/component/cache/strategy/WindXCache.php @@ -42,39 +42,21 @@ protected function deleteValue($key) { */ public function clear() { //xcache_clear_cache需要验证权限 - $this->checkAuthor(); - + $tmp['user'] = isset($_SERVER['PHP_AUTH_USER']) ? null : $_SERVER['PHP_AUTH_USER']; + $tmp['pwd'] = isset($_SERVER['PHP_AUTH_PW']) ? null : $_SERVER['PHP_AUTH_PW']; + $_SERVER['PHP_AUTH_USER'] = $this->authUser; + $_SERVER['PHP_AUTH_PW'] = $this->authPwd; //如果配置中xcache.var_count > 0 则不能用xcache_clear_cache(XC_TYPE_VAR, 0)的方式删除 - $max = xcache_count(XC_TYPE_VAR); + $max = xcache_count(XC_TYPE_VAR); for ($i = 0; $i < $max; $i++) { xcache_clear_cache(XC_TYPE_VAR, $i); } - //恢复之前的权限 - $this->checkAuthor(true); - - return true; - } - - /** - * 设置验证权限 - * @param boolean $recover 是否恢复设置 - */ - private function checkAuthor($recover = false) { - static $tmp = array(); - if (!$recover) { - $tmp['user'] = isset($_SERVER['PHP_AUTH_USER']) ? null : $_SERVER['PHP_AUTH_USER']; - $tmp['pwd'] = isset($_SERVER['PHP_AUTH_PW']) ? null : $_SERVER['PHP_AUTH_PW']; - $_SERVER['PHP_AUTH_USER'] = $this->authUser; - $_SERVER['PHP_AUTH_PW'] = $this->authPwd; - return true; - } $_SERVER['PHP_AUTH_USER'] = $tmp['user']; $_SERVER['PHP_AUTH_PW'] = $tmp['pwd']; - unset($tmp); return true; } - + /* * (non-PHPdoc) * @see AbstractWindCache::setConfig() From a1a41cfc951898d85c0188ed83f9efc2e6c80438 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 12 Aug 2011 05:20:03 +0000 Subject: [PATCH 0257/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2317 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/filter/WindHandlerInterceptor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/filter/WindHandlerInterceptor.php b/wind/component/filter/WindHandlerInterceptor.php index cf104e57..c6ca0890 100644 --- a/wind/component/filter/WindHandlerInterceptor.php +++ b/wind/component/filter/WindHandlerInterceptor.php @@ -34,7 +34,7 @@ public function handle() { } else { $this->result = $this->interceptorChain->execute(); } - call_user_func_array(array($this, 'postHandle'), $args + (array)$this->result); + call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } From fbbad3306fc8b64d866aa1e47729fb1244ec607d Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 12 Aug 2011 05:23:34 +0000 Subject: [PATCH 0258/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2318 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/compiler/WindTemplateCompilerPage.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerPage.php b/wind/component/viewer/compiler/WindTemplateCompilerPage.php index c660101c..9b9f7292 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerPage.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerPage.php @@ -3,7 +3,7 @@ /** * 职责:编译模板page标签 * 支持参数类型: - * + * * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu @@ -66,7 +66,7 @@ private function getDefaultHtml() { return ''; } - /* + /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::getProperties() */ public function getProperties() { From 683f218dfbbc3f5e76e656535d191a1ab5c0c076 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 12 Aug 2011 08:00:15 +0000 Subject: [PATCH 0259/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2319 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/proxy/IWindClassProxy.php | 45 --------- wind/core/factory/proxy/WindClassProxy.php | 105 +++++++++----------- 2 files changed, 46 insertions(+), 104 deletions(-) delete mode 100644 wind/core/factory/proxy/IWindClassProxy.php diff --git a/wind/core/factory/proxy/IWindClassProxy.php b/wind/core/factory/proxy/IWindClassProxy.php deleted file mode 100644 index 1ab6ceef..00000000 --- a/wind/core/factory/proxy/IWindClassProxy.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindClassProxy { - const EVENT_TYPE_METHOD = 'method'; - /** - * Enter description here ... - * - * @var unknown_type - * @deprecated - */ - const EVENT_TYPE_SETTER = 'setter'; - /** - * Enter description here ... - * - * @var unknown_type - * @deprecated - */ - const EVENT_TYPE_GETTER = 'getter'; - - /** - * Enter description here ... - * @return ReflectionClass - */ - public function _getReflection(); - - /** - * Enter description here ... - */ - public function _getInstance(); - - /** - * Enter description here ... - * - * @param string $event - * @param Object $listener - * @param string $type - */ - public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD); -} -?> \ No newline at end of file diff --git a/wind/core/factory/proxy/WindClassProxy.php b/wind/core/factory/proxy/WindClassProxy.php index 03430529..4c761a57 100644 --- a/wind/core/factory/proxy/WindClassProxy.php +++ b/wind/core/factory/proxy/WindClassProxy.php @@ -8,9 +8,12 @@ * @version $Id$ * @package */ -class WindClassProxy implements IWindClassProxy { - private $_interceptorChain = 'COM:filter.WindHandlerInterceptorChain'; - private $_interceptorChainObj = null; +class WindClassProxy { + const EVENT_TYPE_METHOD = 'method'; + const EVENT_TYPE_SETTER = 'setter'; + const EVENT_TYPE_GETTER = 'getter'; + + private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; @@ -21,8 +24,34 @@ class WindClassProxy implements IWindClassProxy { /** * @param string|object $targetObj */ - public function __construct($targetObj = null, $args = array()) { - $this->initClassProxy($targetObj, $args); + public function __construct($targetObject = null, $args = array()) { + try { + if (is_object($targetObject)) { + $this->_setClassName(get_class($targetObject)); + $this->_instance = $targetObject; + } elseif (is_string($targetObject) && !empty($targetObject)) { + $this->_setClassPath($targetObject); + $reflection = new ReflectionClass($this->_className); + if ($reflection->isAbstract() || $reflection->isInterface()) { + throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); + } + $this->_reflection = $reflection; + $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); + } else + throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); + + $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); + foreach ($types as $type) { + $this->_listener[$type] = array(); + } + + if ($this->_instance !== null) return; + + } catch (Exception $e) { + Wind::log('[core.factory.proxy.WindClassProxy.initClassProxy] Initialization proxy failed.' . $e->getMessage(), WindLogger::LEVEL_DEBUG, 'wind.core'); + } + + //$this->initClassProxy($targetObj, $args); } /* (non-PHPdoc) @@ -30,9 +59,7 @@ public function __construct($targetObj = null, $args = array()) { */ public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { - throw new WindException( - '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, - WindException::ERROR_PARAMETER_TYPE_ERROR); + throw new WindException('[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); @@ -101,8 +128,13 @@ protected function initClassProxy($targetObject, $args = array()) { $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; } elseif (is_string($targetObject) && !empty($targetObject)) { - $_className = Wind::import($targetObject); - $this->_setClassName($_className); + $this->_setClassPath($targetObject); + $reflection = new ReflectionClass($this->_className); + if ($reflection->isAbstract() || $reflection->isInterface()) { + throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); + } + $this->_reflection = $reflection; + $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); } else throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); @@ -110,17 +142,9 @@ protected function initClassProxy($targetObject, $args = array()) { foreach ($types as $type) { $this->_listener[$type] = array(); } - $reflection = new ReflectionClass($this->_className); - if ($reflection->isAbstract() || $reflection->isInterface()) { - throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); - } - $this->_reflection = $reflection; - if ($this->_instance !== null) return; - $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); + } catch (Exception $e) { - Wind::log( - '[core.factory.proxy.WindClassProxy.initClassProxy] Initialization proxy failed.' . $e->getMessage(), - WindLogger::LEVEL_DEBUG, 'wind.core'); + Wind::log('[core.factory.proxy.WindClassProxy.initClassProxy] Initialization proxy failed.' . $e->getMessage(), WindLogger::LEVEL_DEBUG, 'wind.core'); } } @@ -134,7 +158,8 @@ private function _getInterceptorChain($event = '') { $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; - } else throw new WindException('unable to create interceptorChain.'); + } else + throw new WindException('[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; @@ -161,17 +186,6 @@ public function _getInstance() { return $this->_instance; } - /* (non-PHPdoc) - * @see IWindClassProxy::_getReflection() - */ - public function _getReflection() { - if ($this->_reflection instanceof ReflectionClass) - return $this->_reflection; - else - throw new WindException(get_class($this) . '->_reflection, ' . gettype($this->_reflection), - WindException::ERROR_CLASS_TYPE_ERROR); - } - /** * @return string */ @@ -209,7 +223,6 @@ public function _setClassPath($classPath) { */ public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; - return true; } /** @@ -218,31 +231,5 @@ public function _setProperty($propertyName, $value) { public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } - - /** - * 根据别名返回属性定义,别名为空时返回整个属性定义列表 - * - * @param string $alias - * @return object | array - */ - public function _getAttribute($alias = '') { - if ($alias === '') - return $this->_attributes; - else - return isset($this->_attributes[$alias]) ? $this->_attributes[$alias] : null; - } - - /** - * 设置属性对象,设置的属性可以在listener中被访问到 - * - * @param string|array $alias - * @param object $object - */ - public function _setAttribute($alias, $object = null) { - if (is_array($alias)) - $this->_attributes += $alias; - elseif (is_string($alias)) - $this->_attributes[$alias] = $object; - } } ?> \ No newline at end of file From a9131df376624218a463eb05e27df6a3ff126b67 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 12 Aug 2011 08:00:31 +0000 Subject: [PATCH 0260/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2320 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 39 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 072a9ff8..0fdfc5f0 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -33,7 +33,9 @@ class WindFactory implements IWindFactory { * @param string $configFile */ public function __construct($classDefinitions = array()) { - $this->classDefinitions = $classDefinitions; + if (is_array($classDefinitions)) { + $this->classDefinitions = $classDefinitions; + } } /* (non-PHPdoc) @@ -43,12 +45,12 @@ public function getInstance($alias, $args = array()) { if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!($definition = $this->checkAlias($alias))) return null; $this->buildDefinition($definition); - $_subDefinitions = $definition['constructorArg']; - foreach ($_subDefinitions as $_subDefinition) { - if (isset($_subDefinition['value'])) { - $args[] = $_subDefinition['value']; - } elseif (isset($_subDefinition['ref'])) - $args[] = $this->getInstance($_subDefinition['ref']); + $_constructorArgs = $definition['constructorArgs']; + foreach ($_constructorArgs as $_var) { + if (isset($_var['value'])) { + $args[] = $_var['value']; + } elseif (isset($_var['ref'])) + $args[] = $this->getInstance($_var['ref']); } $config = $this->buildConfig($definition, $alias); $instance = $this->createInstance($definition['className'], $args); @@ -67,11 +69,14 @@ public function getInstance($alias, $args = array()) { static public function createInstance($className, $args = array()) { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, - WindLogger::LEVEL_DEBUG, 'core.factory'); + Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); + } + if (empty($args)) + return new $className(); + else { + $reflection = new ReflectionClass($className); + return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } - $reflection = new ReflectionClass($className); - return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } @@ -160,9 +165,7 @@ protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { - throw new WindException( - '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', - WindException::ERROR_CLASS_METHOD_NOT_EXIST); + throw new WindException('[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } @@ -187,13 +190,16 @@ protected function setProxyForClass($proxy, $instance) { */ protected function buildProperties($properties, $instance) { if (isset($properties['delay']) && ($properties['delay'] === 'false' || $properties['delay'] === false)) { - unset($properties['delay']); foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); + elseif (isset($subDefinition['path'])) { + $_className = Wind::import($subDefinition['path']); + $_value = $this->createInstance($_className); + } if ($_value) { $_setter = 'set' . ucfirst(trim($key, '_')); call_user_func_array(array($instance, $_setter), array($_value)); @@ -210,7 +216,8 @@ protected function buildProperties($properties, $instance) { * @return boolean */ private function buildDefinition(&$definition) { - $_definition = array('path' => '', 'className' => '', 'factoryMethod' => '', 'initMethod' => '', 'scope' => 'application', 'proxy' => false, 'properties' => array(), 'config' => array(), 'constructorArg' => array()); + $_definition = array('path' => '', 'className' => '', 'factoryMethod' => '', 'initMethod' => '', + 'scope' => 'application', 'proxy' => false, 'properties' => array(), 'config' => array(), 'constructorArgs' => array()); $definition = array_merge($_definition, $definition); $definition['className'] = Wind::import($definition['path']); } From 2f6e8059e0525abb62ebc2f0fe98fd9706dd829c Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 08:38:36 +0000 Subject: [PATCH 0261/1065] =?UTF-8?q?exception=E8=BE=93=E5=87=BA=E7=A9=BA?= =?UTF-8?q?=E7=99=BDbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2321 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindFrontController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index 7a6c9421..bdd4e30b 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -147,6 +147,7 @@ public function displayMessage($header, $message = '', $trace = '') { $_tmp .= "

$message

"; $_tmp .= "
$trace
"; $this->getResponse()->sendError(500, $_tmp); + $this->getResponse()->sendResponse(); } /** From e79a3485aef98ebe68946eb54a374e72f1eb5209 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 08:50:40 +0000 Subject: [PATCH 0262/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2322 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 30b6ddbe..861f2c27 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -58,8 +58,7 @@ template htm compile.template - true - viewCache + 0 From 1b20d3680365e652ed6b3f251ba869d7d3ee5b15 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 08:51:32 +0000 Subject: [PATCH 0263/1065] =?UTF-8?q?cache=20=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2323 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php index d9aafc96..4b07da99 100644 --- a/wind/component/cache/AbstractWindCache.php +++ b/wind/component/cache/AbstractWindCache.php @@ -99,7 +99,7 @@ public function set($key, $value, $expires = 0, AbstractWindCacheDependency $den $data[self::DEPENDENCY] = serialize($denpendency); $data[self::DEPENDENCYCLASS] = get_class($denpendency); } - return $this->setValue($this->buildSecurityKey($key), serialize($data), $expires); + return $this->setValue($this->buildSecurityKey($key), serialize($data), $data[self::EXPIRE]); } catch (Exception $e) { throw new WindCacheException('Setting cache failed.' . $e->getMessage()); } @@ -196,7 +196,7 @@ protected function hasChanged($key, array $data) { * @return string */ protected function buildSecurityKey($key) { - return $this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key . $this->getSecurityCode() : $key . $this->getSecurityCode(); + return md5($this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key . $this->getSecurityCode() : $key . $this->getSecurityCode()); } /** From 82704d6b800508349bd0d4e2bdd216b662a20943 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 08:51:48 +0000 Subject: [PATCH 0264/1065] =?UTF-8?q?cache=20=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2324 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/strategy/WindFileCache.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php index a2e5b70a..47a2c76a 100644 --- a/wind/component/cache/strategy/WindFileCache.php +++ b/wind/component/cache/strategy/WindFileCache.php @@ -69,6 +69,7 @@ public function clear() { * @return string */ protected function buildSecurityKey($key) { + $key = parent::buildSecurityKey($key); if (false !== ($dir = $this->checkCacheDir($key))) return $dir; $_dir = $this->getCacheDir(); if (0 < ($level = $this->getCacheDirectoryLevel())) { @@ -76,7 +77,7 @@ protected function buildSecurityKey($key) { $_dir .= DIRECTORY_SEPARATOR . $_subdir; if (!is_dir($_dir)) mkdir($_dir, 0777, true); } - $filename = parent::buildSecurityKey($key) . '.' . $this->getCacheFileSuffix(); + $filename = $key . '.' . $this->getCacheFileSuffix(); $this->cacheFileList[$key] = ($_dir ? $_dir . DIRECTORY_SEPARATOR . $filename : $filename); return $this->cacheFileList[$key]; } From a050c494d3d817692728351bcbc65bfab08e7aba Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 08:52:16 +0000 Subject: [PATCH 0265/1065] =?UTF-8?q?cache=20=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2325 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindView.php | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 675d3cff..df013496 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -42,12 +42,6 @@ class WindView extends WindModule { */ protected $isCache = false; - /** - * 缓存策略 - * - * @var string - */ - protected $cacheClass; /** * 是否对模板变量进行html字符过滤 @@ -159,7 +153,6 @@ public function init() { $this->setCompileDir($this->getConfig('compile-dir')); $this->setTemplateExt($this->getConfig('template-ext')); $this->setIsCache($this->getConfig('is-cache')); - $this->setCacheClass($this->getConfig('cache-class')); } /** @@ -204,13 +197,6 @@ public function getLayout() { return $this->layout; } - /** - * @return string - */ - public function getCacheClass() { - return $this->cacheClass; - } - /** * @param string $templateDir */ @@ -252,13 +238,6 @@ public function setIsCache($isCache) { public function setLayout($layout) { $this->layout = $layout; } - - /** - * @param string $class - */ - public function setCacheClass($class) { - $this->cacheClass = $class; - } /** * @return the $htmlspecialchars @@ -278,10 +257,7 @@ public function setHtmlspecialchars($htmlspecialchars) { * @return WindViewerCache */ public function getViewCache() { - if ($this->viewCache === null) { - $this->_getViewCache(); - } - return $this->viewCache; + return $this->_getViewCache();; } /** From df78123ea8b4036185ec13638a3406a451a701d8 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 08:52:52 +0000 Subject: [PATCH 0266/1065] =?UTF-8?q?cache=20=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2326 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/listener/WindViewCacheListener.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/wind/component/viewer/listener/WindViewCacheListener.php b/wind/component/viewer/listener/WindViewCacheListener.php index ea5c73b7..f4b6c947 100644 --- a/wind/component/viewer/listener/WindViewCacheListener.php +++ b/wind/component/viewer/listener/WindViewCacheListener.php @@ -37,17 +37,15 @@ public function preHandle() { private function getKey() { $host = Wind::getApp()->getRequest()->getHostInfo(); $uri = Wind::getApp()->getRequest()->getRequestUri(); - return md5($host.$uri . '/' . $this->windView->getTemplateName() . '.' . $this->windView->getTemplateExt()); + return $host.$uri . '/' . $this->windView->getTemplateName() . '.' . $this->windView->getTemplateExt(); } /* (non-PHPdoc) * @see WindHandlerInterceptor::postHandle() */ public function postHandle() { - $args = func_get_args(); - $result = end($args); $cache = $this->windView->getViewCache(); - $cache->set($this->getKey(), $result); + $cache->set($this->getKey(), $this->result); } } From eb7ed2e6fd4cafd5c53b21d8eb733cc66fabc6eb Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 08:54:39 +0000 Subject: [PATCH 0267/1065] =?UTF-8?q?=E5=85=B6=E4=BB=96=E7=9A=84exception?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2327 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 9c3e5780..5b1ef2dc 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -36,6 +36,8 @@ public function processRequest() { } catch (WindViewException $viewException) { //TODO $this->sendErrorMessage($viewException->getMessage()); + } catch (Exception $e) { + throw new WindException($e->getMessage()); } } From aa409ae0031467a4b7b76f59a3af5f44eb1ccd91 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 12 Aug 2011 10:12:21 +0000 Subject: [PATCH 0268/1065] =?UTF-8?q?=E4=BB=A3=E7=90=86=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2328 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/proxy/WindClassProxy.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/core/factory/proxy/WindClassProxy.php b/wind/core/factory/proxy/WindClassProxy.php index 4c761a57..97a2c653 100644 --- a/wind/core/factory/proxy/WindClassProxy.php +++ b/wind/core/factory/proxy/WindClassProxy.php @@ -14,6 +14,7 @@ class WindClassProxy { const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; + private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; From b20a274bc7a4c6f89444a3e133ad9ce842277ca9 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Sat, 13 Aug 2011 04:43:42 +0000 Subject: [PATCH 0269/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2329 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindViewerResolver.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index c0d02793..d3853907 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -17,11 +17,6 @@ * @package */ class WindViewerResolver extends WindModule implements IWindViewerResolver { - /** - * @var WindUrlHelper - */ - protected $urlHelper = null; - /** * @var WindView */ @@ -71,7 +66,7 @@ public function compile($template, $suffix = '', $output = false) { throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, WindViewException::VIEW_NOT_EXIST); } - $compileFile = $this->getWindView()->getCompileFile($template, 'tpl'); + $compileFile = $this->getWindView()->getCompileFile($template, 'php'); /* @var $_windTemplate WindViewTemplate */ $_windTemplate = $this->getSystemFactory()->getInstance(COMPONENT_TEMPLATE); From 9793564c20f51093d7c539c160371a5f0b6e5e76 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Sat, 13 Aug 2011 04:45:04 +0000 Subject: [PATCH 0270/1065] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E4=B8=BAurlrewrite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2330 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index a5f1596d..fbf918ef 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -391,7 +391,7 @@ private static function _loadBaseLib() { define('COMPONENT_ERRORHANDLER', 'errorHandler'); define('COMPONENT_LOGGER', 'windLogger'); define('COMPONENT_FORWARD', 'forward'); -define('COMPONENT_ROUTER', 'urlBasedRouter'); +define('COMPONENT_ROUTER', 'urlRewriteRouter'); define('COMPONENT_URLHELPER', 'urlHelper'); define('COMPONENT_VIEW', 'windView'); define('COMPONENT_VIEWRESOLVER', 'viewResolver'); From 733b5690e74ec2886603b85b22b56d98dbc86c3a Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Sat, 13 Aug 2011 04:46:57 +0000 Subject: [PATCH 0271/1065] =?UTF-8?q?=E8=B0=83=E7=94=A8UrlRewriteRouter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2331 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 861f2c27..ae4f2e7c 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -35,8 +35,12 @@
- + + + + + m/c-a/* @@ -50,7 +54,9 @@ 1 - + + + @@ -65,11 +71,7 @@ - - - - + From 967ea02ad662e921f27d0b1f8e9628f51bbee030 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Sat, 13 Aug 2011 04:47:14 +0000 Subject: [PATCH 0272/1065] UrlRewriteRouter git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2332 18ba2127-5a84-46d4-baec-3457e417f034 --- .../component/router/WindUrlRewriteRouter.php | 322 ++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 wind/component/router/WindUrlRewriteRouter.php diff --git a/wind/component/router/WindUrlRewriteRouter.php b/wind/component/router/WindUrlRewriteRouter.php new file mode 100644 index 00000000..503e77ac --- /dev/null +++ b/wind/component/router/WindUrlRewriteRouter.php @@ -0,0 +1,322 @@ + + * @author xiaoxiao + * @version 2011-8-12 xiaoxiao + */ +class WindUrlRewriteRouter extends AbstractWindRouter { + private $urlPatttern = ''; + private $keyValueSep = ''; + private $separator = ''; + private $suffix = ''; + private $isRewrite = 0; + private $keyPrefix = ''; + private $baseUrl = ''; + private $patterns = array(); + + /** + * 是否开启重写 + * + * @return boolean + */ + public function isRewrite() { + return $this->isRewrite == '1' || $this->isRewrite == 'true'; + } + + /* + * (non-PHPdoc) + * @see AbstractWindRouter::parse() + */ + public function parse() { + $this->isRewrite() && $this->parseUrl(); + $this->setModule($this->getUrlParamValue('module', $this->getModule())); + $this->setController($this->getUrlParamValue('controller', $this->getController())); + $this->setAction($this->getUrlParamValue('action', $this->getAction())); + } + + /** + * 解析Url + * + * 没有配置解析规则,直接返回 + * 获得则匹配RequestUri,根据用户的配置分隔符分割信息 + * 同时设置到超全局变量$_GET中 + */ + public function parseUrl() { + if (!$this->isRewrite()) return; + $url = array(); + if ($this->getRequest()->getServer('SERVER_PROTOCOL')) {//http协议 + $pathInfo = $this->getRequest()->getServer('PATH_INFO'); + if ($pathInfo && !empty($pathInfo)) { + $url = rtrim($pathInfo, $this->suffix); + } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { + $scriptName = $this->getRequest()->getScriptUrl(); + if (0 === strpos($url, $scriptName)) { + $url = substr($url, strlen($scriptName)); + } + $url = rtrim($url, $this->suffix); + } + $url = trim($url, '?/'); + $url && $params = $this->doParserUrl($url); + } else {// 命令行下 + $i = 0; + $args = $this->getRequest()->getServer('argv', array()); + while (isset($args[$i]) && isset($args[$i + 1])) { + $params[$args[$i]] = $args[$i + 1]; + $i += 2; + } + } + foreach ($params as $k => $v) { + !isset($_GET[$k]) && $_GET[$k] = $v; + } + } + + /** + * 构造返回Url地址 + * + * 将根据是否开启url重写来分别构造相对应的url + * + * @param string $action 执行的操作 + * @param string $controller 执行的controller + * @param array $params 附带的参数 + * @return string + */ + public function buildUrl($action = '', $controller = '', $params = array()) { + list($module, $controller, $action) = $this->resolveMvc($action, $controller); + $m = $this->getConfig('module', 'url-param'); + $c = $this->getConfig('controller', 'url-param'); + $a = $this->getConfig('action', 'url-param'); + $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); + return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query($params, '', '&'); + } + + /** + * 解析module, controller, action + * 如果不存在该值,则采用配置的默认值 + * + * @param AbstractWindRouter $urlRouter + * @param string $action + * @param string $controller + * @return array + */ + private function resolveMvc($action, $controller) { + list($controller, $module) = WindHelper::resolveController($controller); + !$module && $module = $this->getConfig('module', 'default-value'); + !$controller && $controller = $this->getConfig('controller', 'default-value'); + !$action && $action = $this->getConfig('action', 'default-value'); + return array($module, $controller, $action); + } + /** + * 构造重写的url + * @param string $m + * @param string $c + * @param string $action + * @param string $params + * @return string + */ + private function buildRewriteUrl($params) { + $url = $this->urlPatttern; + foreach ($this->patterns as $key => $value) { + if ('*' == $value[0]) { + $url = str_replace($value, $this->buildNomalKeys($params), $url); + } else { + $url = $this->buildVars($value, $params, $url); + } + } + return $this->baseUrl . '/' . $url . $this->suffix; + } + + /** + * 构建变量 不是* + * + * @param string $value + * @param array $params + * @param string $url + * @return string + */ + private function buildVars($value, &$params, $url) { + $keys = explode($this->keyValueSep, $value); + $values = array(); + foreach ($keys as $v) { + if (!isset($params[$v])) continue; + $values[] = $params[$v]; + unset($params[$v]); + } + return str_replace($keys, $values, $url); + } + + /** + * 构建rewriteurl的参数部分 + * @param array $params + * @param string $parentKey + * @param boolean $first 只有第一级的变量才加前缀 + * @return string + */ + private function buildNomalKeys($params, $parentKey = '', $first = true) { + $tmp = array(); + foreach ($params as $k => $v) { + if (is_int($k) && $this->keyPrefix != null && $first) { + $k = urlencode($this->keyPrefix . $k); + } + if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; + if (is_array($v)) { + array_push($tmp, $this->buildNomalKeys($v, $k, false)); + } else { + array_push($tmp, $k . $this->keyValueSep . urlencode($v)); + } + } + return implode($this->separator, $tmp); + } + + + /** + * 执行匹配 + * patterns中的匹配模式去匹配url中的信息 + * urlPatterns中可以根据需求将mca进行组合配置。 + * + m-c-a/* + htm + / + - + myvar_ + 1 + + * url-pattern中:*匹配表示其他的变量信息 + * 用户也可以将自己的其他信息添加到格式中比如m/c-a/tid/* + * suffix : url的后缀 + * separator: 变量分隔符 + * key-value-sep: key和value的分隔符,默认和separator一致 + * key-prefix: 数字索引的前缀 + * is-rewrite: 是否采用rewrite机制 + * + * 遍历url模式:采用separator配置的分隔符获得该模式数组 + * 如果模式是*,则代表该位置开始往后为为传递的变量信息 + * 如果模式不是*,则代表该位置为特殊模式。 + * 如果含有key-value-sep配置的分隔符: 则分别对url中相同key下的值和模式中的值分别做分割,对应的模式下获得的数组作为key,url中获得数组作为value + * 如果不含:则该值就作为Key,url对应位置上的值作为value + * + * @param string 待分析匹配的路径信息 + * @return array + */ + private function doParserUrl($url) { + if (!$url) return array(); + if (is_string($url)) { + $url = explode($this->separator, trim($url, $this->separator)); + } + $vars = array(); + foreach ($this->patterns as $key => $value) { + if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); + else { + if (!isset($url[$key])) continue; + if (false === strrpos($value, $this->keyValueSep)) { + $vars[$value] = $url[$key]; + continue; + } + $keys = explode($this->keyValueSep, $value); + $values = explode($this->keyValueSep, $url[$key]); + foreach($keys as $pos =>$key) { + isset($values[$pos]) && $vars[$key] = $values[$pos]; + } + } + } + return $vars; + } + + /** + * 解析url普通参数 + * 如果separator和key-value-sep配置相同:则采用每两个元素为一对key-value的规则获得变量 + * 如果不相同:则将会以每个元素为key-value的组合,之间的分隔符以key-value-sep划分,如果没有该分隔符,则默认该值的索引为数字索引。 + * 如果为没有分隔符:则该值索引以数字索引给出,同时该数字索引将会根据用户是否配置key前缀key-prefix来给出key。 + * 如果有分隔符:则该值将会用分隔符分割获得的两个值来分别作为key和value. + * @param int $key + * @param array $urlParams + * @param array $params + */ + private function parseNomalKeys($key, $urlParams, &$params) { + $pos = 0; + while (isset($urlParams[$key])) { + if ($this->separator == $this->keyValueSep) { + if (isset($urlParams[$key+1])) { + $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); + $key += 2; + } + continue; + } + if (false === strrpos($urlParams[$key], $this->keyValueSep)) { + $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); + $pos ++; + } else { + list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); + $this->parseKey($params, $k, urldecode($v)); + } + $key += 1; + } + } + + /** + * 解析url的parama信息中的key值 + * + * 如果key值不存在'[',']'字符,则该key为字符串,直接返回 + * 如果key值存在,并且'['和']'之前没有字符,则表示该key是将是一个数组,并且键值自增,返回array($key) + * 如果key值存在,并且'['和']'之前有字符,则表示该key是一个数组,并且'['和']'其中的字符是该数组中的键值,返回array(key值, 键值) + * + * //TODO 需要考虑多维数组的情况 + * @param string $key + * @return string|array 返回匹配的结果 + */ + private function parseKey(&$params, $key, $value) { + if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { + $params[$key] = $value; + return; + } + $name = substr($key, 0, $pos); + if ($pos2 === $pos + 1) { + $params[$name][] = $value; + return; + } else { + $key = substr($key, $pos + 1, $pos2 - $pos - 1); + $params[$name][$key] = $value; + return; + } + } + + /* + * (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); + $usrConfig && $config = array_merge($config, $usrConfig); + parent::setConfig($config); + $this->urlPatttern = $this->getConfig('url-pattern'); + $this->separator = $this->getConfig('separator'); + $this->keyValueSep = $this->getConfig('key-value-sep'); + $this->keyValueSep == "" && $this->keyValueSep = $this->separator; + $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); + $this->isRewrite = $this->getConfig('is-rewrite'); + $this->keyPrefix = $this->getConfig('key-prefix'); + $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); + $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); + if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); + } + + + /** + * 返回路由的配置信息 + * + * @param urlParam + * @param defaultValue + * @return string + */ + private function getUrlParamValue($type, $defaultValue = '') { + if ($_param = $this->getConfig($type, 'url-param')) { + $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); + $tmp = $this->getRequest()->getRequest($_param, $defaultValue); + return !$tmp ? $defaultValue : $tmp; + } + return $defaultValue; + } + +} From 3ec432ac8a3fb4bb5891cbbd7dc6b3d3b9d13792 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Sat, 13 Aug 2011 04:47:32 +0000 Subject: [PATCH 0273/1065] urlHelper git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2333 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindUrlHelper.php | 305 +------------------------------- 1 file changed, 3 insertions(+), 302 deletions(-) diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php index ae1a0732..a9bfa467 100644 --- a/wind/core/web/WindUrlHelper.php +++ b/wind/core/web/WindUrlHelper.php @@ -6,50 +6,6 @@ * @package */ class WindUrlHelper extends WindModule { - private $urlPatttern = ''; - private $keyValueSep = ''; - private $separator = ''; - private $suffix = ''; - private $isRewrite = 0; - private $keyPrefix = ''; - private $baseUrl = ''; - private $patterns = array(); - - /** - * 解析Url - * - * 没有配置解析规则,直接返回 - * 获得则匹配RequestUri,根据用户的配置分隔符分割信息 - * 同时设置到超全局变量$_GET中 - */ - public function parseUrl() { - if (!$this->isRewrite()) return; - $url = array(); - if ($this->getRequest()->getServer('SERVER_PROTOCOL')) {//http协议 - $pathInfo = $this->getRequest()->getServer('PATH_INFO'); - if ($pathInfo && !empty($pathInfo)) { - $url = rtrim($pathInfo, $this->suffix); - } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { - $scriptName = $this->getRequest()->getScriptUrl(); - if (0 === strpos($url, $scriptName)) { - $url = substr($url, strlen($scriptName)); - } - $url = rtrim($url, $this->suffix); - } - $url = trim($url, '?/'); - $url && $params = $this->doParserUrl($url); - } else {// 命令行下 - $i = 0; - $args = $this->getRequest()->getServer('argv', array()); - while (isset($args[$i]) && isset($args[$i + 1])) { - $params[$args[$i]] = $args[$i + 1]; - $i += 2; - } - } - foreach ($params as $k => $v) { - !isset($_GET[$k]) && $_GET[$k] = $v; - } - } /** * 构造返回Url地址 @@ -61,264 +17,9 @@ public function parseUrl() { * @param array $params 附带的参数 * @return string */ - public function createUrl($action, $controller, $params = array()) { - $urlRouter = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); - list($module, $controller, $action) = $this->resolveMvc($urlRouter, $action, $controller); - if (!$this->isRewrite()) { - $urlRouter->setAction($action); - $urlRouter->setController($controller); - $urlRouter->setModule($module); - return $this->baseUrl . '/' . $urlRouter->buildUrl() . '&' . http_build_query($params, '', '&'); - } - $m = $urlRouter->getConfig('module', WindUrlBasedRouter::URL_PARAM); - $c = $urlRouter->getConfig('controller', WindUrlBasedRouter::URL_PARAM); - $a = $urlRouter->getConfig('action', WindUrlBasedRouter::URL_PARAM); - $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); - return $this->buildRewriteUrl($params); - } - - /** - * 解析module, controller, action - * 如果不存在该值,则采用配置的默认值 - * - * @param AbstractWindRouter $urlRouter - * @param string $action - * @param string $controller - * @return array - */ - private function resolveMvc($urlRouter, $action, $controller) { - list($controller, $module) = WindHelper::resolveController($controller); - !$module && $module = $urlRouter->getConfig('module', WindUrlBasedRouter::DEFAULT_VALUE); - !$controller && $controller = $urlRouter->getConfig('controller', WindUrlBasedRouter::DEFAULT_VALUE); - !$action && $action = $urlRouter->getConfig('action', WindUrlBasedRouter::DEFAULT_VALUE); - return array($module, $controller, $action); - } - /** - * 构造重写的url - * @param string $m - * @param string $c - * @param string $action - * @param string $params - * @return string - */ - private function buildRewriteUrl($params) { - $url = $this->urlPatttern; - foreach ($this->patterns as $key => $value) { - if ('*' == $value[0]) { - $url = str_replace($value, $this->buildCommonKeys($params), $url); - } else { - $url = $this->buildVars($value, $params, $url); - } - } - return $this->baseUrl . '/' . $url . $this->suffix; - } - - /** - * 构建变量 不是* - * - * @param string $value - * @param array $params - * @param string $url - * @return string - */ - private function buildVars($value, &$params, $url) { - $keys = explode($this->keyValueSep, $value); - $values = array(); - foreach ($keys as $v) { - if (!isset($params[$v])) continue; - $values[] = $params[$v]; - unset($params[$v]); - } - return str_replace($keys, $values, $url); - } - - /** - * 构建rewriteurl的参数部分 - * @param array $params - * @param string $parentKey - * @param boolean $first 只有第一级的变量才加前缀 - * @return string - */ - private function buildCommonKeys($params, $parentKey = '', $first = true) { - $tmp = array(); - foreach ($params as $k => $v) { - if (is_int($k) && $this->keyPrefix != null && $first) { - $k = urlencode($this->keyPrefix . $k); - } - if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; - if (is_array($v)) { - array_push($tmp, $this->buildCommonKeys($v, $k, false)); - } else { - array_push($tmp, $k . $this->keyValueSep . urlencode($v)); - } - } - return implode($this->separator, $tmp); - } - - - /** - * 执行匹配 - * patterns中的匹配模式去匹配url中的信息 - * urlPatterns中可以根据需求将mca进行组合配置。 - * - m-c-a/* - htm - / - - - myvar_ - 1 - - * url-pattern中:*匹配表示其他的变量信息 - * 用户也可以将自己的其他信息添加到格式中比如m/c-a/tid/* - * suffix : url的后缀 - * separator: 变量分隔符 - * key-value-sep: key和value的分隔符,默认和separator一致 - * key-prefix: 数字索引的前缀 - * is-rewrite: 是否采用rewrite机制 - * - * 遍历url模式:采用separator配置的分隔符获得该模式数组 - * 如果模式是*,则代表该位置开始往后为为传递的变量信息 - * 如果模式不是*,则代表该位置为特殊模式。 - * 如果含有key-value-sep配置的分隔符: 则分别对url中相同key下的值和模式中的值分别做分割,对应的模式下获得的数组作为key,url中获得数组作为value - * 如果不含:则该值就作为Key,url对应位置上的值作为value - * - * @param string 待分析匹配的路径信息 - * @return array - */ - private function doParserUrl($url) { - if (!$url) return array(); - if (is_string($url)) { - $url = explode($this->separator, trim($url, $this->separator)); - } - $vars = array(); - foreach ($this->patterns as $key => $value) { - if ('*' == $value[0]) $this->parseCommonKey($key, $url, $vars); - else { - if (!isset($url[$key])) continue; - if (false === strrpos($value, $this->keyValueSep)) { - $vars[$value] = $url[$key]; - continue; - } - $keys = explode($this->keyValueSep, $value); - $values = explode($this->keyValueSep, $url[$key]); - foreach($keys as $pos =>$key) { - isset($values[$pos]) && $vars[$key] = $values[$pos]; - } - } - } - return $vars; - } - - /** - * 解析url普通参数 - * 如果separator和key-value-sep配置相同:则采用每两个元素为一对key-value的规则获得变量 - * 如果不相同:则将会以每个元素为key-value的组合,之间的分隔符以key-value-sep划分,如果没有该分隔符,则默认该值的索引为数字索引。 - * 如果为没有分隔符:则该值索引以数字索引给出,同时该数字索引将会根据用户是否配置key前缀key-prefix来给出key。 - * 如果有分隔符:则该值将会用分隔符分割获得的两个值来分别作为key和value. - * @param int $key - * @param array $urlParams - * @param array $params - */ - private function parseCommonKey($key, $urlParams, &$params) { - $pos = 0; - while (isset($urlParams[$key])) { - if ($this->separator == $this->keyValueSep) { - if (isset($urlParams[$key+1])) { - $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); - $key += 2; - } - continue; - } - if (false === strrpos($urlParams[$key], $this->keyValueSep)) { - $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); - $pos ++; - } else { - list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); - $this->parseKey($params, $k, urldecode($v)); - } - $key += 1; - } - } - - /** - * 解析url的parama信息中的key值 - * - * 如果key值不存在'[',']'字符,则该key为字符串,直接返回 - * 如果key值存在,并且'['和']'之前没有字符,则表示该key是将是一个数组,并且键值自增,返回array($key) - * 如果key值存在,并且'['和']'之前有字符,则表示该key是一个数组,并且'['和']'其中的字符是该数组中的键值,返回array(key值, 键值) - * - * //TODO 需要考虑多维数组的情况 - * @param string $key - * @return string|array 返回匹配的结果 - */ - private function parseKey(&$params, $key, $value) { - if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { - $params[$key] = $value; - return; - } - $name = substr($key, 0, $pos); - if ($pos2 === $pos + 1) { - $params[$name][] = $value; - return; - } else { - $key = substr($key, $pos + 1, $pos2 - $pos - 1); - $params[$name][$key] = $value; - return; - } - } - - /** - * 检查Url地址的正确性,并返回正确的URL地址 - * - * @param string $url - * @return string $url - */ - public function checkUrl($url) { - list($protocal, $serverName) = explode('://', $this->getUrlServer(false)); - $pos1 = stripos($url, $protocal); - $pos2 = stripos($url, $serverName); - if (false === $pos1 && false === $pos2) return $protocal . '://' . $serverName . '/' . ltrim($url, '/'); - if (false === $pos1) return $protocal . '://' . ltrim($url, '/'); - return $url; - } - - /* - * (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - $usrConfig = $this->getSystemConfig()->getConfig('router', 'rewrite'); - $usrConfig && $config = array_merge($config, $usrConfig); - parent::setConfig($config); - $this->urlPatttern = $this->getConfig('url-pattern'); - $this->separator = $this->getConfig('separator'); - $this->keyValueSep = $this->getConfig('key-value-sep'); - $this->keyValueSep == "" && $this->keyValueSep = $this->separator; - $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); - $this->isRewrite = $this->getConfig('is-rewrite'); - $this->keyPrefix = $this->getConfig('key-prefix'); - $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); - $this->getBaseUrl(); - } - - /** - * 返回域名及请求路径 - * - * @return string - */ - private function getBaseUrl() { - $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); - if (!$this->isRewrite()) - $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); - } - - /** - * 是否开启重写 - * - * @return boolean - */ - public function isRewrite() { - return $this->isRewrite == '1' || $this->isRewrite == 'true'; + public function createUrl($action, $controller = '', $params = array()) { + $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); + return $router->buildUrl($action, $controller, $params); } } ?> \ No newline at end of file From 61ad9f438decc22d49f7d406723fe9126e776697 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sat, 13 Aug 2011 06:01:18 +0000 Subject: [PATCH 0274/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2334 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/http/request/WindHttpRequest.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/wind/component/http/request/WindHttpRequest.php b/wind/component/http/request/WindHttpRequest.php index 38bfcb61..36841a6d 100644 --- a/wind/component/http/request/WindHttpRequest.php +++ b/wind/component/http/request/WindHttpRequest.php @@ -541,8 +541,7 @@ private function initRequestUri() { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; - if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace( - '/^\w+:\/\/[^\/]+/', '', $this->_requestUri); + if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; @@ -561,8 +560,7 @@ private function initRequestUri() { * @return */ private function _initScriptUrl() { - if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException( - __CLASS__ . ' determine the entry script URL failed!!!'); + if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; @@ -572,8 +570,7 @@ private function _initScriptUrl() { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; - } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( - 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { + } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); @@ -619,8 +616,8 @@ private function _initPathInfo() { elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else - throw new WindException(''); - if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, 0, $pos); + throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); + if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } \ No newline at end of file From 865ee34197f25d1002c1f439cde63a2ae2d244d8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sat, 13 Aug 2011 06:01:55 +0000 Subject: [PATCH 0275/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2335 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/http/response/WindHttpResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index 35ccef65..fda83ae0 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -478,7 +478,7 @@ private function _normalizeHeader($name) { /** * @return array */ - public function getData($key1 = '', $key2 = '', $encode = false) { + public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; From 39740111c1a005a92fa760089436c6af00a1f8ec Mon Sep 17 00:00:00 2001 From: yishuo Date: Sat, 13 Aug 2011 06:06:33 +0000 Subject: [PATCH 0276/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2336 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindController.php | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php index aaeaf094..4efab31e 100644 --- a/wind/core/web/WindController.php +++ b/wind/core/web/WindController.php @@ -30,14 +30,12 @@ public function run() {} final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { - $this->registerEventListener('doAction', - new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); + $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } - $this->registerEventListener('doAction', - new WindValidateListener($this->request, $rules, $this->getValidatorClass())); + $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } } @@ -54,21 +52,16 @@ protected function setDefaultTemplateName($handlerAdapter) { /* */ protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); - if ($action !== 'run') - $action = $this->resolvedActionName($action); + if ($action !== 'run') $action = $this->resolvedActionName($action); try { - if ($action == 'doAction') - throw new WindException('[core.web.WindController.resolvedActionMethod]', - WindException::ERROR_CLASS_METHOD_NOT_EXIST); + if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); $method = new ReflectionMethod($this, $action); - if ($method->isAbstract() || !$method->isPublic()) - throw new WindException('[core.web.WindController.resolvedActionMethod]', - WindException::ERROR_CLASS_METHOD_NOT_EXIST); + if ($method->isAbstract() || !$method->isPublic()) { + throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); + } return $action; } catch (Exception $exception) { - throw new WindException( - '[core.web.WindController.resolvedActionMethod] action method:' . $action . ' exception message:' . - $exception->getMessage()); + throw new WindException('[core.web.WindController.resolvedActionMethod] ' . $exception->getMessage()); } } From d26696d265170370611be62c6888478f19518d44 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sat, 13 Aug 2011 08:03:18 +0000 Subject: [PATCH 0277/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2337 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/upload/WindCurlUpload.php | 41 +++++++++++++++--------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/wind/component/upload/WindCurlUpload.php b/wind/component/upload/WindCurlUpload.php index 447f3fa5..65931c06 100644 --- a/wind/component/upload/WindCurlUpload.php +++ b/wind/component/upload/WindCurlUpload.php @@ -1,23 +1,32 @@ - * @author Qian Su * @version $Id: WindCurlUpload.php 1710 2011-03-08 12:09:38Z weihu $ * @package * tags - */ -class WindCurlUpload extends AbstractWindUpload{ - - public function upload($newName, $path) { - - } - - public function hasError() { - - } - - public function getErrorInfo($type = '') { - - } - + */ +class WindCurlUpload extends AbstractWindUpload { + + public function upload($newName, $path) { + + } + + public function hasError() { + + } + + public function getErrorInfo($type = '') { + + } + + /* (non-PHPdoc) + * @see AbstractWindUpload::postUpload() + */ + protected function postUpload($tmp_name, $filename) { + // TODO Auto-generated method stub + + + } + } \ No newline at end of file From 5404a238235d9f546030d8ccebf00d5ac76a59a4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sat, 13 Aug 2011 11:19:17 +0000 Subject: [PATCH 0278/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2338 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindSystemConfig.php | 97 +++++++++++++++++++----------- 1 file changed, 63 insertions(+), 34 deletions(-) diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index ddff8e4f..9f07c56f 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -8,26 +8,28 @@ */ class WindSystemConfig extends WindModule { private $appName = ''; + private $modules = array(); /** * @param string $config * @param string $appName * @param WindFactory $factory */ - public function __construct($config, $appName, $factory) { + public function __construct($config, $appName) { $this->appName = $appName; - $this->setConfig($config, $factory); + $this->setConfig($config); } /* (non-PHPdoc) * @see WindModule::setConfig() */ - public function setConfig($config, $factory = null) { + public function setConfig($config) { + if (empty($config)) return; if (is_string($config)) { - $config = $this->parseConfig($config, 'config', '', $factory); + $config = $this->parseConfig($config, 'config', ''); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else - $this->_config = (array) $config; + $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } /** @@ -79,14 +81,6 @@ public function getRouter() { return $this->getConfig('router'); } - /** - * 返回当前路由的配置信息 - * @return array - */ - public function getRouterConfig() { - return $this->getConfig('router', 'config'); - } - /** * 返回路由类型定义 * @return string @@ -120,7 +114,37 @@ public function getRouterClass() { * @return array|string */ public function getModules($name = '') { - return $this->getConfig('modules', $name); + if ($name === '') return $this->modules + $this->getConfig('modules', '', array()); + return isset($this->modules[$name]) ? $this->modules[$name] : $this->getConfig('modules', $name, array()); + } + + /** + * 添加module + * controller + * + * Controller + * + * WIND:core.web.WindErrorHandler + * + * + * + * + * + * template + * + * htm + * + * data.template + * + * + * + * @param string $name + * @param array $config + */ + public function setModules($name, $config) { + if (empty($config)) return; + if (isset($this->modules[$name]) || $this->getConfig('modules', $name)) throw new WindException('[core.web.WindSystemConfig] module name already exist.'); + $this->modules[$name] = array_merge($this->getDefaultConfigStruct('modules'), $config); } /** @@ -128,9 +152,8 @@ public function getModules($name = '') { * @param string $name * @param string $default */ - public function getModuleViewClassByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $module ? $this->getConfig('view', 'class', $default, $module) : ''; + public function getModuleViewClass($name, $default = '') { + return $this->getConfig('view', 'class', $default, $this->getModules($name)); } /** @@ -138,9 +161,8 @@ public function getModuleViewClassByModuleName($name, $default = '') { * @param string $name * @param string $default */ - public function getModuleViewConfigByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $module ? $this->getConfig('view', 'config', $default, $module) : ''; + public function getModuleViewConfig($name, $default = '') { + return $this->getConfig('view', 'config', $default, $this->getModules($name)); } /** @@ -149,9 +171,8 @@ public function getModuleViewConfigByModuleName($name, $default = '') { * @param string $default * @return string */ - public function getModuleErrorHandlerByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $module ? $this->getConfig('error-handler', '', $default, $module) : ''; + public function getModuleErrorHandler($name, $default = '') { + return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } /** @@ -159,9 +180,8 @@ public function getModuleErrorHandlerByModuleName($name, $default = '') { * @param string $name * @return string */ - public function getModuleControllerPathByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $module ? $this->getConfig('controller-path', '', $default, $module) : ''; + public function getModuleControllerPath($name, $default = '') { + return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } /** @@ -169,9 +189,8 @@ public function getModuleControllerPathByModuleName($name, $default = '') { * @param string $name * @return string */ - public function getModuleControllerSuffixByModuleName($name, $default = '') { - $module = $this->getConfig('modules', $name); - return $module ? $this->getConfig('controller-suffix', '', $default, $module) : ''; + public function getModuleControllerSuffix($name, $default = '') { + return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } /** @@ -196,15 +215,25 @@ public function getDbConfig($dbName = '') { * @param string|boolean $append * @param factory */ - private function parseConfig($config, $key = 'config', $append = true, $factory = null) { + private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); - - if ($factory === null) $factory = $this->getSystemFactory(); + $factory = $this->getSystemFactory(); $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); $append === true && $append = $this->appName . '_config'; - $config = $configParser->parse($config, $this->appName . '_' . $key, $append, - $factory->getInstance(COMPONENT_CACHE)); + $config = $configParser->parse($config, $this->appName . '_' . $key, $append, $factory->getInstance(COMPONENT_CACHE)); return $config; } + /** + * 返回对应的配置结构及默认值 + * @param string $configName + * @throws WindException + * @return string + */ + public function getDefaultConfigStruct($configName) { + $_tmp = array(); + $_tmp['modules'] = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', + 'error-handler' => 'WIND:core.web.WindErrorHandler', 'view' => array('class' => COMPONENT_VIEW)); + return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); + } } \ No newline at end of file From 5e2b8b979eba1ce18b003f2790168ba2bbdfe4b4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:48:53 +0000 Subject: [PATCH 0279/1065] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2339 18ba2127-5a84-46d4-baec-3457e417f034 --- .../router/route/AbstractWindRoute.php | 44 +++++++++++++++ .../router/route/WindRewriteRoute.php | 31 +++++++++++ wind/component/router/route/WindRoute.php | 53 +++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 wind/component/router/route/AbstractWindRoute.php create mode 100644 wind/component/router/route/WindRewriteRoute.php create mode 100644 wind/component/router/route/WindRoute.php diff --git a/wind/component/router/route/AbstractWindRoute.php b/wind/component/router/route/AbstractWindRoute.php new file mode 100644 index 00000000..2ee3e8c4 --- /dev/null +++ b/wind/component/router/route/AbstractWindRoute.php @@ -0,0 +1,44 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindRoute extends WindHandlerInterceptor { + + /** + * 根据匹配的路由规则,构建Url + * + * @return string + */ + abstract public function build(); + + /** + * 路由规则匹配方法,返回匹配到的参数列表 + * + * @return array + */ + abstract public function match(); + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::handle() + */ + public function handle() { + $args = func_get_args(); + $this->result = call_user_func_array(array($this, 'match'), $args); + if ($this->result !== null) { + return $this->result; + } + if (null !== ($handler = $this->interceptorChain->getHandler())) { + $this->result = call_user_func_array(array($handler, 'handle'), $args); + } else { + $this->result = $this->interceptorChain->execute(); + } + call_user_func_array(array($this, 'postHandle'), $args); + return $this->result; + } + +} + +?> \ No newline at end of file diff --git a/wind/component/router/route/WindRewriteRoute.php b/wind/component/router/route/WindRewriteRoute.php new file mode 100644 index 00000000..3a9eeb86 --- /dev/null +++ b/wind/component/router/route/WindRewriteRoute.php @@ -0,0 +1,31 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindRewriteRoute extends AbstractWindRoute { + + /* (non-PHPdoc) + * @see AbstractWindRoute::build() + */ + public function build() { + // TODO Auto-generated method stub + + + } + + /* (non-PHPdoc) + * @see AbstractWindRoute::match() + */ + public function match() { + // TODO Auto-generated method stub + + + } + +} + +?> \ No newline at end of file diff --git a/wind/component/router/route/WindRoute.php b/wind/component/router/route/WindRoute.php new file mode 100644 index 00000000..98a44499 --- /dev/null +++ b/wind/component/router/route/WindRoute.php @@ -0,0 +1,53 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindRoute extends AbstractWindRoute { + /** + * 属性名称 + * + * @var array + */ + protected $params = array(); + /** + * 正则表达式 + * + * @var string + */ + protected $pattern; + /** + * 用于反响生成Url的表达式 + * + * @var string + */ + protected $reverse; + + /* (non-PHPdoc) + * @see IWindRoute::match() + */ + public function match() { + //TODO + } + + /* (non-PHPdoc) + * @see IWindRoute::build() + */ + public function build() { + // TODO Auto-generated method stub + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setParams($this->getConfig('params')); + $this->setPattern($this->getConfig('pattern')); + $this->setReverse($this->getConfig('reverse')); + } + +} +?> \ No newline at end of file From 01420ee648f52bdb9118f94e1011f078f8f20214 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:49:16 +0000 Subject: [PATCH 0280/1065] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2340 18ba2127-5a84-46d4-baec-3457e417f034 --- .../filter/WindHandlerInterceptorChain.php | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/wind/component/filter/WindHandlerInterceptorChain.php b/wind/component/filter/WindHandlerInterceptorChain.php index e95a8861..71a5f316 100644 --- a/wind/component/filter/WindHandlerInterceptorChain.php +++ b/wind/component/filter/WindHandlerInterceptorChain.php @@ -9,7 +9,7 @@ class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); - protected $_state = true; + protected $_state = 0; /** * 设置回调方法 @@ -30,9 +30,11 @@ public function setCallBack($callBack, $args = array()) { * @return void|mixed */ public function execute() { - if ($this->_callBack === null) return null; + if ($this->_callBack === null) + return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { - throw new WindException('[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, + throw new WindException( + '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); @@ -44,19 +46,16 @@ public function execute() { * @return WindHandlerInterceptor */ public function getHandler() { - if ($this->_state) { + if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); - $this->_state = false; } - if (count($this->_interceptors) <= 0) return null; - $handler = array_shift($this->_interceptors); + if ($this->_state >= count($this->_interceptors)) + return null; + $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } - Wind::log( - '[core.filter.WindHandlerInterceptorChain.getHandler] the type of Interceptor ' . gettype($handler) . - ' is not supported.', WindLogger::LEVEL_DEBUG, 'wind.core'); return $this->getHandler(); } @@ -72,7 +71,7 @@ public function addInterceptors($interceptors) { else $this->_interceptors[] = $interceptors; } - + /** * 重置初始化信息 * @return boolean @@ -81,7 +80,7 @@ public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); - $this->_state = true; + $this->_state = 0; return true; } } From 68a76ea4f3712424bf227c4f6c8c9c71ed9d4f40 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:49:45 +0000 Subject: [PATCH 0281/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2341 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/http/response/WindHttpResponse.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index fda83ae0..a4373521 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -363,6 +363,7 @@ public function sendError($status = self::SC_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); + $this->sendResponse(); } /** From c700f61dfda95c4b93dafb68fa5989761970cc04 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:50:09 +0000 Subject: [PATCH 0282/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2342 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/parser/WindConfigParser.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index 072b02bc..01d7807e 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -79,7 +79,6 @@ private function setCache($alias, $append, $cache, $data) { * @return array */ private function getCache($alias, $append, $cache) { - if (IS_DEBUG) return array(); if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); From 85947dcd3a09bf4f253913fc985a7a5f984ba843 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:50:27 +0000 Subject: [PATCH 0283/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2343 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/compile.php | 7 ++--- wind/_compile/components_config.xml | 43 +++++++++-------------------- 2 files changed, 16 insertions(+), 34 deletions(-) diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php index e470d0e3..e4a9377c 100644 --- a/wind/_compile/compile.php +++ b/wind/_compile/compile.php @@ -30,17 +30,16 @@ } $pack->packFromFileList($fileList, _COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); /* import信息写入编译文件 */ -WindFile::write(_COMPILE_PATH . 'wind_imports.php', 'parse(_COMPILE_PATH . 'components_config.xml'); WindFile::write($_systemConfig, ' + - - - - - - - - + + + - - - - - - - m/c-a/* - - htm - - / - - - - - myvar_ - 1 - - - + - + @@ -71,7 +51,8 @@ - + @@ -81,9 +62,11 @@ + + From cf3c4a06ec11f760deda7a8d68091d2426528cab Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:50:39 +0000 Subject: [PATCH 0284/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2344 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/utility/WindUtility.php | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/wind/component/utility/WindUtility.php b/wind/component/utility/WindUtility.php index fcfd1050..c6edf86c 100644 --- a/wind/component/utility/WindUtility.php +++ b/wind/component/utility/WindUtility.php @@ -9,6 +9,24 @@ */ class WindUtility { + /** + * 递归合并两个数组 + * + * @param array $array1 + * @param array $array2 + * @return array + */ + public static function mergeArray($array1, $array2) { + foreach ($array2 as $key => $value) { + if (!isset($array1[$key]) || !is_array($array1[$key])) { + $array1[$key] = $value; + continue; + } + $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); + } + return $array1; + } + /** * 将字符串首字母小写 * @@ -16,7 +34,8 @@ class WindUtility { * @return string */ public static function lcfirst($str) { - if (function_exists('lcfirst')) return lcfirst($str); + if (function_exists('lcfirst')) + return lcfirst($str); $str[0] = strtolower($str[0]); return $str; @@ -54,8 +73,8 @@ public static function generateRandStr($length) { * @return array */ public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { - return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, - 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); + return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, + 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } From 95d59f666d94d55682869097158f2cac5c9199a8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:51:16 +0000 Subject: [PATCH 0285/1065] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2345 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/AbstractWindRouter.php | 218 ++++++++---------- wind/component/router/WindRouter.php | 40 ++++ wind/component/router/WindUrlBasedRouter.php | 65 ------ .../component/router/WindUrlRewriteRouter.php | 105 +++++---- 4 files changed, 205 insertions(+), 223 deletions(-) create mode 100644 wind/component/router/WindRouter.php delete mode 100644 wind/component/router/WindUrlBasedRouter.php diff --git a/wind/component/router/AbstractWindRouter.php b/wind/component/router/AbstractWindRouter.php index 8a64b376..340e5065 100644 --- a/wind/component/router/AbstractWindRouter.php +++ b/wind/component/router/AbstractWindRouter.php @@ -9,145 +9,90 @@ * @version $Id$ * @package */ -abstract class AbstractWindRouter extends WindModule { - const DEFAULT_ERROR_HANDLER = 'WIND:core.web.WindErrorHandler'; - const CONTROLLER_DEFAULT_PATH = 'controller'; - const CONTROLLER_DEFAULT_SUFFIX = 'Controller'; - /** - * 默认的处理方法‘run’ - * - * @var string - */ - private $action = 'run'; - /** - * 默认的控制器‘index’ - * - * @var string - */ - private $controller = 'index'; - /** - * 默认的系统应用模块名为‘default’ - * - * @var string - */ - private $module = 'default'; - /** - * 系统应用模块寻址路径 - * - * @var string - */ - protected $modulePath = ''; +abstract class AbstractWindRouter extends WindHandlerInterceptorChain { + protected $moduleKey = 'm'; + protected $controllerKey = 'c'; + protected $actionKey = 'a'; + protected $module = 'default'; + protected $controller = 'index'; + protected $action = 'run'; - private $reParse = true; + protected $currentRoute = null; /** - * 该方法定义了路由解析策略 - * @return string | actionHandler + * 解析请求参数,并返回路由结果 + * @return string */ - abstract public function parse(); + abstract public function route(); /** - * 构建Url并返回 + * 创建Url,并返回 * @return string */ - abstract public function buildUrl(); + abstract public function assemble(); - /** - * 通过调用该方法返回,解析请求参数,并返回路由结果 - * - * @return + /* (non-PHPdoc) + * @see WindModule::setConfig() */ - public function doParse() { - if ($this->reParse) { - $this->parse(); - $this->reParse = false; - } - $_moduleName = $this->getModule(); - if (!$this->getSystemConfig()->getModules($_moduleName)) { - throw new WindException('[core.roter.AbstractWindRouter.doParse] module error: error module :' . $_moduleName); - } - if (!strcasecmp($this->getController(), 'windError')) { - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log( - '[core.roter.AbstractWindRouter.doParse] action hander: default error action :' . - self::DEFAULT_ERROR_HANDLER, WindLogger::LEVEL_DEBUG, 'wind.core'); - } - return $this->getSystemConfig()->getModuleErrorHandlerByModuleName($_moduleName, - self::DEFAULT_ERROR_HANDLER); - } - $_suffix = $this->getSystemConfig()->getModuleControllerSuffixByModuleName($_moduleName, - self::CONTROLLER_DEFAULT_SUFFIX); - if ($this->modulePath) - $_path = $this->modulePath; - else { - $_path = $this->getSystemConfig()->getModuleControllerPathByModuleName($_moduleName, - self::CONTROLLER_DEFAULT_PATH); - } - $_path .= '.' . ucfirst($this->controller) . $_suffix; - if (strpos($_path, ':') === false) - $_path = Wind::getAppName() . ':' . $_path; - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.router.AbstractWindRouter.doParse] action handler: ' . $_path, WindLogger::LEVEL_DEBUG, - 'wind.core'); + public function setConfig($config) { + parent::setConfig($config); + if ($this->_config) { + $this->module = $this->getConfig('module', 'default-value', $this->module); + $this->controller = $this->getConfig('controller', 'default-value', $this->controller); + $this->action = $this->getConfig('action', 'default-value', $this->action); + $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); + $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); + $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } - $this->destroy(); - return $_path; } /** - * @return - */ - protected function destroy() { - $this->modulePath = ''; + * 设置路由变量信息 + * + * @param string $params + */ + protected function setParams($params) { + foreach ($params as $key => $value) { + $this->getRequest()->setAttribute($value, $key); + if ($this->actionKey === $key) + $this->setAction($value); + elseif ($this->controllerKey === $key) + $this->setController($value); + elseif ($this->moduleKey === $key) + $this->setModule($value); + } } /** - * 设置module信息, 支持格式: - * 'moduleName'; - * 'namespace:modulePath' - * - * @param string $module - * @return + * 添加路由协议对象,如果添加的路由协议已经存在则抛出异常 + * @param Object $routeInstance + * @throws WindException + * @return */ - public function setModule($module) { - if (false !== ($pos = strpos($module, ':'))) { - $this->modulePath = $module; - } else { - $this->module = $module; - $this->modulePath = ''; - } + public function addRoute($routeInstance, $current = false) { + if ($current) + $this->currentRoute = $routeInstance; + $this->addInterceptors($routeInstance); } - /** + /** * 获得业务操作 - * - * @return string + * @return string */ public function getAction() { return $this->action; } - /** + /** * 获得业务对象 - * - * @return string + * @return string */ public function getController() { return $this->controller; } - /** - * 返回一组应用入口 - * - * @return string - */ - public function getModule() { - return $this->module; - } - /** * 设置action信息 - * * @param string $action * @return */ @@ -157,7 +102,6 @@ public function setAction($action) { /** * 设置controller信息 - * * @param string $controller * @return */ @@ -166,21 +110,59 @@ public function setController($controller) { } /** - * @param boolean $reParse - * @return + * @return the $module */ - public function reParse() { - $this->reParse = true; + public function getModule() { + return $this->module; } - - /* - * (non-PHPdoc) - * @see WindModule::setConfig() + + /** + * @param string $module */ - public function setConfig($config) { - $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); - $usrConfig && $config = array_merge($config, $usrConfig); - parent::setConfig($config); + public function setModule($module) { + $this->module = $module; + } + + /** + * @return the $moduleKey + */ + public function getModuleKey() { + return $this->moduleKey; + } + + /** + * @return the $controllerKey + */ + public function getControllerKey() { + return $this->controllerKey; + } + + /** + * @return the $actionKey + */ + public function getActionKey() { + return $this->actionKey; + } + + /** + * @param field_type $moduleKey + */ + public function setModuleKey($moduleKey) { + $this->moduleKey = $moduleKey; + } + + /** + * @param field_type $controllerKey + */ + public function setControllerKey($controllerKey) { + $this->controllerKey = $controllerKey; + } + + /** + * @param field_type $actionKey + */ + public function setActionKey($actionKey) { + $this->actionKey = $actionKey; } } \ No newline at end of file diff --git a/wind/component/router/WindRouter.php b/wind/component/router/WindRouter.php new file mode 100644 index 00000000..dafc0a93 --- /dev/null +++ b/wind/component/router/WindRouter.php @@ -0,0 +1,40 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindRouter extends AbstractWindRouter { + + /* (non-PHPdoc) + * @see IWindRouter::route() + */ + public function route() { + $this->setCallBack(array($this, 'defaultRoute')); + $params = $this->getHandler()->handle(); + $this->setParams($params); + } + + /* (non-PHPdoc) + * @see AbstractWindRouter::assemble() + */ + public function assemble() { + // TODO Auto-generated method stub + } + + /** + * 默认路由规则 + */ + public function defaultRoute() { + $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); + $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, + $this->controller); + $params[$this->moduleKey] = $this->getRequest()->getRequest($this->module, $this->module); + return $params; + } + +} + +?> \ No newline at end of file diff --git a/wind/component/router/WindUrlBasedRouter.php b/wind/component/router/WindUrlBasedRouter.php deleted file mode 100644 index ed06ef14..00000000 --- a/wind/component/router/WindUrlBasedRouter.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @link WRouteParser - * @package - */ -class WindUrlBasedRouter extends AbstractWindRouter { - /* url 路由参数规则 */ - const URL_PARAM = 'url-param'; - const DEFAULT_VALUE = 'default-value'; - /* 后缀名参数规则 */ - const CONTROLLER_SUFFIX = 'controller-suffix'; - const ACTION_SUFFIX = 'action-suffix'; - /* 路由信息 */ - const URL_RULE_MODULE = 'module'; - const URL_RULE_CONTROLLER = 'controller'; - const URL_RULE_ACTION = 'action'; - - /* (non-PHPdoc) - * @see AbstractWindRouter::parse() - */ - public function parse() { - $urlHelper = $this->getSystemFactory()->getInstance(COMPONENT_URLHELPER); - $urlHelper->parseUrl(); - $this->setModule($this->getUrlParamValue(self::URL_RULE_MODULE, $this->getModule())); - $this->setController($this->getUrlParamValue(self::URL_RULE_CONTROLLER, $this->getController())); - $this->setAction($this->getUrlParamValue(self::URL_RULE_ACTION, $this->getAction())); - } - - /* (non-PHPdoc) - * @see AbstractWindRouter::buildUrl() - */ - public function buildUrl() { - $module = $this->getConfig(self::URL_RULE_MODULE, self::URL_PARAM); - $controller = $this->getConfig(self::URL_RULE_CONTROLLER, self::URL_PARAM); - $action = $this->getConfig(self::URL_RULE_ACTION, self::URL_PARAM); - $url = '?' . $module . '=' . $this->getModule(); - $url .= '&' . $controller . '=' . $this->getController(); - $url .= '&' . $action . '=' . $this->getAction(); - return $url; - } - - /** - * 返回路由的配置信息 - * - * @param urlParam - * @param defaultValue - * @return string - */ - private function getUrlParamValue($type, $defaultValue = '') { - if ($_param = $this->getConfig($type, self::URL_PARAM)) { - $_defaultValue = $this->getConfig($type, self::DEFAULT_VALUE, $defaultValue); - $tmp = $this->getRequest()->getRequest($_param, $defaultValue); - return !$tmp ? $defaultValue : $tmp; - } - return $defaultValue; - } -} \ No newline at end of file diff --git a/wind/component/router/WindUrlRewriteRouter.php b/wind/component/router/WindUrlRewriteRouter.php index 503e77ac..a81058bb 100644 --- a/wind/component/router/WindUrlRewriteRouter.php +++ b/wind/component/router/WindUrlRewriteRouter.php @@ -16,7 +16,7 @@ class WindUrlRewriteRouter extends AbstractWindRouter { private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); - + /** * 是否开启重写 * @@ -25,7 +25,7 @@ class WindUrlRewriteRouter extends AbstractWindRouter { public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } - + /* * (non-PHPdoc) * @see AbstractWindRouter::parse() @@ -36,7 +36,7 @@ public function parse() { $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } - + /** * 解析Url * @@ -45,9 +45,10 @@ public function parse() { * 同时设置到超全局变量$_GET中 */ public function parseUrl() { - if (!$this->isRewrite()) return; + if (!$this->isRewrite()) + return; $url = array(); - if ($this->getRequest()->getServer('SERVER_PROTOCOL')) {//http协议 + if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { //http协议 $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); @@ -60,7 +61,7 @@ public function parseUrl() { } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); - } else {// 命令行下 + } else { // 命令行下 $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { @@ -72,7 +73,7 @@ public function parseUrl() { !isset($_GET[$k]) && $_GET[$k] = $v; } } - + /** * 构造返回Url地址 * @@ -89,9 +90,10 @@ public function buildUrl($action = '', $controller = '', $params = array()) { $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); - return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query($params, '', '&'); + return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( + $params, '', '&'); } - + /** * 解析module, controller, action * 如果不存在该值,则采用配置的默认值 @@ -108,6 +110,7 @@ private function resolveMvc($action, $controller) { !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } + /** * 构造重写的url * @param string $m @@ -125,9 +128,9 @@ private function buildRewriteUrl($params) { $url = $this->buildVars($value, $params, $url); } } - return $this->baseUrl . '/' . $url . $this->suffix; + return $this->baseUrl . '/' . $url . $this->suffix; } - + /** * 构建变量 不是* * @@ -140,13 +143,14 @@ private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { - if (!isset($params[$v])) continue; + if (!isset($params[$v])) + continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } - + /** * 构建rewriteurl的参数部分 * @param array $params @@ -156,27 +160,27 @@ private function buildVars($value, &$params, $url) { */ private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); - foreach ($params as $k => $v) { - if (is_int($k) && $this->keyPrefix != null && $first) { - $k = urlencode($this->keyPrefix . $k); - } - if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; - if (is_array($v)) { - array_push($tmp, $this->buildNomalKeys($v, $k, false)); - } else { - array_push($tmp, $k . $this->keyValueSep . urlencode($v)); - } - } + foreach ($params as $k => $v) { + if (is_int($k) && $this->keyPrefix != null && $first) { + $k = urlencode($this->keyPrefix . $k); + } + if (!empty($parentKey)) + $k = $parentKey . '[' . $k . ']'; + if (is_array($v)) { + array_push($tmp, $this->buildNomalKeys($v, $k, false)); + } else { + array_push($tmp, $k . $this->keyValueSep . urlencode($v)); + } + } return implode($this->separator, $tmp); } - /** * 执行匹配 * patterns中的匹配模式去匹配url中的信息 * urlPatterns中可以根据需求将mca进行组合配置。 * - m-c-a/* + * htm / - @@ -194,42 +198,45 @@ private function buildNomalKeys($params, $parentKey = '', $first = true) { * 遍历url模式:采用separator配置的分隔符获得该模式数组 * 如果模式是*,则代表该位置开始往后为为传递的变量信息 * 如果模式不是*,则代表该位置为特殊模式。 - * 如果含有key-value-sep配置的分隔符: 则分别对url中相同key下的值和模式中的值分别做分割,对应的模式下获得的数组作为key,url中获得数组作为value - * 如果不含:则该值就作为Key,url对应位置上的值作为value + * 如果含有key-value-sep配置的分隔符: 则分别对url中相同key下的值和模式中的值分别做分割,对应的模式下获得的数组作为key,url中获得数组作为value + * 如果不含:则该值就作为Key,url对应位置上的值作为value * * @param string 待分析匹配的路径信息 * @return array */ private function doParserUrl($url) { - if (!$url) return array(); + if (!$url) + return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { - if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); + if ('*' == $value[0]) + $this->parseNomalKeys($key, $url, $vars); else { - if (!isset($url[$key])) continue; + if (!isset($url[$key])) + continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); - foreach($keys as $pos =>$key) { + foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } - + /** * 解析url普通参数 * 如果separator和key-value-sep配置相同:则采用每两个元素为一对key-value的规则获得变量 * 如果不相同:则将会以每个元素为key-value的组合,之间的分隔符以key-value-sep划分,如果没有该分隔符,则默认该值的索引为数字索引。 - * 如果为没有分隔符:则该值索引以数字索引给出,同时该数字索引将会根据用户是否配置key前缀key-prefix来给出key。 - * 如果有分隔符:则该值将会用分隔符分割获得的两个值来分别作为key和value. + * 如果为没有分隔符:则该值索引以数字索引给出,同时该数字索引将会根据用户是否配置key前缀key-prefix来给出key。 + * 如果有分隔符:则该值将会用分隔符分割获得的两个值来分别作为key和value. * @param int $key * @param array $urlParams * @param array $params @@ -238,7 +245,7 @@ private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { - if (isset($urlParams[$key+1])) { + if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } @@ -246,7 +253,7 @@ private function parseNomalKeys($key, $urlParams, &$params) { } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); - $pos ++; + $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); @@ -281,7 +288,7 @@ private function parseKey(&$params, $key, $value) { return; } } - + /* * (non-PHPdoc) * @see WindModule::setConfig() @@ -299,10 +306,10 @@ public function setConfig($config) { $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); - if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); + if (!$this->isRewrite()) + $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } - /** * 返回路由的配置信息 * @@ -319,4 +326,22 @@ private function getUrlParamValue($type, $defaultValue = '') { return $defaultValue; } + /* (non-PHPdoc) + * @see AbstractWindRouter::route() + */ + public function route() { + // TODO Auto-generated method stub + + + } + + /* (non-PHPdoc) + * @see AbstractWindRouter::assemble() + */ + public function assemble() { + // TODO Auto-generated method stub + + + } + } From 4325a3d2b58366fd53aa956042bed470f5eeba32 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:52:01 +0000 Subject: [PATCH 0286/1065] =?UTF-8?q?=E4=BF=AE=E6=94=B9application?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2346 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/IWindApplication.php | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/wind/core/IWindApplication.php b/wind/core/IWindApplication.php index aa44406d..857e3d21 100644 --- a/wind/core/IWindApplication.php +++ b/wind/core/IWindApplication.php @@ -8,17 +8,35 @@ interface IWindApplication { /** - * 请求处理 - * @param IWindHttpRequest $request - * @param IWindHttpResponse $response + * Enter description here ... + * @return */ - public function processRequest(); + public function run(); /** * 请求转发 - * * @param WindForward $forward */ public function doDispatch($forward); + + /** + * @return WindHttpRequest $request + */ + public function getRequest(); + + /** + * @return WindHttpResponse $response + */ + public function getResponse(); + + /** + * @return WindSystemConfig $windSystemConfig + */ + public function getWindSystemConfig(); + + /** + * @return WindFactory $windFactory + */ + public function getWindFactory(); } ?> \ No newline at end of file From 0164fac6a5728aa3f6febbd1526b3b1f414cd22e Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:52:35 +0000 Subject: [PATCH 0287/1065] =?UTF-8?q?=E4=BF=AE=E6=94=B9application?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2347 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 93 +++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 30 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 0fdfc5f0..271b2bc6 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -1,4 +1,5 @@ instances[$alias])) return $this->instances[$alias]; - if (!($definition = $this->checkAlias($alias))) return null; + if (isset($this->prototype[$alias])) + return clone $this->prototype[$alias]; + if (isset($this->instances[$alias])) + return $this->instances[$alias]; + if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) + return null; $this->buildDefinition($definition); $_constructorArgs = $definition['constructorArgs']; foreach ($_constructorArgs as $_var) { @@ -54,10 +49,14 @@ public function getInstance($alias, $args = array()) { } $config = $this->buildConfig($definition, $alias); $instance = $this->createInstance($definition['className'], $args); - if (!empty($config)) $instance->setConfig($config); - if ($definition['properties']) $this->buildProperties($definition['properties'], $instance); - if ($definition['initMethod']) $this->executeInitMethod($definition['initMethod'], $instance); - if ($definition['proxy']) $instance = $this->setProxyForClass($definition['proxy'], $instance); + if (!empty($config)) + $instance->setConfig($config); + if ($definition['properties']) + $this->buildProperties($definition['properties'], $instance); + if ($definition['initMethod']) + $this->executeInitMethod($definition['initMethod'], $instance); + if ($definition['proxy']) + $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; @@ -69,7 +68,8 @@ public function getInstance($alias, $args = array()) { static public function createInstance($className, $args = array()) { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); + Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, + WindLogger::LEVEL_DEBUG, 'core.factory'); } if (empty($args)) return new $className(); @@ -86,9 +86,7 @@ static public function createInstance($className, $args = array()) { * @see IWindFactory::getPrototype() */ public function getPrototype($alias) { - $instance = $this->getInstance($alias); - if ($instance === null) return null; - return clone $instance; + return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } /** @@ -99,10 +97,35 @@ public function getPrototype($alias) { * @return */ public function addClassDefinitions($alias, $classDefinition) { - if (isset($this->classDefinitions[$alias])) return; + if (!is_string($alias) || empty($alias)) { + throw new WindException( + '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', + WindException::ERROR_PARAMETER_TYPE_ERROR); + } + if (isset($this->classDefinitions[$alias])) + return; $this->classDefinitions[$alias] = $classDefinition; } + /** + * 加载类定义,如果merge为true,则覆盖原有配置信息 + * + * @param array $classDefinitions + * @param boolean $merge + * @return + */ + public function loadClassDefinitions($classDefinitions, $merge = true) { + foreach ((array) $classDefinitions as $alias => $definition) { + if (!isset($this->classDefinitions[$alias]) || $merge === false) { + $this->classDefinitions[$alias] = $definition; + continue; + } + $this->classDefinitions[$alias] = WindUtility::mergeArray( + $this->classDefinitions[$alias], $definition); + unset($this->instances[$alias], $this->prototype[$alias]); + } + } + /** * 类定义检查,检查类型以是否已经存在 * @@ -110,7 +133,11 @@ public function addClassDefinitions($alias, $classDefinition) { * @return boolean */ public function checkAlias($alias) { - return isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : false; + if (isset($this->prototype[$alias])) + return true; + elseif (isset($this->instances[$alias])) + return true; + return false; } /** @@ -121,6 +148,7 @@ public function checkAlias($alias) { protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': + $this->prototype[$alias] = $instance; break; case 'application': $this->instances[$alias] = $instance; @@ -140,7 +168,8 @@ protected function setScope($alias, $scope, $instance) { * @return */ protected function buildConfig(&$definition, $alias) { - if (!($config = $definition['config'])) return array(); + if (!($config = $definition['config'])) + return array(); if (isset($config['resource']) && !empty($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance(COMPONENT_CONFIGPARSER); @@ -165,7 +194,9 @@ protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { - throw new WindException('[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); + throw new WindException( + '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } @@ -177,8 +208,9 @@ protected function executeInitMethod($initMethod, $instance) { * @return WindClassProxy */ protected function setProxyForClass($proxy, $instance) { - if ($proxy === 'false' || $proxy === false) return $instance; - $proxy = Wind::import(self::WIND_PROXY); + if ($proxy === 'false' || $proxy === false) + return $instance; + $proxy = Wind::import($this->proxyType); return $this->createInstance($proxy, array($instance)); } @@ -216,8 +248,9 @@ protected function buildProperties($properties, $instance) { * @return boolean */ private function buildDefinition(&$definition) { - $_definition = array('path' => '', 'className' => '', 'factoryMethod' => '', 'initMethod' => '', - 'scope' => 'application', 'proxy' => false, 'properties' => array(), 'config' => array(), 'constructorArgs' => array()); + $_definition = array('path' => '', 'className' => '', 'factoryMethod' => '', + 'initMethod' => '', 'scope' => 'application', 'proxy' => false, 'properties' => array(), + 'config' => array(), 'constructorArgs' => array()); $definition = array_merge($_definition, $definition); $definition['className'] = Wind::import($definition['path']); } From 499ef8c3b35390db467fd576ab057954e0255552 Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:53:18 +0000 Subject: [PATCH 0288/1065] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=EF=BC=8C=20=E6=9A=82=E6=97=B6=E8=BF=98?= =?UTF-8?q?=E4=B8=BA=E5=88=86=E7=A6=BB=EF=BC=8Capplication=20run?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2348 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 122 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 94 insertions(+), 28 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index fbf918ef..305b462a 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -6,6 +6,7 @@ define('D_S', DIRECTORY_SEPARATOR); define('WIND_PATH', dirname(__FILE__) . D_S); !defined('COMPILE_PATH') && define('COMPILE_PATH', WIND_PATH . D_S); + /* debug/log */ !defined('IS_DEBUG') && define('IS_DEBUG', 1); !defined('LOG_DIR') && define('LOG_DIR', COMPILE_PATH . 'log'); @@ -39,8 +40,18 @@ class Wind { public static function run($appName = 'default', $config = '', $rootPath = '') { self::beforRun($appName, $config, $rootPath); if (!isset(self::$_app[$appName])) { - Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); - self::$_app[$appName] = new WindFrontController($config); + Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, + true); + $factory = new WindFactory(@include (self::getRealPath('WIND:components_config'))); + $config = new WindSystemConfig($config, Wind::getAppName(), $factory); + $factory->loadClassDefinitions($config->getComponents()); + $application = $factory->getInstance($config->getAppClass('windWebApp'), + array($config, $factory)); + if ($application === null) { + throw new WindException('[wind.run] ' . $config->getAppClass('windWebApp'), + WindException::ERROR_CLASS_NOT_EXIST); + } + self::$_app[$appName] = $application; } self::getApp()->run(); self::afterRun($appName, $config, $rootPath); @@ -61,7 +72,8 @@ public static function runWithCompile($appName = 'default', $config = '') { * @return string */ public static function getAppName() { - if (empty(self::$_currentApp)) throw new WindException('Get appName failed.', WindException::ERROR_SYSTEM_ERROR); + if (empty(self::$_currentApp)) throw new WindException('Get appName failed.', + WindException::ERROR_SYSTEM_ERROR); return end(self::$_currentApp); } @@ -109,7 +121,8 @@ public static function import($filePath, $recursivePackage = false) { if ($isPackage) { $filePath = substr($filePath, 0, $pos); $dirPath = self::getRealDir($filePath); - if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); + if (!$dh = opendir($dirPath)) throw new Exception( + 'the file ' . $dirPath . ' open failed!'); while (($file = readdir($dh)) !== false) { if (is_dir($dirPath . D_S . $file)) { if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { @@ -151,15 +164,27 @@ public static function register($path, $alias = '', $includePath = false, $reset if ($includePath) { if (empty(self::$_includePaths)) { self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); - if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset(self::$_includePaths[$pos]); + if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset( + self::$_includePaths[$pos]); } array_unshift(self::$_includePaths, $path); - if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { + if (set_include_path( + '.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { throw new Exception('set include path error.'); } } } + /** + * 返回命名空间的路径信息 + * @param string $namespace + * @return string|Ambigous + */ + public static function getRootPath($namespace) { + $namespace = strtolower($namespace); + return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; + } + /** * 类文件自动加载方法 callback * @param string $className @@ -185,16 +210,6 @@ public static function getImports($key = '') { return $key ? self::$_imports[$key] : self::$_imports; } - /** - * 返回命名空间的路径信息 - * @param string $namespace - * @return string|Ambigous - */ - public static function getRootPath($namespace) { - $namespace = strtolower($namespace); - return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; - } - /** * 解析路径信息,并返回路径的详情 * @param string $filePath 路径信息 @@ -301,20 +316,69 @@ public static function clear() { } /** - * 重置当前应用 - * - * @return + * 错误处理句柄 + * @param string $errno + * @param string $errstr + * @param string $errfile + * @param string $errline */ - protected static function resetApp() { - array_pop(self::$_currentApp); + public static function errorHandle($errno, $errstr, $errfile, $errline) { + if ($errno & error_reporting()) { + restore_error_handler(); + restore_exception_handler(); + $message = $trace = ''; + if (IS_DEBUG) { + $message = $errstr . '(' . $errfile . ' : ' . $errline . ')'; + $_trace = debug_backtrace(); + foreach ($_trace as $key => $value) { + if (!isset($value['file']) || !isset($value['line']) || !isset( + $value['function'])) continue; + $trace .= "#$key {$value['file']}({$value['line']}): "; + if (isset($value['object']) && is_object($value['object'])) $trace .= get_class( + $value['object']) . '->'; + $trace .= "{$value['function']}()\r\n"; + } + } + self::displayMessage($errstr, $message, $trace); + } + } + + /** + * 异常处理句柄 + * @param Exception $exception + */ + public static function exceptionHandle($exception) { + restore_error_handler(); + restore_exception_handler(); + $header = $message = $trace = ''; + $header = $exception->getMessage(); + if (IS_DEBUG) { + $message = $exception->getMessage() . '(' . $exception->getFile() . ' : ' . $exception->getLine() . ')'; + $trace = $exception->getTraceAsString(); + } + self::displayMessage($header, $message, $trace); + } + + /** + * @param string $header + * @param string $message + * @param string $trace + */ + protected static function displayMessage($header, $message = '', $trace = '') { + $_tmp = "

$header

"; + $_tmp .= "

$message

"; + $_tmp .= "
$trace
"; + echo $_tmp; } /** * @return */ protected static function beforRun($appName, $config, $rootPath) { - if (!$appName || in_array($appName, self::$_currentApp)) throw new WindException('Nested request', - WindException::ERROR_SYSTEM_ERROR); + set_error_handler('Wind::errorHandle'); + set_exception_handler('Wind::exceptionHandle'); + if (!$appName || in_array($appName, self::$_currentApp)) throw new WindException( + 'Nested request', WindException::ERROR_SYSTEM_ERROR); array_push(self::$_currentApp, $appName); } @@ -322,8 +386,10 @@ protected static function beforRun($appName, $config, $rootPath) { * @return */ protected static function afterRun($appName, $config, $rootPath) { - self::resetApp(); + array_pop(self::$_currentApp); if (self::$_logger) self::$_logger->flush(); + restore_error_handler(); + restore_exception_handler(); } /** @@ -341,10 +407,10 @@ private static function _setDefaultSystemNamespace() { */ private static function _checkEnvironment() { if (version_compare(PHP_VERSION, PHPVERSION) === -1) { - throw new Exception('[wind._checkEnvironment] php version is lower, php ' . PHPVERSION . ' or later.', + throw new Exception( + '[wind._checkEnvironment] current php version is lower, php ' . PHPVERSION . ' or later.', E_WARNING); } - if (!defined('COMPILE_PATH')) throw new Exception('compile path undefined.'); function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); } @@ -381,7 +447,7 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - self::$_classes = array('WindLogger' => 'log/WindLogger', 'WindActionException' => 'core/exception/WindActionException', 'WindException' => 'core/exception/WindException', 'WindFinalException' => 'core/exception/WindFinalException', 'IWindFactory' => 'core/factory/IWindFactory', 'IWindClassProxy' => 'core/factory/proxy/IWindClassProxy', 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', 'WindFactory' => 'core/factory/WindFactory', 'IWindApplication' => 'core/IWindApplication', 'IWindController' => 'core/IWindController', 'IWindErrorMessage' => 'core/IWindErrorMessage', 'IWindFrontController' => 'core/IWindFrontController', 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', 'WindFormListener' => 'core/web/listener/WindFormListener', 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', 'WindValidateListener' => 'core/web/listener/WindValidateListener', 'WindController' => 'core/web/WindController', 'WindDispatcher' => 'core/web/WindDispatcher', 'WindErrorHandler' => 'core/web/WindErrorHandler', 'WindErrorMessage' => 'core/web/WindErrorMessage', 'WindForward' => 'core/web/WindForward', 'WindFrontController' => 'core/web/WindFrontController', 'WindHelper' => 'core/web/WindHelper', 'WindSimpleController' => 'core/web/WindSimpleController', 'WindSystemConfig' => 'core/web/WindSystemConfig', 'WindUrlHelper' => 'core/web/WindUrlHelper', 'WindWebApplication' => 'core/web/WindWebApplication', 'WindEnableValidateModule' => 'core/WindEnableValidateModule', 'WindModule' => 'core/WindModule', 'WindFilter' => 'filter/WindFilter', 'WindFilterChain' => 'filter/WindFilterChain', 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', 'WindConfigParser' => 'parser/WindConfigParser', 'IWindRequest' => 'http/request/IWindRequest', 'WindHttpRequest' => 'http/request/WindHttpRequest', 'IWindResponse' => 'http/response/IWindResponse', 'WindHttpResponse' => 'http/response/WindHttpResponse', 'AbstractWindRouter' => 'router/AbstractWindRouter', 'WindUrlBasedRouter' => 'router/WindUrlBasedRouter'); + self::$_classes = array(); } } Wind::init(); @@ -391,7 +457,7 @@ private static function _loadBaseLib() { define('COMPONENT_ERRORHANDLER', 'errorHandler'); define('COMPONENT_LOGGER', 'windLogger'); define('COMPONENT_FORWARD', 'forward'); -define('COMPONENT_ROUTER', 'urlRewriteRouter'); +define('COMPONENT_ROUTER', 'urlBasedRouter'); define('COMPONENT_URLHELPER', 'urlHelper'); define('COMPONENT_VIEW', 'windView'); define('COMPONENT_VIEWRESOLVER', 'viewResolver'); From d79c5b014923bf8d8d6cc82b1fa992ca5ea1bfac Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:53:31 +0000 Subject: [PATCH 0289/1065] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=EF=BC=8C=20=E6=9A=82=E6=97=B6=E8=BF=98?= =?UTF-8?q?=E4=B8=BA=E5=88=86=E7=A6=BB=EF=BC=8Capplication=20run?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2349 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindFrontController.php | 88 +++------------ wind/core/web/WindSystemConfig.php | 42 ++++--- wind/core/web/WindWebApplication.php | 151 ++++++++++++++++++-------- 3 files changed, 146 insertions(+), 135 deletions(-) diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php index bdd4e30b..6ef2a690 100644 --- a/wind/core/web/WindFrontController.php +++ b/wind/core/web/WindFrontController.php @@ -11,10 +11,6 @@ * @package */ class WindFrontController implements IWindFrontController { - /** - * 框架系统配置信息资源地址,只接受php格式配置 - */ - const WIND_COMPONENT_CONFIG_RESOURCE = 'WIND:components_config'; /** * @var WindHttpRequest */ @@ -31,17 +27,21 @@ class WindFrontController implements IWindFrontController { * @var WindFactory */ protected $windFactory = null; - - private $config; /** - * @param WindConfig $windConfig - * @param WindFactory $windFactory + * @return WindWebApplication */ - public function __construct($config = '') { - $this->request = new WindHttpRequest(); - $this->response = new WindHttpResponse(); - $this->config = $config; + public function getApplication($config) { + $factory = new WindFactory(@include (Wind::getRealPath('WIND:components_config'))); + $config = new WindSystemConfig($config, Wind::getAppName(), $factory); + if ($components = $config->getComponents()) $factory->loadClassDefinitions($components); + $application = $this->windFactory->getInstance($config->getAppClass('windWebApp')); + if ($application === null) { + throw new WindException( + '[core.web.WindFrontController.getApplication] ' . $config->getAppClass( + 'windWebApp'), WindException::ERROR_CLASS_NOT_EXIST); + } + return $application; } /** @@ -85,71 +85,15 @@ protected function beforeProcess() { ob_start(); $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); $this->windFactory = new WindFactory(@include ($configPath)); - $this->windSystemConfig = new WindSystemConfig($this->config, Wind::getAppName(), $this->windFactory); - set_error_handler(array($this, 'errorHandle')); - set_exception_handler(array($this, 'exceptionHandle')); + $this->windSystemConfig = new WindSystemConfig($this->config, Wind::getAppName(), + $this->windFactory); } catch (Exception $e) { - Wind::log('System failed to initialize. (' . $e->getMessage() . ')', WindLogger::LEVEL_INFO, 'wind.core'); + Wind::log('System failed to initialize. (' . $e->getMessage() . ')', + WindLogger::LEVEL_INFO, 'wind.core'); throw new WindException('System failed to initialize.' . $e->getMessage()); } } - /** - * 错误处理句柄 - * @param string $errno - * @param string $errstr - * @param string $errfile - * @param string $errline - */ - final public function errorHandle($errno, $errstr, $errfile, $errline) { - if ($errno & error_reporting()) { - restore_error_handler(); - restore_exception_handler(); - $header = $message = $trace = ''; - $header = $errstr; - if (IS_DEBUG) { - $message = $errstr . '(' . $errfile . ' : ' . $errline . ')'; - $_trace = debug_backtrace(); - foreach ($_trace as $key => $value) { - if (!isset($value['file']) || !isset($value['line']) || !isset($value['function'])) continue; - $trace .= "#$key {$value['file']}({$value['line']}): "; - if (isset($value['object']) && is_object($value['object'])) $trace .= get_class($value['object']) . '->'; - $trace .= "{$value['function']}()\r\n"; - } - } - $this->displayMessage($header, $message, $trace); - } - } - - /** - * 异常处理句柄 - * @param Exception $exception - */ - final public function exceptionHandle($exception) { - restore_error_handler(); - restore_exception_handler(); - $header = $message = $trace = ''; - $header = $exception->getMessage(); - if (IS_DEBUG) { - $message = $exception->getMessage() . '(' . $exception->getFile() . ' : ' . $exception->getLine() . ')'; - $trace = $exception->getTraceAsString(); - } - $this->displayMessage($header, $message, $trace); - } - - /** - * @param string $header - * @param string $message - * @param string $trace - */ - public function displayMessage($header, $message = '', $trace = '') { - $_tmp = "

$header

"; - $_tmp .= "

$message

"; - $_tmp .= "
$trace
"; - $this->getResponse()->sendError(500, $_tmp); - $this->getResponse()->sendResponse(); - } - /** * 后处理Process方法 */ diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index 9f07c56f..b5958201 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -15,18 +15,19 @@ class WindSystemConfig extends WindModule { * @param string $appName * @param WindFactory $factory */ - public function __construct($config, $appName) { + public function __construct($config, $appName, $factory) { $this->appName = $appName; - $this->setConfig($config); + $this->setConfig($config, $factory); } /* (non-PHPdoc) * @see WindModule::setConfig() */ - public function setConfig($config) { + public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { - $config = $this->parseConfig($config, 'config', ''); + $configParser = $factory->getInstance('configParser'); + $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; @@ -42,8 +43,8 @@ public function getAppName() { /** * 返回当前应用的启动脚本位置 */ - public function getAppClass() { - return $this->getConfig('class', '', COMPONENT_WEBAPP); + public function getAppClass($default = '') { + return $this->getConfig('class', '', $default); } /** @@ -114,8 +115,7 @@ public function getRouterClass() { * @return array|string */ public function getModules($name = '') { - if ($name === '') return $this->modules + $this->getConfig('modules', '', array()); - return isset($this->modules[$name]) ? $this->modules[$name] : $this->getConfig('modules', $name, array()); + return $this->getConfig('modules', $name, array()); } /** @@ -140,11 +140,10 @@ public function getModules($name = '') { * * @param string $name * @param array $config + * @return */ - public function setModules($name, $config) { - if (empty($config)) return; - if (isset($this->modules[$name]) || $this->getConfig('modules', $name)) throw new WindException('[core.web.WindSystemConfig] module name already exist.'); - $this->modules[$name] = array_merge($this->getDefaultConfigStruct('modules'), $config); + public function setModules($name, $config = array()) { + $this->_config['modules'][$name] = WindUtility::mergeArray($this->getDefaultConfigStruct('modules'), $config); } /** @@ -193,6 +192,15 @@ public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } + /** + * 返回指定ComponentName的Component配置信息 + * @param string $name + * @return string + */ + public function getComponents($name = '', $default = array()) { + return $this->getConfig('components', $name, $default); + } + /** * 获得DB配置,根据DB名义的别名来获取DB链接配置信息. * 当别名为空时,返回全部DB链接配置. @@ -217,11 +225,8 @@ public function getDbConfig($dbName = '') { */ private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); - $factory = $this->getSystemFactory(); - $configParser = $factory->getInstance(COMPONENT_CONFIGPARSER); - $append === true && $append = $this->appName . '_config'; - $config = $configParser->parse($config, $this->appName . '_' . $key, $append, $factory->getInstance(COMPONENT_CACHE)); - return $config; + $configParser = $this->getSystemConfig()->getInstance('configParser'); + return $configParser->parse($config); } /** @@ -233,7 +238,8 @@ private function parseConfig($config, $key = 'config', $append = true) { public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules'] = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', - 'error-handler' => 'WIND:core.web.WindErrorHandler', 'view' => array('class' => COMPONENT_VIEW)); + 'error-handler' => 'WIND:core.web.WindErrorHandler', 'template-dir' => 'template', 'template-ext' => 'htm', + 'compile-dir' => 'data.template', 'compile-suffix' => 'tpl'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 5b1ef2dc..77365b92 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -6,6 +6,22 @@ * @package */ class WindWebApplication extends WindModule implements IWindApplication { + /** + * @var WindHttpRequest + */ + private $request; + /** + * @var WindHttpResponse + */ + private $response; + /** + * @var WindSystemConfig + */ + protected $windSystemConfig = null; + /** + * @var WindFactory + */ + protected $windFactory = null; /** * @var WindDispatcher */ @@ -15,30 +31,30 @@ class WindWebApplication extends WindModule implements IWindApplication { */ protected $handlerAdapter = null; + /** + * @param WindSystemConfig $config + * @param WindFactory $factory + */ + public function __construct($config, $factory) { + $this->windSystemConfig = $config; + $this->windFactory = $factory; + } + /* (non-PHPdoc) - * @see IWindApplication::processRequest() + * @see IWindApplication::run() */ - public function processRequest() { - try { - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.web.WindWebApplication.processRequest]', WindLogger::LEVEL_DEBUG, 'wind.core'); - } - $handler = $this->getHandler(); - call_user_func_array(array($handler, 'preAction'), array($this->handlerAdapter)); - $forward = call_user_func_array(array($handler, 'doAction'), array($this->handlerAdapter)); - call_user_func_array(array($handler, 'postAction'), array($this->handlerAdapter)); - $this->doDispatch($forward); - } catch (WindActionException $actionException) { - $this->sendErrorMessage($actionException); - } catch (WindDbException $dbException) { - //TODO - $this->sendErrorMessage($dbException->getMessage()); - } catch (WindViewException $viewException) { - //TODO - $this->sendErrorMessage($viewException->getMessage()); - } catch (Exception $e) { - throw new WindException($e->getMessage()); - } + public function run() { + ob_start(); + $this->request = new WindHttpRequest(); + $this->response = new WindHttpResponse(); + $this->_getHandlerAdapter()->route(); + if (null !== ($filterChain = $this->getFilterChain())) { + $filterChain->setCallBack(array($this, 'processRequest')); + $filterChain->getHandler()->handle($this->request, $this->response); + } else + $this->processRequest(); + ob_end_flush(); + $this->response->sendResponse(); } /* (non-PHPdoc) @@ -50,28 +66,49 @@ public function doDispatch($forward) { WindLogger::LEVEL_DEBUG, 'wind.core'); return; } - $this->getDispatcher()->dispatch($this, $forward, $this->handlerAdapter); + $this->_getDispatcher()->dispatch($this, $forward, $this->handlerAdapter); } /** - * 获得Action处理句柄 - * - * @param WindHttpRequest $request + * @return */ - protected function getHandler() { - $handler = $this->getHandlerAdapter()->doParse(); - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.web.WindWebApplication.getHandler] router result:' . $handler, WindLogger::LEVEL_DEBUG, - 'wind.core'); - } - if (!$this->getSystemFactory()->checkAlias($handler)) { - $this->getSystemFactory()->addClassDefinitions($handler, - array('path' => $handler, 'scope' => 'singleton', 'proxy' => true, - 'properties' => array('errorMessage' => array('ref' => COMPONENT_ERRORMESSAGE), - 'forward' => array('ref' => COMPONENT_FORWARD), - 'urlHelper' => array('ref' => COMPONENT_URLHELPER)))); + protected function processRequest() { + try { + $moduleName = $this->handlerAdapter->getModule(); + if (!$moduleName) + $moduleName = 'default'; + if ($moduleName === 'default' && !$this->windSystemConfig->getModules($moduleName)) + $this->windSystemConfig->setModules($moduleName); + $handlerPath = $this->windSystemConfig->getModuleControllerPath($moduleName) . '.' . ucfirst( + $this->handlerAdapter->getController()) . $this->windSystemConfig->getModuleControllerSuffix( + $moduleName); + $handlerPath = trim($handlerPath, '.'); + if (!$handlerPath) + throw new WindFinalException( + '[core.web.WindWebApplication.processRequest] handler path \'' . $handlerPath . '\' is not exist.'); + + if (strpos($handlerPath, ':') === false) + $handlerPath = Wind::getAppName() . ':' . $handlerPath; + if (!$this->getSystemFactory()->checkAlias($handlerPath)) { + $this->getSystemFactory()->addClassDefinitions($handlerPath, + array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, + 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), + 'forward' => array('ref' => 'forward'), + 'urlHelper' => array('ref' => 'urlHelper')))); + } + $handler = $this->windFactory->getInstance($handlerPath); + if ($handler === null) + throw new WindFinalException( + '[core.web.WindWebApplication.processRequest] action handler \'' . $handlerPath . '\' is not exist.'); + call_user_func_array(array($handler, 'preAction'), array($this->handlerAdapter)); + $forward = call_user_func_array(array($handler, 'doAction'), + array($this->handlerAdapter)); + call_user_func_array(array($handler, 'postAction'), array($this->handlerAdapter)); + + $this->doDispatch($forward); + } catch (WindActionException $actionException) { + $this->sendErrorMessage($actionException); } - return $this->getSystemFactory()->getInstance($handler); } /** @@ -91,17 +128,41 @@ protected function sendErrorMessage($actionException) { } /** - * @return WindUrlBasedRouter + * @return WindFilterChain + */ + protected function getFilterChain() { + if (!($filters = $this->getWindSystemConfig()->getFilters())) + return null; + if (!($filterChainPath = $this->getWindSystemConfig()->getFilterClass())) + return null; + return $this->getWindFactory()->createInstance($filterChainPath, array($filters)); + } + + /** + * @return the $request + */ + public function getRequest() { + return $this->request; + } + + /** + * @return the $response */ - protected function getHandlerAdapter() { - return $this->_getHandlerAdapter(); + public function getResponse() { + return $this->response; } /** - * @return WindDispatcher + * @return the $windSystemConfig */ - protected function getDispatcher() { - return $this->_getDispatcher(); + public function getWindSystemConfig() { + return $this->windSystemConfig; } + /** + * @return the $windFactory + */ + public function getWindFactory() { + return $this->windFactory; + } } \ No newline at end of file From 6f2fd1e7402647c52bd64d1881fbe424f695dc9c Mon Sep 17 00:00:00 2001 From: yishuo Date: Sun, 14 Aug 2011 17:54:50 +0000 Subject: [PATCH 0290/1065] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=EF=BC=8C=20=E6=9A=82=E6=97=B6=E8=BF=98?= =?UTF-8?q?=E4=B8=BA=E5=88=86=E7=A6=BB=EF=BC=8Capplication=20run?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2350 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindFrontController.php | 132 -------------------------- 1 file changed, 132 deletions(-) delete mode 100644 wind/core/web/WindFrontController.php diff --git a/wind/core/web/WindFrontController.php b/wind/core/web/WindFrontController.php deleted file mode 100644 index 6ef2a690..00000000 --- a/wind/core/web/WindFrontController.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindFrontController implements IWindFrontController { - /** - * @var WindHttpRequest - */ - private $request; - /** - * @var WindHttpResponse - */ - private $response; - /** - * @var WindSystemConfig - */ - protected $windSystemConfig = null; - /** - * @var WindFactory - */ - protected $windFactory = null; - - /** - * @return WindWebApplication - */ - public function getApplication($config) { - $factory = new WindFactory(@include (Wind::getRealPath('WIND:components_config'))); - $config = new WindSystemConfig($config, Wind::getAppName(), $factory); - if ($components = $config->getComponents()) $factory->loadClassDefinitions($components); - $application = $this->windFactory->getInstance($config->getAppClass('windWebApp')); - if ($application === null) { - throw new WindException( - '[core.web.WindFrontController.getApplication] ' . $config->getAppClass( - 'windWebApp'), WindException::ERROR_CLASS_NOT_EXIST); - } - return $application; - } - - /** - * 执行操作 - * @throws Exception - */ - public function run() { - $this->beforeProcess(); - $appName = $this->windSystemConfig->getAppClass(); - /* @var $application WindModule */ - $application = $this->windFactory->getInstance($appName); - if ($application === null) { - throw new WindException($appName . '[core.web.WindFrontController.process]', - WindException::ERROR_CLASS_NOT_EXIST); - } - $routerAlias = $this->windSystemConfig->getRouterClass(); - $application->setDelayAttributes(array('handlerAdapter' => array('ref' => $routerAlias))); - - if (null !== ($filterChain = $this->getFilterChain())) { - $filterChain->setCallBack(array($application, 'processRequest'), array()); - $filterChain->getHandler()->handle($this->request, $this->response); - } else - $application->processRequest($this->request, $this->response); - $this->afterProcess(); - } - - /** - * @return WindFilterChain - */ - protected function getFilterChain() { - if (!($filters = $this->windSystemConfig->getFilters())) return null; - if (!($filterChainPath = $this->windSystemConfig->getFilterClass())) return null; - return $this->getWindFactory()->createInstance($filterChainPath, array($filters)); - } - - /** - * 预处理Process方法 - */ - protected function beforeProcess() { - try { - ob_start(); - $configPath = Wind::getRealPath(self::WIND_COMPONENT_CONFIG_RESOURCE); - $this->windFactory = new WindFactory(@include ($configPath)); - $this->windSystemConfig = new WindSystemConfig($this->config, Wind::getAppName(), - $this->windFactory); - } catch (Exception $e) { - Wind::log('System failed to initialize. (' . $e->getMessage() . ')', - WindLogger::LEVEL_INFO, 'wind.core'); - throw new WindException('System failed to initialize.' . $e->getMessage()); - } - } - - /** - * 后处理Process方法 - */ - protected function afterProcess() { - ob_end_flush(); - $this->response->sendResponse(); - } - - /** - * @return WindsystemConfig - */ - public function getWindSystemConfig() { - return $this->windSystemConfig; - } - - /** - * @return WindComponentFactory - */ - public function getWindFactory() { - return $this->windFactory; - } - - /** - * @return WindHttpRequest - */ - public function getRequest() { - return $this->request; - } - - /** - * @return WindHttpResponse - */ - public function getResponse() { - return $this->response; - } -} \ No newline at end of file From 6e277da95cf631e3381235b5700c9e84830e999a Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 15 Aug 2011 08:06:00 +0000 Subject: [PATCH 0291/1065] =?UTF-8?q?=E5=90=8D=E8=AF=8D=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2352 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 2 +- wind/component/db/WindSqlStatement.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 5e305fe7..adea53d4 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -219,7 +219,7 @@ public function createTable($tableName, $values, $engine = '', $autoIncrement = * @param string $name * @return int */ - public function lastInsterId($name = '') { + public function lastInsertId($name = '') { if ($name) return $this->getDbHandle()->lastInsertId($name); else diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index dc9d0134..91437b89 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -262,7 +262,7 @@ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { /* (non-PHPdoc) * @see WindConnection::lastInsterId() */ - public function lastInsterId($name = '') { + public function lastInsertId($name = '') { return $this->getConnection($name); } From f50ef636f3005e08a7d4563cdae6ed7758721515 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 16 Aug 2011 02:44:30 +0000 Subject: [PATCH 0292/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2355 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 10 +- .../http/response/WindHttpResponse.php | 56 ++-- wind/component/router/AbstractWindRouter.php | 2 +- wind/component/router/WindRouter.php | 2 +- wind/component/viewer/IWindView.php | 20 ++ wind/component/viewer/WindView.php | 246 +++++------------- wind/component/viewer/WindViewerResolver.php | 73 +++--- .../compiler/WindTemplateCompilerEcho.php | 8 +- .../viewer/listener/WindViewCacheListener.php | 2 +- wind/core/IWindFrontController.php | 32 --- wind/core/WindModule.php | 17 +- wind/core/web/WindDispatcher.php | 100 ++----- wind/core/web/WindForward.php | 10 +- wind/core/web/WindSimpleController.php | 14 +- wind/core/web/WindSystemConfig.php | 38 +-- wind/core/web/WindWebApplication.php | 77 ++++-- 16 files changed, 309 insertions(+), 398 deletions(-) create mode 100644 wind/component/viewer/IWindView.php delete mode 100644 wind/core/IWindFrontController.php diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 8d704259..1d9280a2 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -28,21 +28,20 @@
- + - + - + template htm + 0 compile.template 0 @@ -56,7 +55,6 @@ - diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index a4373521..199f9c0d 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -23,7 +23,7 @@ class WindHttpResponse implements IWindResponse { private $_status = ''; - private $_data = array(); + private $_data = array('G' => array()); /* * Server status codes; see RFC 2068. @@ -300,10 +300,12 @@ class WindHttpResponse implements IWindResponse { * @param string $value 响应头的字段取值 */ public function setHeader($name, $value, $replace = false) { - if (!$name || !$value) return; + if (!$name || !$value) + return; $name = $this->_normalizeHeader($name); foreach ($this->_headers as $key => $one) { - ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); + ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, + 'value' => $value, 'replace' => $replace); } } @@ -314,7 +316,8 @@ public function setHeader($name, $value, $replace = false) { * @param string $value 响应头的字段取值 */ public function addHeader($name, $value, $replace = false) { - if ($name == '' || $value == '') return; + if ($name == '' || $value == '') + return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } @@ -326,7 +329,9 @@ public function addHeader($name, $value, $replace = false) { * @param string $message */ public function setStatus($status, $message = '') { - if (!is_int($status) || $status < 100 || $status > 505) return; + $status = intval($status); + if ($status < 100 || $status > 505) + return; $this->_status = (int) $status; } @@ -338,7 +343,8 @@ public function setStatus($status, $message = '') { * @param string $name */ public function setBody($content, $name = null) { - if (!$content) return; + if (!$content) + return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; @@ -360,7 +366,8 @@ public function addCookie(Cookie $cookie) { * @param string $message */ public function sendError($status = self::SC_NOT_FOUND, $message = '') { - if (!is_int($status) || $status < 400 || $status > 505) return; + if (!is_int($status) || $status < 400 || $status > 505) + return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); @@ -372,7 +379,8 @@ public function sendError($status = self::SC_NOT_FOUND, $message = '') { * @param string $location */ public function sendRedirect($location, $status = 302) { - if (!is_int($status) || $status < 300 || $status > 399) return; + if (!is_int($status) || $status < 300 || $status > 399) + return; $this->addHeader('Location', $location, true); $this->setStatus($status); @@ -393,7 +401,8 @@ public function sendResponse() { * 发送响应头部信息 */ public function sendHeaders() { - if ($this->isSendedHeader()) return; + if ($this->isSendedHeader()) + return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } @@ -434,8 +443,9 @@ public function getBody($name = false) { */ public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); - if ($throw && $sended) throw new WindException( - __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); + if ($throw && $sended) + throw new WindException( + __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } @@ -480,21 +490,33 @@ private function _normalizeHeader($name) { * @return array */ public function getData($key1 = '', $key2 = '') { - if (!$key1) return $this->_data; - if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; + if (!$key1) + return $this->_data; + if (!$key2) + return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } /** * @param $data */ - public function setData($data, $key = '') { + public function setData($data, $key = '', $isG = false) { if ($key) { - $this->_data[$key] = $data; + if ($isG) + $this->_data['G'][$key] = $data; + else + $this->_data[$key] = $data; return; } - if (is_object($data)) $data = get_object_vars($data); - if (is_array($data)) $this->_data += $data; + if (is_object($data)) + $data = get_object_vars($data); + if (is_array($data)) { + if ($isG) + $this->_data['G'] += $data; + else + $this->_data += $data; + + } } } \ No newline at end of file diff --git a/wind/component/router/AbstractWindRouter.php b/wind/component/router/AbstractWindRouter.php index 340e5065..218b4d4d 100644 --- a/wind/component/router/AbstractWindRouter.php +++ b/wind/component/router/AbstractWindRouter.php @@ -13,7 +13,7 @@ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; - protected $module = 'default'; + protected $module; protected $controller = 'index'; protected $action = 'run'; diff --git a/wind/component/router/WindRouter.php b/wind/component/router/WindRouter.php index dafc0a93..11c5dfa7 100644 --- a/wind/component/router/WindRouter.php +++ b/wind/component/router/WindRouter.php @@ -31,7 +31,7 @@ public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); - $params[$this->moduleKey] = $this->getRequest()->getRequest($this->module, $this->module); + $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } diff --git a/wind/component/viewer/IWindView.php b/wind/component/viewer/IWindView.php new file mode 100644 index 00000000..3be5c86b --- /dev/null +++ b/wind/component/viewer/IWindView.php @@ -0,0 +1,20 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindView { + + /** + * 视图渲染 + * + * @param WindForward $forward + * @param WindUrlBasedRouter $router + */ + public function render($forward, $router); + +} + +?> \ No newline at end of file diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index df013496..5fa92e79 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -1,4 +1,5 @@ init(); - if (!($_templateName = $forward->getTemplateName())) { - Wind::log('[component.viewer.WindView.render] view render fail. TemplateName is not defined.', - WindLogger::LEVEL_DEBUG, 'wind.component'); + $this->templateName = $forward->getTemplateName(); + if (!$this->templateName) return; - } - $this->setTemplateName($_templateName); - if ($_ext = $forward->getTemplateExt()) $this->setTemplateExt($_ext); - if ($_path = $forward->getTemplatePath()) $this->setTemplateDir($_path); - if ($_layout = $forward->getLayout()) $this->setLayout($_layout); + if (null !== ($_ext = $forward->getTemplateExt())) + $this->templateExt = $_ext; + if (null !== ($_path = $forward->getTemplatePath())) + $this->templateDir = $_path; + if (null !== ($_layout = $forward->getLayout())) + $this->layout = $_layout; - $viewResolver = $this->getViewResolver(); - $viewResolver->windAssign($forward->getVars(), $_templateName); + $viewResolver = $this->_getViewResolver($this); + $viewResolver->windAssign($forward->getVars(), $this->templateName); if ($display === false) { - $this->getResponse()->setBody($viewResolver->windFetch(), $_templateName); + $this->getResponse()->setBody($viewResolver->windFetch(), $this->templateName); } else $viewResolver->displayWindFetch(); } + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + if ($this->_config) { + $this->templateDir = $this->getConfig('template-dir', '', $this->templateDir); + $this->templateExt = $this->getConfig('template-ext', '', $this->templateExt); + $this->compileDir = $this->getConfig('compile-dir', '', $this->compileDir); + $this->compileExt = $this->getConfig('compile-ext', '', $this->compileExt); + $this->isCompile = $this->getConfig('is-compile', '', $this->isCompile); + $this->htmlspecialchars = $this->getConfig('htmlspecialchars', '', + $this->htmlspecialchars); + } + } + /** * 模板路径解析 * 根据模板的逻辑名称,返回模板的绝对路径信息 @@ -108,7 +124,9 @@ public function render($forward, $router, $display = false) { * @return string | false */ public function getViewTemplate($template = '', $ext = '') { - return $this->parseFilePath($template, $ext, $this->getTemplateDir()); + !$template && $template = $this->templateName; + !$ext && $ext = $this->templateExt; + return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); } /** @@ -119,162 +137,28 @@ public function getViewTemplate($template = '', $ext = '') { * @param string $templateExt * @return string | false */ - public function getCompileFile($template = '', $ext = '') { - return $this->parseFilePath($template, $ext, $this->getCompileDir(), true); - } - - /** - * @param $fileName - * @param $fileExt - * @param $path - */ - private function parseFilePath($fileName, $fileExt, $path, $ifCheckPath = false) { - if (!$fileName) $fileName = $this->getTemplateName(); - if (!$fileExt) $fileExt = $this->getTemplateExt(); - if (strrpos($path, ':') === false) $path = Wind::getAppName() . ':' . $path; - if ($ifCheckPath) { - $dir = Wind::getRealDir($path); - if (!is_dir($dir)) { - @mkdir($dir); - Wind::log('[component.viewer.WindView.parseFilePath] template dir is not exist.', - WindLogger::LEVEL_DEBUG, 'wind.component'); - } + public function getCompileFile($template = '') { + if (!$this->compileDir) return; + !$template && $template = $this->templateName; + $dir = Wind::getRealDir($this->compileDir); + $_tmp = explode('.', $template); + foreach ($_tmp as $_dir) { + !is_dir($dir) && @mkdir($dir); + $dir .= D_S . $_dir; } - return Wind::getRealPath($path . '.' . $fileName, $fileExt); - } - - /** - * 初始哈windView类 - * - * @return - */ - public function init() { - $this->setTemplateDir($this->getConfig('template-dir')); - $this->setCompileDir($this->getConfig('compile-dir')); - $this->setTemplateExt($this->getConfig('template-ext')); - $this->setIsCache($this->getConfig('is-cache')); - } - - /** - * @return string - */ - public function getTemplateDir() { - return $this->templateDir; - } - - /** - * @return string - */ - public function getCompileDir() { - return $this->compileDir; - } - - /** - * @return string - */ - public function getTemplateExt() { - return $this->templateExt; - } - - /** - * @return string - */ - public function getTemplateName() { - return $this->templateName; - } - - /** - * @return boolean - */ - public function getIsCache() { - return $this->isCache; - } - - /** - * @return WindLayout - */ - public function getLayout() { - return $this->layout; - } - - /** - * @param string $templateDir - */ - public function setTemplateDir($templateDir) { - $this->templateDir = $templateDir; - } - - /** - * @param string $compileDir - */ - public function setCompileDir($compileDir) { - $this->compileDir = $compileDir; - } - - /** - * @param string $templateExt - */ - public function setTemplateExt($templateExt) { - $this->templateExt = $templateExt; - } - - /** - * @param string $templateName - */ - public function setTemplateName($templateName) { - $this->templateName = $templateName; - } - - /** - * @param boolean $isCache - */ - public function setIsCache($isCache) { - $this->isCache = (strtolower($isCache) == 'true' || $isCache == '1'); - } - - /** - * @param string $layout - */ - public function setLayout($layout) { - $this->layout = $layout; - } - - /** - * @return the $htmlspecialchars - */ - public function getHtmlspecialchars() { - return $this->htmlspecialchars; - } - - /** - * @param boolean $htmlspecialchars - */ - public function setHtmlspecialchars($htmlspecialchars) { - $this->htmlspecialchars = $htmlspecialchars; - } - - /** - * @return WindViewerCache - */ - public function getViewCache() { - return $this->_getViewCache();; - } - - /** - * @param AbstractWindCache $viewCache - */ - public function setViewCache($viewCache) { - $this->viewCache = $viewCache; + return $this->compileExt ? $dir . '.' . $this->compileExt : $dir; } /** * @return WindViewerResolver */ public function getViewResolver() { - if (null !== $this->viewResolver) return $this->viewResolver; + if (null !== $this->viewResolver) + return $this->viewResolver; $this->_getViewResolver(); $this->viewResolver->setWindView($this); - if (!$this->getIsCache()) return $this->viewResolver; + if (!$this->getIsCache()) + return $this->viewResolver; $this->viewResolver = new WindClassProxy($this->viewResolver); $listener = Wind::import('COM:viewer.listener.WindViewCacheListener'); $this->viewResolver->registerEventListener('windFetch', new $listener($this)); @@ -282,10 +166,10 @@ public function getViewResolver() { } /** - * @param WindViewerResolver $viewResolver + * @return the $layout */ - public function setViewResolver($viewResolver) { - $this->viewResolver = $viewResolver; + public function getLayout() { + return $this->layout; } } \ No newline at end of file diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index d3853907..794a2924 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -16,18 +16,30 @@ * @version $Id$ * @package */ -class WindViewerResolver extends WindModule implements IWindViewerResolver { +class WindViewerResolver implements IWindViewerResolver { + /** + * @var array + */ + protected $vars = array(); /** * @var WindView */ protected $windView = null; + /** + * @param WindView $windView + */ + public function __construct($windView) { + $this->windView = $windView; + } + /* (non-PHPdoc) * @see IWindViewerResolver::windFetch() */ public function windFetch($template = '') { - if (!$template && null !== ($layout = $this->getWindView()->getLayout())) { - $template = $layout; + if (!$template) { + $layout = $this->windView->getLayout(); + $template = $layout ? $layout : $this->windView->templateName; } ob_start(); $this->render($template); @@ -38,63 +50,56 @@ public function windFetch($template = '') { * @see IWindViewerResolver::windAssign() */ public function windAssign($vars, $key = '') { - if ($key === '') $key = $this->getWindView()->getTemplateName(); - $this->getResponse()->setData($vars, $key); - } - - /** - * 立即输出模板内容 - * - * @param string $template - * @param WindView $view - */ - public function displayWindFetch($template = '') { - echo $this->windFetch($template); + if ($key === '') + $key = $this->windView->templateName; + $this->vars[$key] = $vars; } /** * 编译模板并返回编译后模板名称 - * * @param string $template * @param string $suffix * @param boolean $output * @return string */ public function compile($template, $suffix = '', $output = false) { - $templateFile = $this->getWindView()->getViewTemplate($template, $suffix); + $templateFile = $this->windView->getViewTemplate($template, $suffix); if (!is_file($templateFile)) { throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, WindViewException::VIEW_NOT_EXIST); } - $compileFile = $this->getWindView()->getCompileFile($template, 'php'); - + if (!($compileFile = $this->windView->getCompileFile($template))) + return array($templateFile, ''); + /* @var $_windTemplate WindViewTemplate */ - $_windTemplate = $this->getSystemFactory()->getInstance(COMPONENT_TEMPLATE); + $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); $_output = $_windTemplate->compile($templateFile, $this); - if (!$compileFile && !$_output) return array('', ''); + if (!$compileFile && !$_output) + return array('', ''); WindFile::write($compileFile, $_output); return array($compileFile, $_output); } /** * 加载视图模板文件 - * * @param template */ protected function render($template) { list($_tmp, $_output) = $this->compile($template); - @extract((array) $this->getResponse()->getData($this->getWindView()->getTemplateName()), EXTR_REFS); - if (!include $_tmp) { + $_var = Wind::getApp()->getResponse()->getData('G'); + if (isset($this->vars[$template])) + $_var += $this->vars[$template]; + @extract($_var, EXTR_REFS); + if (!@include ($_tmp)) { throw new WindViewException( - '[component.viewer.ViewerResolver.render] template:' . $template . ' compile template:' . $_tmp, + '[component.viewer.ViewerResolver.render] template name ' . $template, WindViewException::VIEW_NOT_EXIST); } } /** * 检查是否需要重新编译 - * * @param string $templateFile * @param string $compileFile */ @@ -106,19 +111,20 @@ private function checkReCompile($templateFile, $compileFile) { $_reCompile = true; } else { $templateFileModifyTime = @filemtime($templateFile); - if ((int) $templateFileModifyTime >= $compileFileModifyTime) $_reCompile = true; + if ((int) $templateFileModifyTime >= $compileFileModifyTime) + $_reCompile = true; } return $_reCompile; } /** * 当前模板内容 - * * @param string $template */ private function getContent($template = '') { - if (!$template) $template = $this->getWindView()->getTemplateName(); - if ($template) $this->displayWindFetch($template); + !$template && $template = $this->windView->templateName; + if ($template) + echo $this->windFetch($template); } /** @@ -128,11 +134,4 @@ public function getWindView() { return $this->windView; } - /** - * @param WindView $windView - */ - public function setWindView($windView) { - $this->windView = $windView; - } - } \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index 5db9ad7a..62ce7bb0 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -21,11 +21,12 @@ class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { public function compile($key, $content) { $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content); list($_output, $type) = $this->doCompile($_output); - if ($this->windViewerResolver->getWindView()->getHtmlspecialchars() === true && $type == 'text') + if ($this->windViewerResolver->getWindView()->htmlspecialchars === true && $type == 'text') return ''; else return ''; } + /** * 处理变量 * @param string $var @@ -43,11 +44,12 @@ private function doCompile($var) { * @return string */ private function compileVarShare($input) { - if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) return $input; + if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) + return $input; list($templateName, $var) = explode(':', $input); return '$this->getResponse()->getData(\'' . $templateName . '\', \'' . $var . '\')'; } - + /** * 获得变量后的|之后的值 * @return array diff --git a/wind/component/viewer/listener/WindViewCacheListener.php b/wind/component/viewer/listener/WindViewCacheListener.php index f4b6c947..99a1eef6 100644 --- a/wind/component/viewer/listener/WindViewCacheListener.php +++ b/wind/component/viewer/listener/WindViewCacheListener.php @@ -37,7 +37,7 @@ public function preHandle() { private function getKey() { $host = Wind::getApp()->getRequest()->getHostInfo(); $uri = Wind::getApp()->getRequest()->getRequestUri(); - return $host.$uri . '/' . $this->windView->getTemplateName() . '.' . $this->windView->getTemplateExt(); + return $host.$uri . '/' . $this->windView->templateName . '.' . $this->windView->templateExt; } /* (non-PHPdoc) diff --git a/wind/core/IWindFrontController.php b/wind/core/IWindFrontController.php deleted file mode 100644 index f2cba621..00000000 --- a/wind/core/IWindFrontController.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindFrontController { - - /** - * @return WindsystemConfig - */ - public function getWindSystemConfig(); - - /** - * @return WindComponentFactory - */ - public function getWindFactory(); - - /** - * @return WindHttpRequest - */ - public function getRequest(); - - /** - * @return WindHttpResponse - */ - public function getResponse(); - -} - -?> \ No newline at end of file diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 2dc3cfc9..e12d4668 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -37,7 +37,8 @@ public function __set($propertyName, $value) { if (method_exists($this, $_setter)) $this->$_setter($value); else - Wind::log('[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, + Wind::log( + '[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } @@ -52,7 +53,8 @@ public function __get($propertyName) { if (method_exists($this, $_getter)) return $this->$_getter(); else - Wind::log('[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, + Wind::log( + '[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } @@ -78,13 +80,17 @@ public function __call($methodName, $args) { if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { - $_value = $this->getSystemFactory()->getInstance($_property['ref']); + $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); + } elseif (isset($_property['path'])) { + $_className = Wind::import($_property['path']); + $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; } return $this->$_propertyName; } - throw new WindException('[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', + throw new WindException( + '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } @@ -128,7 +134,8 @@ public function toArray() { */ protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { - Wind::log('[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', + Wind::log( + '[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php index a72c68ee..45540a84 100644 --- a/wind/core/web/WindDispatcher.php +++ b/wind/core/web/WindDispatcher.php @@ -12,7 +12,6 @@ class WindDispatcher extends WindModule { /** * 将上一次请求信息缓存在这个变量中 - * * @var array */ protected $processCache = array(); @@ -20,7 +19,6 @@ class WindDispatcher extends WindModule { * @var WindUrlHelper */ protected $urlHelper = null; - /** * @var boolean */ @@ -29,58 +27,51 @@ class WindDispatcher extends WindModule { /** * 请求分发处理 * - * @param WindWebApplication $app * @param WindForward $forward * @param WindUrlBasedRouter $router * @return */ - public function dispatch($app, $forward, $router) { + public function dispatch($forward, $router) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) - $this->dispatchWithRedirect($app, $forward, $router); + $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) - $this->dispatchWithAction($app, $forward, $router); + $this->dispatchWithAction($forward, $router); else - $this->render($app, $forward, $router); - $this->destroy(); + $this->render($forward, $router); } /** * 请求分发一个重定向请求 - * - * @param WindWebApplication $app * @param WindForward $forward * @param WindUrlBasedRouter $router * @return */ - protected function dispatchWithRedirect($app, $forward, $router) { + protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { - $_url = $this->getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), - $forward->getArgs()); + $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), + $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( - '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . - $router->getAction(), WindException::ERROR_SYSTEM_ERROR); + '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), + WindException::ERROR_SYSTEM_ERROR); } } else - $_url = $this->getUrlHelper()->checkUrl($_url); + $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } /** * 请求分发一个操作请求 - * - * @param WindWebApplication $app * @param WindForward $forward * @param WindUrlBasedRouter $router * @return */ - protected function dispatchWithAction($app, $forward, $router) { + protected function dispatchWithAction($forward, $router) { //TODO 是否需要缓存上次请求的变量信息 - $this->getRequest()->setAttribute($forward->getVars(), - $router->getAction() . '_' . $router->getController()); + $this->getRequest()->setAttribute($forward->getVars()); $this->setDisplay($forward->getDisplay()); list($_c, $_m) = WindHelper::resolveController($forward->getController()); $_a = $forward->getAction(); @@ -89,38 +80,30 @@ protected function dispatchWithAction($app, $forward, $router) { $_m && $router->setModule($_m); if (!$this->checkProcess($router)) { throw new WindFinalException( - '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . - $router->getAction(), WindException::ERROR_SYSTEM_ERROR); + '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), + WindException::ERROR_SYSTEM_ERROR); } - $app->processRequest(); + Wind::getApp()->processRequest(); } /** * 进行视图渲染 - * - * @param WindWebApplication $app * @param WindForward $forward * @param WindUrlBasedRouter $router * @return */ - protected function render($app, $forward, $router) { - try { - if ($windViewClass = $forward->getWindView()) - $view = $this->getSystemFactory()->createInstance($windViewClass); - elseif ($windViewClass = $this->getSystemConfig()->getModuleViewClassByModuleName($router->getModule())) - $view = $this->getSystemFactory()->getInstance($windViewClass); - else - $view = $this->getSystemFactory()->getInstance(COMPONENT_VIEW); - $view->setConfig($this->getSystemConfig()->getModuleViewConfigByModuleName($router->getModule())); - $view->render($forward, $router, $this->getDisplay()); - } catch (Exception $e) { - throw new WindViewException('[core.web.WindDispatcher.render] view render fail.' . $e->getMessage()); - } + protected function render($forward, $router) { + if ($windViewClass = $forward->getWindView()) { + $_className = Wind::import($windViewClass); + $view = $this->getSystemFactory()->createInstance($windViewClass); + } else + $view = $this->getSystemFactory()->getInstance('windView'); + $view->render($forward, $router, $this->display); + $this->display = false; } /** * 检查请求是否是重复请求 - * * @param WindUrlBasedRouter $router * @param boolean $check * @return boolean @@ -130,37 +113,11 @@ protected function checkProcess($router, $check = true) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); - } elseif ($router->getAction() === $this->processCache['action'] && - $router->getController() === $this->processCache['controller'] && - $router->getModule() === $this->processCache['module']) - return false; + } elseif ($router->getAction() === $this->processCache['action'] && $router->getController() === $this->processCache['controller'] && $router->getModule() === $this->processCache['module']) + return false; return true; } - /** - * 注销当前dispatcher状态 - * - * @return - */ - protected function destroy() { - $this->processCache = array(); - $this->setDisplay(false); - } - - /** - * @return boolean - */ - public function getDisplay() { - return $this->display; - } - - /** - * @param boolean $display - */ - public function setDisplay($display) { - $this->display = $display; - } - /** * @return WindUrlHelper */ @@ -168,11 +125,4 @@ public function getUrlHelper() { return $this->_getUrlHelper(); } - /** - * @param WindUrlHelper $urlHelper - */ - public function setUrlHelper($urlHelper) { - $this->urlHelper = $urlHelper; - } - } diff --git a/wind/core/web/WindForward.php b/wind/core/web/WindForward.php index 65294291..ce404354 100644 --- a/wind/core/web/WindForward.php +++ b/wind/core/web/WindForward.php @@ -24,13 +24,13 @@ class WindForward extends WindModule { * * @var string */ - private $templatePath; + private $templatePath = null; /** * 模板扩展名 * * @var string */ - private $templateExt; + private $templateExt = null; /** * 模板布局 * @@ -91,8 +91,10 @@ public function forwardAnotherAction($action = 'run', $controller = '', $args = */ public function setVars($vars, $key = '') { if (!$key) { - if (is_object($vars)) $vars = get_object_vars($vars); - if (is_array($vars)) $this->vars += $vars; + if (is_object($vars)) + $vars = get_object_vars($vars); + if (is_array($vars)) + $this->vars += $vars; } else $this->vars[$key] = $vars; return; diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index fa07c217..a10c8ea8 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -59,7 +59,8 @@ public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); - Wind::log('[core.web.controller.WindSimpleController.doAction] resolved action method:' . $method, + Wind::log( + '[core.web.controller.WindSimpleController.doAction] resolved action method:' . $method, WindLogger::LEVEL_INFO, 'wind.core'); call_user_func_array(array($this, $method), array()); $this->getErrorMessage()->sendError(); @@ -103,6 +104,17 @@ protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } + /** + * 设置模板数据 + * + * @param string|array|object $data + * @param string $key + * @return + */ + protected function setGlobal($data, $key = '') { + $this->getResponse()->setData($data, $key, true); + } + /** * 获得输入数据 * 如果输入了回调方法则返回数组: diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index b5958201..cc6c5336 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -24,11 +24,13 @@ public function __construct($config, $appName, $factory) { * @see WindModule::setConfig() */ public function setConfig($config, $factory = null) { - if (empty($config)) return; + if (empty($config)) + return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); - if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; + if (isset($config[$this->appName])) + $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } @@ -126,33 +128,33 @@ public function getModules($name = '') { * * WIND:core.web.WindErrorHandler * - * * - * * * template * * htm - * - * data.template - * - * * * @param string $name * @param array $config * @return */ public function setModules($name, $config = array()) { - $this->_config['modules'][$name] = WindUtility::mergeArray($this->getDefaultConfigStruct('modules'), $config); + if (isset($this->_config['modules'][$name])) + return; + if (!$config) + $this->_config['modules'][$name] = $this->getDefaultConfigStruct('modules'); + else + $this->_config['modules'][$name] = WindUtility::mergeArray( + $this->getDefaultConfigStruct('modules'), $config); } /** - * 根据module名称返回module的视图处理类 - * @param string $name - * @param string $default + * 返回module模板定义 + * @param unknown_type $name + * @param unknown_type $default */ - public function getModuleViewClass($name, $default = '') { - return $this->getConfig('view', 'class', $default, $this->getModules($name)); + public function getModuleTemplateDir($name, $default = '') { + return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } /** @@ -224,7 +226,8 @@ public function getDbConfig($dbName = '') { * @param factory */ private function parseConfig($config, $key = 'config', $append = true) { - if (!$config) return array(); + if (!$config) + return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } @@ -237,9 +240,8 @@ private function parseConfig($config, $key = 'config', $append = true) { */ public function getDefaultConfigStruct($configName) { $_tmp = array(); - $_tmp['modules'] = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', - 'error-handler' => 'WIND:core.web.WindErrorHandler', 'template-dir' => 'template', 'template-ext' => 'htm', - 'compile-dir' => 'data.template', 'compile-suffix' => 'tpl'); + $_tmp['modules'] = array('controller-path' => 'controller', + 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 77365b92..e31aa5eb 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -60,28 +60,40 @@ public function run() { /* (non-PHPdoc) * @see IWindApplication::doDispatch() */ - public function doDispatch($forward) { + public function doDispatch($forward, $module = array()) { if ($forward === null) { Wind::log('[core.web.WindWebApplication.doDispatch] Forward is null, dispatch abort.', WindLogger::LEVEL_DEBUG, 'wind.core'); return; } - $this->_getDispatcher()->dispatch($this, $forward, $this->handlerAdapter); + if ($module) { + /* @var $forward WindForward */ + if ($forward->getTemplateExt() === null && isset($module['template-ext'])) + $forward->setTemplateExt($module['template-ext']); + if ($forward->getTemplatePath() === null && isset($module['template-dir'])) + $forward->setTemplatePath($module['template-dir']); + } + $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter); } /** * @return */ - protected function processRequest() { + public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); - if (!$moduleName) + if (!$moduleName) { $moduleName = 'default'; - if ($moduleName === 'default' && !$this->windSystemConfig->getModules($moduleName)) $this->windSystemConfig->setModules($moduleName); - $handlerPath = $this->windSystemConfig->getModuleControllerPath($moduleName) . '.' . ucfirst( - $this->handlerAdapter->getController()) . $this->windSystemConfig->getModuleControllerSuffix( - $moduleName); + } + if (!($module = $this->windSystemConfig->getModules($moduleName))) + throw new WindException( + '[core.web.WindWebApplication.processRequest] The module \'' . $moduleName . '\' is not exist.'); + $module = WindUtility::mergeArray( + $this->windSystemConfig->getDefaultConfigStruct('modules'), $module); + $handlerPath = $module['controller-path'] . '.' . ucfirst( + $this->handlerAdapter->getController()) . $module['controller-suffix']; + $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindFinalException( @@ -105,10 +117,42 @@ protected function processRequest() { array($this->handlerAdapter)); call_user_func_array(array($handler, 'postAction'), array($this->handlerAdapter)); - $this->doDispatch($forward); - } catch (WindActionException $actionException) { - $this->sendErrorMessage($actionException); + $this->doDispatch($forward, $module); + } catch (WindActionException $e) { + $this->sendErrorMessage($e); + } catch (WindViewException $e) { + echo $e;exit; + $this->sendErrorMessage($e->getMessage()); + } + } + + /** + * 返回module配置信息 + * @return array + */ + protected function resolveModule() { + $moduleName = $this->handlerAdapter->getModule(); + if (!$moduleName) { + $moduleName = 'default'; + $this->windSystemConfig->setModules($moduleName); } + if (!($module = $this->windSystemConfig->getModules($moduleName))) + throw new WindException( + '[core.web.WindWebApplication.processRequest] The module \'' . $moduleName . '\' is not exist.'); + return $module; + } + + /** + * @param string $componentName + * @param object $componentInstance + */ + public function registeComponent($componentName, $componentInstance) {} + + /** + * @param string $componentName + */ + public function getComponent($componentName) { + return $this->windFactory->getInstance($componentName); } /** @@ -117,13 +161,14 @@ protected function processRequest() { * @param WindActionException|string actionException * @return */ - protected function sendErrorMessage($actionException) { + protected function sendErrorMessage($actionException, $errorCode = '') { $_tmp = is_object($actionException) ? $actionException->getError() : $actionException; if (is_string($_tmp)) $_tmp = new WindErrorMessage($_tmp); $forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD); $forward->forwardAnotherAction($_tmp->getErrorAction(), $_tmp->getErrorController()); $this->getRequest()->setAttribute($_tmp->getError(), 'error'); + $this->getRequest()->setAttribute($errorCode, 'errorCode'); $this->doDispatch($forward); } @@ -139,28 +184,28 @@ protected function getFilterChain() { } /** - * @return the $request + * @return WindHttpRequest $request */ public function getRequest() { return $this->request; } /** - * @return the $response + * @return WindHttpResponse $response */ public function getResponse() { return $this->response; } /** - * @return the $windSystemConfig + * @return WindSystemConfig $windSystemConfig */ public function getWindSystemConfig() { return $this->windSystemConfig; } /** - * @return the $windFactory + * @return WindFactory $windFactory */ public function getWindFactory() { return $this->windFactory; From b2cfefb72eb508405e23fa8b4f822bab963b88d5 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 16 Aug 2011 02:44:42 +0000 Subject: [PATCH 0293/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2356 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 305b462a..a8f6b818 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -81,7 +81,7 @@ public static function getAppName() { * 返回当前的app应用 * * @param string $appName - * @return WindFrontController + * @return WindWebApplication */ public static function getApp() { $_appName = self::getAppName(); @@ -197,7 +197,7 @@ public static function autoLoad($className, $path = '') { throw new Exception('auto load ' . $className . ' failed.'); } $path .= '.' . self::$_extensions; - if ((include $path) === false) { + if ((@include $path) === false) { throw new Exception('[wind.Wind.autoLoad] auto load class ' . $className . ' failed.'); } } From 3ddf91c697998bf7ae2e55e4e461f74fe7e96ee4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 16 Aug 2011 09:08:06 +0000 Subject: [PATCH 0294/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2360 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindHelper.php | 152 ++++++++++++++++++++++++++- wind/core/web/WindWebApplication.php | 18 ++-- 2 files changed, 162 insertions(+), 8 deletions(-) diff --git a/wind/core/web/WindHelper.php b/wind/core/web/WindHelper.php index 0f414ea6..411e9b12 100644 --- a/wind/core/web/WindHelper.php +++ b/wind/core/web/WindHelper.php @@ -9,6 +9,155 @@ * @package */ class WindHelper { + const INTERNAL_LOCATION = "~Internal Location~"; + + /** + * 错误处理句柄 + * @param string $errno + * @param string $errstr + * @param string $errfile + * @param string $errline + */ + public static function errorHandle($errno, $errstr, $errfile, $errline) { + if ($errno & error_reporting()) { + restore_error_handler(); + restore_exception_handler(); + $trace = debug_backtrace(); + unset($trace[0]["function"], $trace[0]["args"]); + self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); + exit(); + } + } + + /** + * 异常处理句柄 + * @param Exception $exception + */ + public static function exceptionHandle($exception) { + restore_error_handler(); + restore_exception_handler(); + $trace = $exception->getTrace(); + if (@$trace[0]['file'] == '') { + unset($trace[0]); + $trace = array_values($trace); + } + $file = @$trace[0]['file']; + $line = @$trace[0]['line']; + self::crash($exception->getMessage(), $file, $line, $trace); + exit(); + } + + /** + * @param string $message + * @param string $file + * @param string $line + * @param array $trace + */ + protected static function crash($message, $file, $line, $trace, $status = 500) { + $errmessage = substr($message, 0, 8000) . "\n"; + $topic = "Wind Framework - Error Caught\n"; + $_headers = Wind::getApp()->getResponse()->getHeaders(); + $_errhtml = false; + foreach ($_headers as $_header) { + if (strtolower($_header['name']) == strtolower('Content-type')) { + $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; + break; + } + } + if (IS_DEBUG) { + $errtrace = "__Stack:\n"; + $count = count($trace); + $padLen = strlen($count); + foreach ($trace as $key => $call) { + if (!isset($call['file']) || $call['file'] == '') { + $call['file'] = self::INTERNAL_LOCATION; + $call['line'] = 'N/A'; + } + + $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( + $call); + $errtrace .= "$traceLine\n"; + } + $errsample = ''; + if ($_errhtml && is_file($file)) { + $currentLine = $line - 1; + $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); + $topLine = $currentLine - 5; + $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); + if (($count = count($fileLines)) > 0) { + $padLen = strlen($count); + foreach ($fileLines as $line => &$fileLine) + $fileLine = " " . htmlspecialchars( + str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( + "\t", " ", rtrim($fileLine)), null, "UTF-8"); + + $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; + $errsample = implode("\n", $fileLines) . "\n"; + } + } + $errraised = "$file; line #$line\n"; + $msg = "
$errraised$errsample\n$errtrace
"; + } else { + $status !== '' && $topic = "$status - " . Wind::getApp()->getResponse()->codeMap( + $status) . "\n"; + $msg = "
The server encountered an internal error and failed to process your request.\nPlease try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message
"; + } + if ($_errhtml) { + $errmessage = "$errmessage"; + $topic = "

$topic

"; + } + ob_end_flush(); + Wind::getApp()->getResponse()->sendHeaders(); + die($topic . $errmessage . $msg); + } + + /** + * @param array $call + * @return string + */ + private static function getCallLine($call) { + $call_signature = ""; + if (isset($call['file'])) + $call_signature .= $call['file'] . " "; + if (isset($call['line'])) + $call_signature .= "(" . $call['line'] . ") "; + if (isset($call['function'])) { + $call_signature .= $call['function'] . '('; + if (isset($call['args'])) { + foreach ($call['args'] as $arg) { + if (is_string($arg)) + $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; + else if (is_object($arg)) + $arg = "[Instance of '" . get_class($arg) . "']"; + else if ($arg === true) + $arg = "true"; + else if ($arg === false) + $arg = "false"; + else if ($arg === null) + $arg = "null"; + else + $arg = strval($arg); + $call_signature .= $arg . ','; + } + } + $call_signature = trim($call_signature, ',') . ")"; + } + return $call_signature; + } + + /** + * @param int $errorNumber + * @return string + */ + protected static function getErrorName($errorNumber) { + $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", + E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", + E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", + E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", + E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", + E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); + return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; + } /** * 解析ControllerPath @@ -19,7 +168,8 @@ class WindHelper { */ public static function resolveController($controllerPath) { $_m = $_c = ''; - if (!$controllerPath) return array($_c, $_m); + if (!$controllerPath) + return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index e31aa5eb..45f19aac 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -44,16 +44,19 @@ public function __construct($config, $factory) { * @see IWindApplication::run() */ public function run() { - ob_start(); + set_error_handler('WindHelper::errorHandle'); + set_exception_handler('WindHelper::exceptionHandle'); $this->request = new WindHttpRequest(); - $this->response = new WindHttpResponse(); + $this->response = $this->request->getResponse(); $this->_getHandlerAdapter()->route(); - if (null !== ($filterChain = $this->getFilterChain())) { + if (null == ($filterChain = $this->getFilterChain())) + $this->processRequest(); + else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); - } else - $this->processRequest(); - ob_end_flush(); + } + restore_error_handler(); + restore_exception_handler(); $this->response->sendResponse(); } @@ -121,7 +124,8 @@ public function processRequest() { } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { - echo $e;exit; + echo $e; + exit(); $this->sendErrorMessage($e->getMessage()); } } From c0b9fd00056c452887aa6d5b378d7c863408673d Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 16 Aug 2011 09:08:53 +0000 Subject: [PATCH 0295/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2361 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/utility/WindString.php | 364 +++++++++++++------------- 1 file changed, 186 insertions(+), 178 deletions(-) diff --git a/wind/component/utility/WindString.php b/wind/component/utility/WindString.php index 002a5660..eb41cd5e 100644 --- a/wind/component/utility/WindString.php +++ b/wind/component/utility/WindString.php @@ -1,11 +1,11 @@ - 2010-12-17 * @link http://www.phpwind.com * @copyright Copyright © 2003-2110 phpwind.com * @license - */ - + */ + /** * 字符串格式化 * the last known user to change this file in the repository <$LastChangedBy$> @@ -24,99 +24,105 @@ class WindString { * @param string $charset 原妈编码 * @param boolean $dot 是否显示省略号 * @return string 截取后的字串 - */ - public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { - return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr($string, $start, $length, $dot); - } + */ + public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { + return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( + $string, $start, $length, $dot); + } + /** * 求取字符串长度 * @param string $string 要计算的字符串编码 * @param string $charset 原始编码 * @return int - */ - public static function strlen($string, $charset = self::UTF8) { - $len = strlen($string); - $i = $count = 0; - while ($i < $len) { - ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; - $count++; - } - return $count; - } + */ + public static function strlen($string, $charset = self::UTF8) { + $len = strlen($string); + $i = $count = 0; + while ($i < $len) { + ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; + $count++; + } + return $count; + } + /** * 将变量的值转换为字符串 * * @param mixed $input 变量 * @param string $indent 缩进 * @return string - */ - public static function varToString($input, $indent = '') { - switch (gettype($input)) { - case 'string': - return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; - case 'array': - $output = "array(\r\n"; - foreach ($input as $key => $value) { - $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString($value, $indent . "\t"); - $output .= ",\r\n"; - } - $output .= $indent . ')'; - return $output; - case 'boolean': - return $input ? 'true' : 'false'; - case 'NULL': - return 'NULL'; - case 'integer': - case 'double': - case 'float': - return "'" . (string) $input . "'"; - } - return 'NULL'; - } - - public static function jsonEncode($value) { - if (!function_exists('json_encode')) { - Wind::import('Wind:component.utility.json.WindEncoder'); - return WindDecoder::decode($value); - } - return json_encode($value); - } - - public static function jsonDecode($value) { - if (!function_exists('json_decode')) { - Wind::import('Wind:component.utility.json.WindEncoder'); - return WindEncoder::encode($value); - } - return json_decode($value); - } - - public static function jsonSimpleEncode($var) { - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - case 'NULL': - return 'null'; - case 'integer': - return (int) $var; - case 'double': - case 'float': - return (float) $var; - case 'string': - return '"' . addslashes(str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; - case 'array': - if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - $properties = array(); - foreach ($var as $name => $value) { - $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode($value); - } - return '{' . join(',', $properties) . '}'; - } - $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); - return '[' . join(',', $elements) . ']'; - } - return false; - } - + */ + public static function varToString($input, $indent = '') { + switch (gettype($input)) { + case 'string': + return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; + case 'array': + $output = "array(\r\n"; + foreach ($input as $key => $value) { + $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( + $value, $indent . "\t"); + $output .= ",\r\n"; + } + $output .= $indent . ')'; + return $output; + case 'boolean': + return $input ? 'true' : 'false'; + case 'NULL': + return 'NULL'; + case 'integer': + case 'double': + case 'float': + return "'" . (string) $input . "'"; + } + return 'NULL'; + } + + public static function jsonEncode($value) { + if (!function_exists('json_encode')) { + Wind::import('Wind:component.utility.json.WindEncoder'); + return WindDecoder::decode($value); + } + return json_encode($value); + } + + public static function jsonDecode($value) { + if (!function_exists('json_decode')) { + Wind::import('Wind:component.utility.json.WindEncoder'); + return WindEncoder::encode($value); + } + return json_decode($value); + } + + public static function jsonSimpleEncode($var) { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + case 'NULL': + return 'null'; + case 'integer': + return (int) $var; + case 'double': + case 'float': + return (float) $var; + case 'string': + return '"' . addslashes( + str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; + case 'array': + if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array(); + foreach ($var as $name => $value) { + $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( + $value); + } + return '{' . join(',', $properties) . '}'; + } + $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); + return '[' . join(',', $elements) . ']'; + } + return false; + } + /** * 以utf8格式截取的字符串编码 * @param string $string 要截取的字符串编码 @@ -124,111 +130,113 @@ public static function jsonSimpleEncode($var) { * @param int $length 截取的长度 * @param boolean $dot 是否显示省略号 * @return string - */ - public static function utf8_substr($string, $start, $length = null, $dot = false) { - if (empty($string) || !is_int($start) || ($length && !is_int($length))) { - return ''; - } - $strlen = strlen($string); - $length = $length ? $length : $strlen; - $substr = ''; - $chinese = $word = 0; - for ($i = 0, $j = 0; $i < $start; $i++) { - if (0xa0 < ord(substr($string, $j, 1))) { - $chinese++; - $j += 2; - } else { - $word++; - } - $j++; - } - $start = $word + 3 * $chinese; - for ($i = $start, $j = $start; $i < $start + $length; $i++) { - if (0xa0 < ord(substr($string, $j, 1))) { - $substr .= substr($string, $j, 3); - $j += 2; - } else { - $substr .= substr($string, $j, 1); - } - $j++; - } - (strlen($substr) < $strlen) && $dot && $substr .= "..."; - return $substr; - } + */ + public static function utf8_substr($string, $start, $length = null, $dot = false) { + if (empty($string) || !is_int($start) || ($length && !is_int($length))) { + return ''; + } + $strlen = strlen($string); + $length = $length ? $length : $strlen; + $substr = ''; + $chinese = $word = 0; + for ($i = 0, $j = 0; $i < $start; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $chinese++; + $j += 2; + } else { + $word++; + } + $j++; + } + $start = $word + 3 * $chinese; + for ($i = $start, $j = $start; $i < $start + $length; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $substr .= substr($string, $j, 3); + $j += 2; + } else { + $substr .= substr($string, $j, 1); + } + $j++; + } + (strlen($substr) < $strlen) && $dot && $substr .= "..."; + return $substr; + } + /** * 以utf8求取字符串长度 * @param string $str 要计算的字符串编码 * @return number - */ - public static function utf8_strlen($str) { - $i = $count = 0; - $len = strlen($str); - while ($i < $len) { - $chr = ord($str[$i]); - $count++; - $i++; - if ($i >= $len) break; - if ($chr & 0x80) { - $chr <<= 1; - while ($chr & 0x80) { - $i++; - $chr <<= 1; - } - } - } - return $count; - } - + */ + public static function utf8_strlen($str) { + $i = $count = 0; + $len = strlen($str); + while ($i < $len) { + $chr = ord($str[$i]); + $count++; + $i++; + if ($i >= $len) + break; + if ($chr & 0x80) { + $chr <<= 1; + while ($chr & 0x80) { + $i++; + $chr <<= 1; + } + } + } + return $count; + } + /* 以gbk格式截取的字符串编码 * @param string $string 要截取的字符串编码 * @param int $start 开始截取 * @param int $length 截取的长度 * @param boolean $dot 是否显示省略号 * @return string - */ - public static function gbk_substr($string, $start, $length = null, $dot = false) { - if (empty($string) || !is_int($start) || ($length && !is_int($length))) { - return ''; - } - $strlen = strlen($string); - $length = $length ? $length : $strlen; - $substr = ''; - $chinese = $word = 0; - for ($i = 0, $j = 0; $i < $start; $i++) { - if (0xa0 < ord(substr($string, $j, 1))) { - $chinese++; - $j++; - } else { - $word++; - } - $j++; - } - $start = $word + 2 * $chinese; - for ($i = $start, $j = $start; $i < $start + $length; $i++) { - if (0xa0 < ord(substr($string, $j, 1))) { - $substr .= substr($string, $j, 2); - $j++; - } else { - $substr .= substr($string, $j, 1); - } - $j++; - } - (strlen($substr) < $strlen) && $dot && $substr .= "..."; - return $substr; - } - + */ + public static function gbk_substr($string, $start, $length = null, $dot = false) { + if (empty($string) || !is_int($start) || ($length && !is_int($length))) { + return ''; + } + $strlen = strlen($string); + $length = $length ? $length : $strlen; + $substr = ''; + $chinese = $word = 0; + for ($i = 0, $j = 0; $i < $start; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $chinese++; + $j++; + } else { + $word++; + } + $j++; + } + $start = $word + 2 * $chinese; + for ($i = $start, $j = $start; $i < $start + $length; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $substr .= substr($string, $j, 2); + $j++; + } else { + $substr .= substr($string, $j, 1); + } + $j++; + } + (strlen($substr) < $strlen) && $dot && $substr .= "..."; + return $substr; + } + /** * 以gbk求取字符串长度 * @param string $str 要计算的字符串编码 * @return number - */ - public static function gbk_strlen($string) { - $len = strlen($string); - $i = $count = 0; - while ($i < $len) { - ord($string[$i]) > 129 ? $i += 2 : $i++; - $count++; - } - return $count; - } + */ + public static function gbk_strlen($string) { + $len = strlen($string); + $i = $count = 0; + while ($i < $len) { + ord($string[$i]) > 129 ? $i += 2 : $i++; + $count++; + } + return $count; + } } \ No newline at end of file From d4cd6dcce24445490d79abf569512f910cb9c438 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 16 Aug 2011 09:09:08 +0000 Subject: [PATCH 0296/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2362 18ba2127-5a84-46d4-baec-3457e417f034 --- .../http/request/WindHttpRequest.php | 114 +++++++++++------ .../http/response/WindHttpResponse.php | 119 +++++++++++------- 2 files changed, 152 insertions(+), 81 deletions(-) diff --git a/wind/component/http/request/WindHttpRequest.php b/wind/component/http/request/WindHttpRequest.php index 36841a6d..ee3b4d40 100644 --- a/wind/component/http/request/WindHttpRequest.php +++ b/wind/component/http/request/WindHttpRequest.php @@ -56,15 +56,20 @@ public function __construct() { protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { - if (isset($_GET)) $_GET = $this->stripSlashes($_GET); - if (isset($_POST)) $_POST = $this->stripSlashes($_POST); - if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); - if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); + if (isset($_GET)) + $_GET = $this->stripSlashes($_GET); + if (isset($_POST)) + $_POST = $this->stripSlashes($_POST); + if (isset($_REQUEST)) + $_REQUEST = $this->stripSlashes($_REQUEST); + if (isset($_COOKIE)) + $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { - return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes($data); + return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( + $data); } /** @@ -79,8 +84,10 @@ public function setAttribute($data, $key = '') { $this->_attribute[$key] = $data; return; } - if (is_object($data)) $data = get_object_vars($data); - if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); + if (is_object($data)) + $data = get_object_vars($data); + if (is_array($data)) + $this->_attribute = array_merge($this->_attribute, $data); } /** @@ -113,9 +120,12 @@ public function getAttribute($key, $defaultValue = '') { * @param string $name | attribute name */ public function getRequest($key = null, $defaultValue = null) { - if (!$key) return array_merge($_POST, $_GET); - if (isset($_GET[$key])) return $_GET[$key]; - if (isset($_POST[$key])) return $_POST[$key]; + if (!$key) + return array_merge($_POST, $_GET); + if (isset($_GET[$key])) + return $_GET[$key]; + if (isset($_POST[$key])) + return $_POST[$key]; return $defaultValue; } @@ -138,7 +148,8 @@ public function getQuery($name = null, $defaultValue = null) { * @return string|null */ public function getPost($name = null, $defaultValue = null) { - if ($name == null) return $_POST; + if ($name == null) + return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } @@ -150,7 +161,8 @@ public function getPost($name = null, $defaultValue = null) { * @return string|null */ public function getGet($name = '', $defaultValue = null) { - if ($name == null) return $_GET; + if ($name == null) + return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } @@ -162,7 +174,8 @@ public function getGet($name = '', $defaultValue = null) { * @return string|null|array */ public function getCookie($name = null, $defaultValue = null) { - if ($name == null) return $_COOKIE; + if ($name == null) + return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } @@ -174,7 +187,8 @@ public function getCookie($name = null, $defaultValue = null) { * @return string|null|array */ public function getSession($name = null, $defaultValue = null) { - if ($name == null) return $_SESSION; + if ($name == null) + return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } @@ -186,7 +200,8 @@ public function getSession($name = null, $defaultValue = null) { * @return string|null|array */ public function getServer($name = null, $defaultValue = null) { - if ($name == null) return $_SERVER; + if ($name == null) + return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } @@ -198,7 +213,8 @@ public function getServer($name = null, $defaultValue = null) { * @return string|null|array */ public function getEnv($name = null, $defaultValue = null) { - if ($name == null) return $_ENV; + if ($name == null) + return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } @@ -225,7 +241,8 @@ public function getProtocol() { * @return string|0.0.0.0 */ public function getClientIp() { - if (!$this->_clientIp) $this->_getClientIp(); + if (!$this->_clientIp) + $this->_getClientIp(); return $this->_clientIp; } @@ -304,7 +321,8 @@ public function isDelete() { * @return string */ public function getRequestUri() { - if (!$this->_requestUri) $this->initRequestUri(); + if (!$this->_requestUri) + $this->_initRequestUri(); return $this->_requestUri; } @@ -319,7 +337,8 @@ public function getRequestUri() { * @return string */ public function getScriptUrl() { - if (!$this->_scriptUrl) $this->_initScriptUrl(); + if (!$this->_scriptUrl) + $this->_initScriptUrl(); return $this->_scriptUrl; } @@ -327,7 +346,8 @@ public function getScriptUrl() { * 返回执行脚本 */ public function getScript() { - if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; + if (($pos = strrpos($this->getScriptUrl(), '/')) === false) + $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } @@ -338,11 +358,14 @@ public function getScript() { */ public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); - if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; - if (($header = $this->getServer($temp)) != null) return $header; + if (substr($temp, 0, 5) != 'HTTP_') + $temp = 'HTTP_' . $temp; + if (($header = $this->getServer($temp)) != null) + return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); - if ($headers[$header]) return $headers[$header]; + if ($headers[$header]) + return $headers[$header]; } return $default; } @@ -354,7 +377,8 @@ public function getHeader($header, $default = null) { * @return string */ public function getPathInfo() { - if (!$this->_pathInfo) $this->_initPathInfo(); + if (!$this->_pathInfo) + $this->_initPathInfo(); return $this->_pathInfo; } @@ -374,7 +398,8 @@ public function getPathInfo() { * @return string */ public function getBaseUrl($absolute = false) { - if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); + if ($this->_baseUrl === null) + $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } @@ -384,7 +409,8 @@ public function getBaseUrl($absolute = false) { * @return string */ public function getHostInfo() { - if ($this->_hostInfo === null) $this->_initHostInfo(); + if ($this->_hostInfo === null) + $this->_initHostInfo(); return $this->_hostInfo; } @@ -497,6 +523,16 @@ public function getAcceptLanguage() { return $this->_language; } + /** + * @return WindHttpResponse + */ + public function getResponse() { + $response = new WindHttpResponse(); + $response->setHeader('Content-type', 'text/html'); + $response->setHeader('Content-type', 'charset=UTF-8'); + return $response; + } + /** * 返回访问的IP地址 * @@ -536,15 +572,17 @@ private function _getClientIp() { * * @throws WindException */ - private function initRequestUri() { + private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; - if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); + if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) + $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; - if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; + if (($query = $this->getServer('QUERY_STRING')) != null) + $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } @@ -560,18 +598,22 @@ private function initRequestUri() { * @return */ private function _initScriptUrl() { - if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); + if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; - } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { + } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( + $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; - } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer('SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { - $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); + } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( + 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { + $this->_scriptUrl = str_replace('\\', '/', + str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } @@ -594,7 +636,8 @@ private function _initHostInfo() { $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; - if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; + if (($port = $this->getServerPort()) != null) + $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } @@ -617,7 +660,8 @@ private function _initPathInfo() { $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); - if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); + if (($pos = strpos($pathInfo, '?')) !== false) + $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } \ No newline at end of file diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index 199f9c0d..cd422702 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -29,68 +29,68 @@ class WindHttpResponse implements IWindResponse { * Server status codes; see RFC 2068. * Status code (100) indicating the client can continue. */ - const SC_CONTINUE = 100; + const W_CONTINUE = 100; /** * Status code (101) indicating the server is switching protocols * according to Upgrade header. */ - const SC_SWITCHING_PROTOCOLS = 101; + const W_SWITCHING_PROTOCOLS = 101; /** * Status code (200) indicating the request succeeded normally. */ - const SC_OK = 200; + const W_OK = 200; /** * Status code (201) indicating the request succeeded and created * a new resource on the server. */ - const SC_CREATED = 201; + const W_CREATED = 201; /** * Status code (202) indicating that a request was accepted for * processing, but was not completed. */ - const SC_ACCEPTED = 202; + const W_ACCEPTED = 202; /** * Status code (203) indicating that the meta information presented * by the client did not originate from the server. */ - const SC_NON_AUTHORITATIVE_INFORMATION = 203; + const W_NON_AUTHORITATIVE_INFORMATION = 203; /** * Status code (204) indicating that the request succeeded but that * there was no new information to return. */ - const SC_NO_CONTENT = 204; + const W_NO_CONTENT = 204; /** * Status code (205) indicating that the agent SHOULD reset * the document view which caused the request to be sent. */ - const SC_RESET_CONTENT = 205; + const W_RESET_CONTENT = 205; /** * Status code (206) indicating that the server has fulfilled * the partial GET request for the resource. */ - const SC_PARTIAL_CONTENT = 206; + const W_PARTIAL_CONTENT = 206; /** * Status code (300) indicating that the requested resource * corresponds to any one of a set of representations, each with * its own specific location. */ - const SC_MULTIPLE_CHOICES = 300; + const W_MULTIPLE_CHOICES = 300; /** * Status code (301) indicating that the resource has permanently * moved to a new location, and that future references should use a * new URI with their requests. */ - const SC_MOVED_PERMANENTLY = 301; + const W_MOVED_PERMANENTLY = 301; /** * Status code (302) indicating that the resource has temporarily @@ -98,9 +98,9 @@ class WindHttpResponse implements IWindResponse { * still use the original URI to access the resource. * * This definition is being retained for backwards compatibility. - * SC_FOUND is now the preferred definition. + * W_FOUND is now the preferred definition. */ - const SC_MOVED_TEMPORARILY = 302; + const W_MOVED_TEMPORARILY = 302; /** * Status code (302) indicating that the resource reside @@ -109,26 +109,26 @@ class WindHttpResponse implements IWindResponse { * Request-URI for future requests.(HTTP/1.1) To represent the * status code (302), it is recommended to use this variable. */ - const SC_FOUND = 302; + const W_FOUND = 302; /** * Status code (303) indicating that the response to the request * can be found under a different URI. */ - const SC_SEE_OTHER = 303; + const W_SEE_OTHER = 303; /** * Status code (304) indicating that a conditional GET operation * found that the resource was available and not modified. */ - const SC_NOT_MODIFIED = 304; + const W_NOT_MODIFIED = 304; /** * Status code (305) indicating that the requested resource * MUST be accessed through the proxy given by the * Location field. */ - const SC_USE_PROXY = 305; + const W_USE_PROXY = 305; /** * Status code (307) indicating that the requested resource @@ -136,43 +136,43 @@ class WindHttpResponse implements IWindResponse { * SHOULD be given by the Location * field in the response. */ - const SC_TEMPORARY_REDIRECT = 307; + const W_TEMPORARY_REDIRECT = 307; /** * Status code (400) indicating the request sent by the client was * syntactically incorrect. */ - const SC_BAD_REQUEST = 400; + const W_BAD_REQUEST = 400; /** * Status code (401) indicating that the request requires HTTP * authentication. */ - const SC_UNAUTHORIZED = 401; + const W_UNAUTHORIZED = 401; /** * Status code (402) reserved for future use. */ - const SC_PAYMENT_REQUIRED = 402; + const W_PAYMENT_REQUIRED = 402; /** * Status code (403) indicating the server understood the request * but refused to fulfill it. */ - const SC_FORBIDDEN = 403; + const W_FORBIDDEN = 403; /** * Status code (404) indicating that the requested resource is not * available. */ - const SC_NOT_FOUND = 404; + const W_NOT_FOUND = 404; /** * Status code (405) indicating that the method specified in the * Request-Line is not allowed for the resource * identified by the Request-URI. */ - const SC_METHOD_NOT_ALLOWED = 405; + const W_METHOD_NOT_ALLOWED = 405; /** * Status code (406) indicating that the resource identified by the @@ -180,118 +180,137 @@ class WindHttpResponse implements IWindResponse { * content characteristics not acceptable according to the accept * headers sent in the request. */ - const SC_NOT_ACCEPTABLE = 406; + const W_NOT_ACCEPTABLE = 406; /** * Status code (407) indicating that the client MUST first * authenticate itself with the proxy. */ - const SC_PROXY_AUTHENTICATION_REQUIRED = 407; + const W_PROXY_AUTHENTICATION_REQUIRED = 407; /** * Status code (408) indicating that the client did not produce a * request within the time that the server was prepared to wait. */ - const SC_REQUEST_TIMEOUT = 408; + const W_REQUEST_TIMEOUT = 408; /** * Status code (409) indicating that the request could not be * completed due to a conflict with the current state of the * resource. */ - const SC_CONFLICT = 409; + const W_CONFLICT = 409; /** * Status code (410) indicating that the resource is no longer * available at the server and no forwarding address is known. * This condition SHOULD be considered permanent. */ - const SC_GONE = 410; + const W_GONE = 410; /** * Status code (411) indicating that the request cannot be handled * without a defined Content-Length. */ - const SC_LENGTH_REQUIRED = 411; + const W_LENGTH_REQUIRED = 411; /** * Status code (412) indicating that the precondition given in one * or more of the request-header fields evaluated to false when it * was tested on the server. */ - const SC_PRECONDITION_FAILED = 412; + const W_PRECONDITION_FAILED = 412; /** * Status code (413) indicating that the server is refusing to process * the request because the request entity is larger than the server is * willing or able to process. */ - const SC_REQUEST_ENTITY_TOO_LARGE = 413; + const W_REQUEST_ENTITY_TOO_LARGE = 413; /** * Status code (414) indicating that the server is refusing to service * the request because the Request-URI is longer * than the server is willing to interpret. */ - const SC_REQUEST_URI_TOO_LONG = 414; + const W_REQUEST_URI_TOO_LONG = 414; /** * Status code (415) indicating that the server is refusing to service * the request because the entity of the request is in a format not * supported by the requested resource for the requested method. */ - const SC_UNSUPPORTED_MEDIA_TYPE = 415; + const W_UNSUPPORTED_MEDIA_TYPE = 415; /** * Status code (416) indicating that the server cannot serve the * requested byte range. */ - const SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; /** * Status code (417) indicating that the server could not meet the * expectation given in the Expect request header. */ - const SC_EXPECTATION_FAILED = 417; + const W_EXPECTATION_FAILED = 417; /** * Status code (500) indicating an error inside the HTTP server * which prevented it from fulfilling the request. */ - const SC_INTERNAL_SERVER_ERROR = 500; + const W_INTERNAL_SERVER_ERROR = 500; /** * Status code (501) indicating the HTTP server does not support * the functionality needed to fulfill the request. */ - const SC_NOT_IMPLEMENTED = 501; + const W_NOT_IMPLEMENTED = 501; /** * Status code (502) indicating that the HTTP server received an * invalid response from a server it consulted when acting as a * proxy or gateway. */ - const SC_BAD_GATEWAY = 502; + const W_BAD_GATEWAY = 502; /** * Status code (503) indicating that the HTTP server is * temporarily overloaded, and unable to handle the request. */ - const SC_SERVICE_UNAVAILABLE = 503; + const W_SERVICE_UNAVAILABLE = 503; /** * Status code (504) indicating that the server did not receive * a timely response from the upstream server while acting as * a gateway or proxy. */ - const SC_GATEWAY_TIMEOUT = 504; + const W_GATEWAY_TIMEOUT = 504; /** * Status code (505) indicating that the server does not support * or refuses to support the HTTP protocol version that was used * in the request message. */ - const SC_HTTP_VERSION_NOT_SUPPORTED = 505; + const W_HTTP_VERSION_NOT_SUPPORTED = 505; + + public function codeMap($code) { + $map = array(505 => 'HTTP VERSION NOT SUPPORTED', 504 => 'GATEWAY TIMEOUT', + 503 => 'SERVICE UNAVAILABLE', 503 => 'BAD GATEWAY', 502 => 'BAD GATEWAY', + 501 => 'NOT IMPLEMENTED', 500 => 'INTERNAL SERVER ERROR', 417 => 'EXPECTATION FAILED', + 416 => 'REQUESTED RANGE NOT SATISFIABLE', 415 => 'UNSUPPORTED MEDIA TYPE', + 414 => 'REQUEST URI TOO LONG', 413 => 'REQUEST ENTITY TOO LARGE', + 412 => 'PRECONDITION FAILED', 411 => 'LENGTH REQUIRED', 410 => 'GONE', 409 => 'CONFLICT', + 408 => 'REQUEST TIMEOUT', 407 => 'PROXY AUTHENTICATION REQUIRED', + 406 => 'NOT ACCEPTABLE', 405 => 'METHOD NOT ALLOWED', 404 => 'NOT FOUND', + 403 => 'FORBIDDEN', 402 => 'PAYMENT REQUIRED', 401 => 'UNAUTHORIZED', + 400 => 'BAD REQUEST', 300 => 'MULTIPLE CHOICES', 301 => 'MOVED PERMANENTLY', + 302 => 'MOVED TEMPORARILY', 302 => 'FOUND', 303 => 'SEE OTHER', 304 => 'NOT MODIFIED', + 305 => 'USE PROXY', 307 => 'TEMPORARY REDIRECT', 100 => 'CONTINUE', + 101 => 'WITCHING PROTOCOLS', 200 => 'OK', 201 => 'CREATED', 202 => 'ACCEPTED', + 203 => 'NON AUTHORITATIVE INFORMATION', 204 => 'NO CONTENT', 205 => 'RESET CONTENT', + 206 => 'PARTIAL CONTENT'); + return isset($map[$code]) ? $map[$code] : 'UNKNOWN ERROR'; + } /** * 设置响应头信息,如果已经设置过同名的响应头,该方法将用新的设置取代原来的头字段 @@ -303,9 +322,17 @@ public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); + $setted = false; foreach ($this->_headers as $key => $one) { - ($one['name'] == $name) && $this->_headers[$key] = array('name' => $name, - 'value' => $value, 'replace' => $replace); + if ($one['name'] == $name && $replace === false) { + $this->_headers[$key] = array('name' => $name, + 'value' => $value . '; ' . $one['value'], 'replace' => $replace); + $setted = true; + break; + } + } + if ($setted === false) { + $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } } @@ -365,7 +392,7 @@ public function addCookie(Cookie $cookie) { * @param int $status * @param string $message */ - public function sendError($status = self::SC_NOT_FOUND, $message = '') { + public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); @@ -406,7 +433,7 @@ public function sendHeaders() { foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } - header('HTTP/1.1 ' . $this->_status); + header('HTTP/1.1 ' . $this->_status . " " . $this->codeMap($this->_status)); } /** From 615884842b36ca0c9b8df6a6bfc93da7668657ad Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 16 Aug 2011 09:10:00 +0000 Subject: [PATCH 0297/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2363 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 105 +++++++++++++------------------------------------- 1 file changed, 27 insertions(+), 78 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index a8f6b818..33fb38b3 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -12,6 +12,7 @@ !defined('LOG_DIR') && define('LOG_DIR', COMPILE_PATH . 'log'); !defined('LOG_WRITE_LEVEL') && define('LOG_WRITE_LEVEL', 0); define('DEBUG_TIME', microtime(true)); + /** * the last known user to change this file in the repository <$LastChangedBy: yishuo $> * @author Qiong Wu @@ -72,8 +73,8 @@ public static function runWithCompile($appName = 'default', $config = '') { * @return string */ public static function getAppName() { - if (empty(self::$_currentApp)) throw new WindException('Get appName failed.', - WindException::ERROR_SYSTEM_ERROR); + if (empty(self::$_currentApp)) + throw new WindException('Get appName failed.', WindException::ERROR_SYSTEM_ERROR); return end(self::$_currentApp); } @@ -109,8 +110,10 @@ public static function getApp() { * @return string|null */ public static function import($filePath, $recursivePackage = false) { - if (!$filePath) return; - if (isset(self::$_imports[$filePath])) return self::$_imports[$filePath]; + if (!$filePath) + return; + if (isset(self::$_imports[$filePath])) + return self::$_imports[$filePath]; if (($pos = strrpos($filePath, '.')) !== false) $fileName = substr($filePath, $pos + 1); elseif (($pos1 = strrpos($filePath, ':')) !== false) @@ -121,8 +124,8 @@ public static function import($filePath, $recursivePackage = false) { if ($isPackage) { $filePath = substr($filePath, 0, $pos); $dirPath = self::getRealDir($filePath); - if (!$dh = opendir($dirPath)) throw new Exception( - 'the file ' . $dirPath . ' open failed!'); + if (!$dh = opendir($dirPath)) + throw new Exception('the file ' . $dirPath . ' open failed!'); while (($file = readdir($dh)) !== false) { if (is_dir($dirPath . D_S . $file)) { if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { @@ -156,16 +159,18 @@ public static function import($filePath, $recursivePackage = false) { * @return */ public static function register($path, $alias = '', $includePath = false, $reset = false) { - if (!$path) return; + if (!$path) + return; $alias = strtolower($alias); if (!empty($alias)) { - if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = $path; + if (!isset(self::$_namespace[$alias]) || $reset) + self::$_namespace[$alias] = $path; } if ($includePath) { if (empty(self::$_includePaths)) { self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); - if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset( - self::$_includePaths[$pos]); + if (($pos = array_search('.', self::$_includePaths, true)) !== false) + unset(self::$_includePaths[$pos]); } array_unshift(self::$_includePaths, $path); if (set_include_path( @@ -192,7 +197,8 @@ public static function getRootPath($namespace) { * @return null */ public static function autoLoad($className, $path = '') { - if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; + if (isset(self::$_classes[$className])) + $path = self::$_classes[$className]; if ($path === '') { throw new Exception('auto load ' . $className . ' failed.'); } @@ -255,7 +261,8 @@ public static function getRealDir($dirPath) { * 初始化框架 */ public static function init() { - if (IS_DEBUG) self::_checkEnvironment(); + if (IS_DEBUG) + self::_checkEnvironment(); self::_setDefaultSystemNamespace(); self::_registerAutoloader(); self::_loadBaseLib(); @@ -315,70 +322,12 @@ public static function clear() { self::$_classes = array(); } - /** - * 错误处理句柄 - * @param string $errno - * @param string $errstr - * @param string $errfile - * @param string $errline - */ - public static function errorHandle($errno, $errstr, $errfile, $errline) { - if ($errno & error_reporting()) { - restore_error_handler(); - restore_exception_handler(); - $message = $trace = ''; - if (IS_DEBUG) { - $message = $errstr . '(' . $errfile . ' : ' . $errline . ')'; - $_trace = debug_backtrace(); - foreach ($_trace as $key => $value) { - if (!isset($value['file']) || !isset($value['line']) || !isset( - $value['function'])) continue; - $trace .= "#$key {$value['file']}({$value['line']}): "; - if (isset($value['object']) && is_object($value['object'])) $trace .= get_class( - $value['object']) . '->'; - $trace .= "{$value['function']}()\r\n"; - } - } - self::displayMessage($errstr, $message, $trace); - } - } - - /** - * 异常处理句柄 - * @param Exception $exception - */ - public static function exceptionHandle($exception) { - restore_error_handler(); - restore_exception_handler(); - $header = $message = $trace = ''; - $header = $exception->getMessage(); - if (IS_DEBUG) { - $message = $exception->getMessage() . '(' . $exception->getFile() . ' : ' . $exception->getLine() . ')'; - $trace = $exception->getTraceAsString(); - } - self::displayMessage($header, $message, $trace); - } - - /** - * @param string $header - * @param string $message - * @param string $trace - */ - protected static function displayMessage($header, $message = '', $trace = '') { - $_tmp = "

$header

"; - $_tmp .= "

$message

"; - $_tmp .= "
$trace
"; - echo $_tmp; - } - /** * @return */ protected static function beforRun($appName, $config, $rootPath) { - set_error_handler('Wind::errorHandle'); - set_exception_handler('Wind::exceptionHandle'); - if (!$appName || in_array($appName, self::$_currentApp)) throw new WindException( - 'Nested request', WindException::ERROR_SYSTEM_ERROR); + if (!$appName || in_array($appName, self::$_currentApp)) + throw new WindException('Nested request', WindException::ERROR_SYSTEM_ERROR); array_push(self::$_currentApp, $appName); } @@ -387,9 +336,8 @@ protected static function beforRun($appName, $config, $rootPath) { */ protected static function afterRun($appName, $config, $rootPath) { array_pop(self::$_currentApp); - if (self::$_logger) self::$_logger->flush(); - restore_error_handler(); - restore_exception_handler(); + if (self::$_logger) + self::$_logger->flush(); } /** @@ -426,7 +374,8 @@ private static function _setImport($className, $classPath) { self::$_classes[$className] = $_classPath; } else $_classPath = self::$_classes[$className]; - if (!self::$_isAutoLoad) self::autoLoad($className, $_classPath); + if (!self::$_isAutoLoad) + self::autoLoad($className, $_classPath); } /** @@ -434,7 +383,8 @@ private static function _setImport($className, $classPath) { * @return */ private static function _registerAutoloader() { - if (!self::$_isAutoLoad) return; + if (!self::$_isAutoLoad) + return; if (function_exists('spl_autoload_register')) spl_autoload_register('Wind::autoLoad'); else @@ -469,4 +419,3 @@ private static function _loadBaseLib() { define('COMPONENT_CACHE', 'windCache'); //TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 //********************约定变量*********************************** -define('WIND_M_ERROR', 'windError'); From 79f654b346b174184bbc22b759db62fa9ece4c08 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 16 Aug 2011 10:43:41 +0000 Subject: [PATCH 0298/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2364 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindHelper.php | 27 +++++++++++++++++---------- wind/core/web/WindWebApplication.php | 8 ++++---- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/wind/core/web/WindHelper.php b/wind/core/web/WindHelper.php index 411e9b12..17970601 100644 --- a/wind/core/web/WindHelper.php +++ b/wind/core/web/WindHelper.php @@ -43,7 +43,7 @@ public static function exceptionHandle($exception) { } $file = @$trace[0]['file']; $line = @$trace[0]['line']; - self::crash($exception->getMessage(), $file, $line, $trace); + self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } @@ -53,7 +53,7 @@ public static function exceptionHandle($exception) { * @param string $line * @param array $trace */ - protected static function crash($message, $file, $line, $trace, $status = 500) { + protected static function crash($message, $file, $line, $trace, $status = '') { $errmessage = substr($message, 0, 8000) . "\n"; $topic = "Wind Framework - Error Caught\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); @@ -95,20 +95,27 @@ protected static function crash($message, $file, $line, $trace, $status = 500) { $errsample = implode("\n", $fileLines) . "\n"; } } - $errraised = "$file; line #$line\n"; - $msg = "
$errraised$errsample\n$errtrace
"; - } else { - $status !== '' && $topic = "$status - " . Wind::getApp()->getResponse()->codeMap( - $status) . "\n"; - $msg = "
The server encountered an internal error and failed to process your request.\nPlease try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message
"; + if ($_errhtml) + $errfile = "$file"; + else + $errfile = "$file"; + $msg = "$errfile\n$errsample\n$errtrace\n"; + } + $msg .= "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; + if ($status !== '') { + $topic = "$status - " . ucwords(Wind::getApp()->getResponse()->codeMap($status)) . "\n"; + Wind::getApp()->getResponse()->setStatus($status); } if ($_errhtml) { - $errmessage = "$errmessage"; + $errmessage = "$errmessage"; $topic = "

$topic

"; + $msg = "
$topic$errmessage\n$msg
"; + } else { + $msg = "$topic\n$errmessage\n$msg"; } ob_end_flush(); Wind::getApp()->getResponse()->sendHeaders(); - die($topic . $errmessage . $msg); + die($msg); } /** diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 45f19aac..662bd5a8 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -91,7 +91,8 @@ public function processRequest() { } if (!($module = $this->windSystemConfig->getModules($moduleName))) throw new WindException( - '[core.web.WindWebApplication.processRequest] The module \'' . $moduleName . '\' is not exist.'); + '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', + '404'); $module = WindUtility::mergeArray( $this->windSystemConfig->getDefaultConfigStruct('modules'), $module); $handlerPath = $module['controller-path'] . '.' . ucfirst( @@ -100,7 +101,8 @@ public function processRequest() { $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindFinalException( - '[core.web.WindWebApplication.processRequest] handler path \'' . $handlerPath . '\' is not exist.'); + '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', + '404'); if (strpos($handlerPath, ':') === false) $handlerPath = Wind::getAppName() . ':' . $handlerPath; @@ -124,8 +126,6 @@ public function processRequest() { } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { - echo $e; - exit(); $this->sendErrorMessage($e->getMessage()); } } From ec49359f46beba524f6035054fb247ce2822bc5d Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 16 Aug 2011 10:44:25 +0000 Subject: [PATCH 0299/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2365 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/components_config.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 1d9280a2..24800531 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -31,7 +31,6 @@ - From e26bf14fbcb2279d3737d1fe9ae046d492c743ae Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 04:01:39 +0000 Subject: [PATCH 0300/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2369 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindController.php | 31 +++--- wind/core/web/WindDispatcher.php | 48 ++++----- wind/core/web/WindErrorHandler.php | 15 ++- wind/core/web/WindErrorMessage.php | 38 ++----- wind/core/web/WindForward.php | 33 +++--- wind/core/web/WindHelper.php | 26 ++--- wind/core/web/WindSimpleController.php | 10 +- wind/core/web/WindSystemConfig.php | 28 +++-- wind/core/web/WindWebApplication.php | 142 +++++++++++++------------ 9 files changed, 176 insertions(+), 195 deletions(-) diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php index 4efab31e..c56de63c 100644 --- a/wind/core/web/WindController.php +++ b/wind/core/web/WindController.php @@ -30,20 +30,22 @@ public function run() {} final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { - $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); + $this->registerEventListener('doAction', + new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } - $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); + $this->registerEventListener('doAction', + new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } } /* (non-PHPdoc) * @see WindAction::setDefaultTemplateName() */ - protected function setDefaultTemplateName($handlerAdapter) { /* - $_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); + protected function setDefaultTemplateName($handlerAdapter) { + /*$_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); $this->setTemplate($_temp);*/ } @@ -52,17 +54,18 @@ protected function setDefaultTemplateName($handlerAdapter) { /* */ protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); - if ($action !== 'run') $action = $this->resolvedActionName($action); - try { - if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); - $method = new ReflectionMethod($this, $action); - if ($method->isAbstract() || !$method->isPublic()) { - throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); - } - return $action; - } catch (Exception $exception) { - throw new WindException('[core.web.WindController.resolvedActionMethod] ' . $exception->getMessage()); + if ($action !== 'run') + $action = $this->resolvedActionName($action); + if ($action == 'doAction') { + throw new WindException('[core.web.WindController.resolvedActionMethod]', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); + } + $method = new ReflectionMethod($this, $action); + if ($method->isAbstract() || !$method->isPublic()) { + throw new WindException('[core.web.WindController.resolvedActionMethod]', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); } + return $action; } /** diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php index 45540a84..74aa2e55 100644 --- a/wind/core/web/WindDispatcher.php +++ b/wind/core/web/WindDispatcher.php @@ -15,10 +15,6 @@ class WindDispatcher extends WindModule { * @var array */ protected $processCache = array(); - /** - * @var WindUrlHelper - */ - protected $urlHelper = null; /** * @var boolean */ @@ -29,14 +25,15 @@ class WindDispatcher extends WindModule { * * @param WindForward $forward * @param WindUrlBasedRouter $router + * @param boolean $display * @return */ - public function dispatch($forward, $router) { + public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) - $this->dispatchWithAction($forward, $router); + $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } @@ -65,19 +62,29 @@ protected function dispatchWithRedirect($forward, $router) { /** * 请求分发一个操作请求 + * module/controller/action/?param * @param WindForward $forward - * @param WindUrlBasedRouter $router + * @param WindRouter $router + * @param boolean $display * @return */ - protected function dispatchWithAction($forward, $router) { - //TODO 是否需要缓存上次请求的变量信息 - $this->getRequest()->setAttribute($forward->getVars()); - $this->setDisplay($forward->getDisplay()); - list($_c, $_m) = WindHelper::resolveController($forward->getController()); - $_a = $forward->getAction(); - $_a && $router->setAction($_a); - $_c && $router->setController($_c); - $_m && $router->setModule($_m); + protected function dispatchWithAction($forward, $router, $display) { + if (!$action = $forward->getAction()) + throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', + WindException::ERROR_PARAMETER_TYPE_ERROR); + + $args = $forward->getArgs(); + $this->display = $display; + list($action, $_args) = explode('?', $action . '?'); + $action = trim($action, '/') . '/'; + $action = explode('/', $action); + end($action); + if ($_tmp = prev($action)) + $router->setAction($_tmp); + if ($_tmp = prev($action)) + $router->setController($_tmp); + if ($_tmp = prev($action)) + $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), @@ -113,16 +120,9 @@ protected function checkProcess($router, $check = true) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); - } elseif ($router->getAction() === $this->processCache['action'] && $router->getController() === $this->processCache['controller'] && $router->getModule() === $this->processCache['module']) + } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } - /** - * @return WindUrlHelper - */ - public function getUrlHelper() { - return $this->_getUrlHelper(); - } - } diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php index 5682083b..d4b7e3f7 100644 --- a/wind/core/web/WindErrorHandler.php +++ b/wind/core/web/WindErrorHandler.php @@ -7,6 +7,7 @@ */ class WindErrorHandler extends WindController { protected $error = array(); + protected $errorCode = 0; protected $urlReferer = ''; /* (non-PHPdoc) @@ -14,23 +15,27 @@ class WindErrorHandler extends WindController { */ public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); + $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); - return true; } /* (non-PHPdoc) * @see WindAction::run() */ public function run() { - $this->setOutput("User Error Message: " . $this->error[0], "errorHeader"); - $this->setOutput('', "errorTrace"); + if ($this->errorCode >= 400 && $this->errorCode <= 505) { + $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); + $topic = "$this->errorCode - " . $_statusMsg; + $this->getResponse()->setStatus($this->errorCode); + } else + $topic = "Error message:"; + $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); - $this->setTemplate('default_error'); $this->setTemplatePath('COM:viewer.errorPage'); + $this->setTemplate('default_error'); } - } \ No newline at end of file diff --git a/wind/core/web/WindErrorMessage.php b/wind/core/web/WindErrorMessage.php index 39f54154..d053458a 100644 --- a/wind/core/web/WindErrorMessage.php +++ b/wind/core/web/WindErrorMessage.php @@ -7,19 +7,14 @@ */ class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); - private $errorAction = 'run'; - /** - * @var string - */ - private $errorController = 'windError'; + private $errorAction; /** * @param string $message */ - public function __construct($message = '', $errorAction = '', $errorController = '') { - $this->addError($message); - $this->setErrorAction($errorAction); - $this->setErrorController($errorController); + public function __construct($message = '', $errorAction = '') { + $message !== '' && $this->addError($message); + $errorAction !== '' && $this->setErrorAction($errorAction); } /* (non-PHPdoc) @@ -44,16 +39,13 @@ public function clearError() { public function getError($key = '') { if ($key === '') return $this->error; - else - return isset($this->error[$key]) ? $this->error[$key] : ''; + return isset($this->error[$key]) ? $this->error[$key] : ''; } /* (non-PHPdoc) * @see IWindErrorMessage::addError() */ public function addError($error, $key = '') { - if (!$error) - return; if ($key === '') { if (is_string($error)) $this->error[] = $error; @@ -73,25 +65,11 @@ public function getErrorAction() { } /** - * @return the $errorController - */ - public function getErrorController() { - return $this->errorController; - } - - /** - * @param field_type $errorAction + * /module/controller/action/?a=b&c=a + * @param string $errorAction */ public function setErrorAction($errorAction) { - if ($errorAction) - $this->errorAction = $errorAction; + $this->errorAction = $errorAction; } - /** - * @param field_type $errorController - */ - public function setErrorController($errorController) { - if ($errorController) - $this->errorController = $errorController; - } } \ No newline at end of file diff --git a/wind/core/web/WindForward.php b/wind/core/web/WindForward.php index ce404354..f2f46fd9 100644 --- a/wind/core/web/WindForward.php +++ b/wind/core/web/WindForward.php @@ -64,7 +64,6 @@ class WindForward extends WindModule { private $action; private $controller; private $args; - private $display = false; /** * 将请求重定向到另外一个Action操作 @@ -83,6 +82,23 @@ public function forwardAnotherAction($action = 'run', $controller = '', $args = $this->setIsRedirect($isRedirect); } + /** + * 将请求重定向到另外一个Action操作 + * $action参数支持: + * module/controller/action/?a=&b=&c= + * + * @param string $action | $action 操作 + * @param array $args | 参数 + * @param boolean $isRedirect | 是否重定向 + * @return + */ + public function forwardAction($action, $args = array(), $isRedirect = false) { + $this->setIsReAction(true); + $this->setAction($action); + $this->setArgs($args); + $this->setIsRedirect($isRedirect); + } + /** * 设置页面模板变量 * @@ -260,19 +276,4 @@ public function getWindView() { public function setWindView($windView) { $this->windView = $windView; } - - /** - * @return the $display - */ - public function getDisplay() { - return $this->display; - } - - /** - * @param field_type $display - */ - public function setDisplay($display) { - $this->display = $display; - } - } \ No newline at end of file diff --git a/wind/core/web/WindHelper.php b/wind/core/web/WindHelper.php index 17970601..0aef953e 100644 --- a/wind/core/web/WindHelper.php +++ b/wind/core/web/WindHelper.php @@ -53,9 +53,8 @@ public static function exceptionHandle($exception) { * @param string $line * @param array $trace */ - protected static function crash($message, $file, $line, $trace, $status = '') { + protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; - $topic = "Wind Framework - Error Caught\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { @@ -64,6 +63,7 @@ protected static function crash($message, $file, $line, $trace, $status = '') { break; } } + $msg = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); @@ -102,19 +102,19 @@ protected static function crash($message, $file, $line, $trace, $status = '') { $msg = "$errfile\n$errsample\n$errtrace\n"; } $msg .= "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; - if ($status !== '') { - $topic = "$status - " . ucwords(Wind::getApp()->getResponse()->codeMap($status)) . "\n"; - Wind::getApp()->getResponse()->setStatus($status); - } + if ($status >= 400 && $status <= 505) { + $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); + $topic = "$status - " . $_statusMsg . "\n"; + header('HTTP/1.x ' . $status . ' ' . $_statusMsg); + header('Status: ' . $status . ' ' . $_statusMsg); + } else + $topic = "Wind Framework - Error Caught\n"; if ($_errhtml) { - $errmessage = "$errmessage"; - $topic = "

$topic

"; - $msg = "
$topic$errmessage\n$msg
"; - } else { + $msg = "$topic

$topic

$errmessage\n$msg
"; + } else $msg = "$topic\n$errmessage\n$msg"; - } - ob_end_flush(); - Wind::getApp()->getResponse()->sendHeaders(); + + ob_end_clean(); die($msg); } diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index a10c8ea8..b41dace6 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -59,11 +59,9 @@ public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); - Wind::log( - '[core.web.controller.WindSimpleController.doAction] resolved action method:' . $method, - WindLogger::LEVEL_INFO, 'wind.core'); call_user_func_array(array($this, $method), array()); - $this->getErrorMessage()->sendError(); + if ($this->errorMessage !== null) + $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } @@ -193,13 +191,11 @@ protected function addMessage($message, $key = '') { * @param string $message * @param string $key * @param string $errorAction - * @param string $errorController * @return */ - protected function showMessage($message = '', $key = '', $errorAction = '', $errorController = '') { + protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); - $this->getErrorMessage()->setErrorController($errorController); $this->getErrorMessage()->sendError(); } diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php index cc6c5336..54b8f800 100644 --- a/wind/core/web/WindSystemConfig.php +++ b/wind/core/web/WindSystemConfig.php @@ -139,13 +139,15 @@ public function getModules($name = '') { * @return */ public function setModules($name, $config = array()) { - if (isset($this->_config['modules'][$name])) - return; + if (!$_default = @$this->_config['modules']['default']) { + $_default = $this->getDefaultConfigStruct('modules'); + $this->_config['modules']['default'] = $_default; + } if (!$config) - $this->_config['modules'][$name] = $this->getDefaultConfigStruct('modules'); + $this->_config['modules'][$name] = $_default; else - $this->_config['modules'][$name] = WindUtility::mergeArray( - $this->getDefaultConfigStruct('modules'), $config); + $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); + return $this->_config['modules'][$name]; } /** @@ -157,15 +159,6 @@ public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } - /** - * 根据module名称返回module的视图配置信息 - * @param string $name - * @param string $default - */ - public function getModuleViewConfig($name, $default = '') { - return $this->getConfig('view', 'config', $default, $this->getModules($name)); - } - /** * 根据module名称返回错误的处理句柄 * @param string $name @@ -240,8 +233,11 @@ private function parseConfig($config, $key = 'config', $append = true) { */ public function getDefaultConfigStruct($configName) { $_tmp = array(); - $_tmp['modules'] = array('controller-path' => 'controller', - 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); + $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); + $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', + 'Controller'); + $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', + 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 662bd5a8..2ecfd027 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -27,7 +27,7 @@ class WindWebApplication extends WindModule implements IWindApplication { */ protected $dispatcher = null; /** - * @var WindUrlBasedRouter + * @var WindRouter */ protected $handlerAdapter = null; @@ -63,23 +63,25 @@ public function run() { /* (non-PHPdoc) * @see IWindApplication::doDispatch() */ - public function doDispatch($forward, $module = array()) { - if ($forward === null) { - Wind::log('[core.web.WindWebApplication.doDispatch] Forward is null, dispatch abort.', - WindLogger::LEVEL_DEBUG, 'wind.core'); + public function doDispatch($forward, $display = false) { + if ($forward === null) return; - } - if ($module) { - /* @var $forward WindForward */ - if ($forward->getTemplateExt() === null && isset($module['template-ext'])) - $forward->setTemplateExt($module['template-ext']); - if ($forward->getTemplatePath() === null && isset($module['template-dir'])) - $forward->setTemplatePath($module['template-dir']); - } - $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter); + $moduleName = $this->handlerAdapter->getModule(); + if (!($module = $this->windSystemConfig->getModules($moduleName))) + throw new WindActionException( + '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', + 404); + + /* @var $forward WindForward */ + if ($forward->getTemplateExt() === null && isset($module['template-ext'])) + $forward->setTemplateExt($module['template-ext']); + if ($forward->getTemplatePath() === null && isset($module['template-dir'])) + $forward->setTemplatePath($module['template-dir']); + $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } /** + * 请求处理 * @return */ public function processRequest() { @@ -87,22 +89,22 @@ public function processRequest() { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; - $this->windSystemConfig->setModules($moduleName); + $this->handlerAdapter->setModule($moduleName); + $module = $this->windSystemConfig->setModules($moduleName); + } else { + if (!($module = $this->windSystemConfig->getModules($moduleName))) + throw new WindActionException( + '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', + 404); + $module = $this->windSystemConfig->setModules($moduleName, $module); } - if (!($module = $this->windSystemConfig->getModules($moduleName))) - throw new WindException( - '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', - '404'); - $module = WindUtility::mergeArray( - $this->windSystemConfig->getDefaultConfigStruct('modules'), $module); - $handlerPath = $module['controller-path'] . '.' . ucfirst( - $this->handlerAdapter->getController()) . $module['controller-suffix']; - + $handlerPath = @$module['controller-path'] . '.' . ucfirst( + $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) - throw new WindFinalException( + throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', - '404'); + 404); if (strpos($handlerPath, ':') === false) $handlerPath = Wind::getAppName() . ':' . $handlerPath; @@ -114,36 +116,64 @@ public function processRequest() { 'urlHelper' => array('ref' => 'urlHelper')))); } $handler = $this->windFactory->getInstance($handlerPath); - if ($handler === null) - throw new WindFinalException( - '[core.web.WindWebApplication.processRequest] action handler \'' . $handlerPath . '\' is not exist.'); + + if (!$handler) + throw new WindActionException( + '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', + 404); call_user_func_array(array($handler, 'preAction'), array($this->handlerAdapter)); $forward = call_user_func_array(array($handler, 'doAction'), array($this->handlerAdapter)); call_user_func_array(array($handler, 'postAction'), array($this->handlerAdapter)); - - $this->doDispatch($forward, $module); + $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { - $this->sendErrorMessage($e->getMessage()); + $this->sendErrorMessage($e); } } /** - * 返回module配置信息 - * @return array + * 异常处理请求 + * @param WindActionException actionException + * @return */ - protected function resolveModule() { + protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); - if (!$moduleName) { - $moduleName = 'default'; - $this->windSystemConfig->setModules($moduleName); - } - if (!($module = $this->windSystemConfig->getModules($moduleName))) + if ($moduleName === 'error' || !($module = $this->windSystemConfig->getModules($moduleName))) throw new WindException( - '[core.web.WindWebApplication.processRequest] The module \'' . $moduleName . '\' is not exist.'); - return $module; + '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); + + if ($exception instanceof WindActionException) + $errorMessage = $exception->getError(); + if (!$errorMessage) { + $errorMessage = $this->windFactory->getInstance('errorMessage'); + $errorMessage->addError($exception->getMessage()); + } + if (!$_errorAction = $errorMessage->getErrorAction()) { + preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); + $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); + $_errorAction = 'error/' . @$matchs[0] . '/run/'; + $this->windSystemConfig->setModules('error', + array('controller-path' => $_errorHandler, 'controller-suffix' => '', + 'error-handler' => '')); + } + $forward = $this->getSystemFactory()->getInstance('forward'); + $forward->forwardAction($_errorAction); + $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); + $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); + $this->doDispatch($forward); + } + + /** + * @return WindFilterChain + */ + protected function getFilterChain() { + if (!($filters = $this->getWindSystemConfig()->getFilters())) + return null; + if (!($filterChainPath = $this->getWindSystemConfig()->getFilterClass())) + return null; + return $this->getWindFactory()->createInstance($filterChainPath, array($filters)); } /** @@ -159,34 +189,6 @@ public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } - /** - * 异常处理请求 - * - * @param WindActionException|string actionException - * @return - */ - protected function sendErrorMessage($actionException, $errorCode = '') { - $_tmp = is_object($actionException) ? $actionException->getError() : $actionException; - if (is_string($_tmp)) - $_tmp = new WindErrorMessage($_tmp); - $forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD); - $forward->forwardAnotherAction($_tmp->getErrorAction(), $_tmp->getErrorController()); - $this->getRequest()->setAttribute($_tmp->getError(), 'error'); - $this->getRequest()->setAttribute($errorCode, 'errorCode'); - $this->doDispatch($forward); - } - - /** - * @return WindFilterChain - */ - protected function getFilterChain() { - if (!($filters = $this->getWindSystemConfig()->getFilters())) - return null; - if (!($filterChainPath = $this->getWindSystemConfig()->getFilterClass())) - return null; - return $this->getWindFactory()->createInstance($filterChainPath, array($filters)); - } - /** * @return WindHttpRequest $request */ From 6dd690c420f4d3dc11704cc39bcae7b0e1ef35fa Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 04:01:47 +0000 Subject: [PATCH 0301/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2370 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 271b2bc6..d8cc7d5a 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -148,7 +148,7 @@ public function checkAlias($alias) { protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': - $this->prototype[$alias] = $instance; + $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; From 77fc5d3976eba667093ba1f21c4302f51262e6b3 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 04:01:54 +0000 Subject: [PATCH 0302/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2371 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/exception/WindActionException.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/core/exception/WindActionException.php b/wind/core/exception/WindActionException.php index 027cc34f..eddd73e8 100644 --- a/wind/core/exception/WindActionException.php +++ b/wind/core/exception/WindActionException.php @@ -13,9 +13,9 @@ class WindActionException extends WindException { /** * @param WindErrorMessage $error */ - public function __construct($error) { + public function __construct($error, $code = 0) { $this->setError($error); - parent::__construct(''); + parent::__construct($error->getError(0), $code); } /** From 0773c3cef770b4843bb7a7b4624f9cf9ea1b9ee7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 04:02:03 +0000 Subject: [PATCH 0303/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2372 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/errorPage/default_error.htm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wind/component/viewer/errorPage/default_error.htm b/wind/component/viewer/errorPage/default_error.htm index 78dd07e6..9bbfc757 100644 --- a/wind/component/viewer/errorPage/default_error.htm +++ b/wind/component/viewer/errorPage/default_error.htm @@ -2,14 +2,14 @@ -{@G_PAGE:title} -{@G_PAGE:head} +{@G:title} +{@G:head} -

{$errorHeader}

+

{$errorHeader}

#{$key}. {$error}
+#-->{$key}. {$error}

Click here go back!

From 023bf44ce4ffd4274f006a1f58891e1338ebd9ce Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 04:02:20 +0000 Subject: [PATCH 0304/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2373 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 3 +- wind/_compile/components_config.xml | 3 +- .../http/request/WindHttpRequest.php | 3 +- .../http/response/WindHttpResponse.php | 38 ++++++++++--------- .../component/router/WindUrlRewriteRouter.php | 1 - wind/component/viewer/WindViewerResolver.php | 6 +-- .../compiler/WindTemplateCompilerEcho.php | 2 +- 7 files changed, 30 insertions(+), 26 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 33fb38b3..99beeea9 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -204,7 +204,8 @@ public static function autoLoad($className, $path = '') { } $path .= '.' . self::$_extensions; if ((@include $path) === false) { - throw new Exception('[wind.Wind.autoLoad] auto load class ' . $className . ' failed.'); + throw new Exception( + '[wind.Wind.autoLoad] Your requested \'' . $path . '\' was not found on this server.'); } } diff --git a/wind/_compile/components_config.xml b/wind/_compile/components_config.xml index 24800531..97486198 100644 --- a/wind/_compile/components_config.xml +++ b/wind/_compile/components_config.xml @@ -58,7 +58,8 @@ + scope='prototype'> +
diff --git a/wind/component/http/request/WindHttpRequest.php b/wind/component/http/request/WindHttpRequest.php index ee3b4d40..c79f5a3a 100644 --- a/wind/component/http/request/WindHttpRequest.php +++ b/wind/component/http/request/WindHttpRequest.php @@ -528,8 +528,7 @@ public function getAcceptLanguage() { */ public function getResponse() { $response = new WindHttpResponse(); - $response->setHeader('Content-type', 'text/html'); - $response->setHeader('Content-type', 'charset=UTF-8'); + $response->setHeader('Content-type', 'text/html;charset=UTF-8'); return $response; } diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index cd422702..d4d6d53a 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -294,22 +294,22 @@ class WindHttpResponse implements IWindResponse { const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { - $map = array(505 => 'HTTP VERSION NOT SUPPORTED', 504 => 'GATEWAY TIMEOUT', - 503 => 'SERVICE UNAVAILABLE', 503 => 'BAD GATEWAY', 502 => 'BAD GATEWAY', - 501 => 'NOT IMPLEMENTED', 500 => 'INTERNAL SERVER ERROR', 417 => 'EXPECTATION FAILED', - 416 => 'REQUESTED RANGE NOT SATISFIABLE', 415 => 'UNSUPPORTED MEDIA TYPE', - 414 => 'REQUEST URI TOO LONG', 413 => 'REQUEST ENTITY TOO LARGE', - 412 => 'PRECONDITION FAILED', 411 => 'LENGTH REQUIRED', 410 => 'GONE', 409 => 'CONFLICT', - 408 => 'REQUEST TIMEOUT', 407 => 'PROXY AUTHENTICATION REQUIRED', - 406 => 'NOT ACCEPTABLE', 405 => 'METHOD NOT ALLOWED', 404 => 'NOT FOUND', - 403 => 'FORBIDDEN', 402 => 'PAYMENT REQUIRED', 401 => 'UNAUTHORIZED', - 400 => 'BAD REQUEST', 300 => 'MULTIPLE CHOICES', 301 => 'MOVED PERMANENTLY', - 302 => 'MOVED TEMPORARILY', 302 => 'FOUND', 303 => 'SEE OTHER', 304 => 'NOT MODIFIED', - 305 => 'USE PROXY', 307 => 'TEMPORARY REDIRECT', 100 => 'CONTINUE', - 101 => 'WITCHING PROTOCOLS', 200 => 'OK', 201 => 'CREATED', 202 => 'ACCEPTED', - 203 => 'NON AUTHORITATIVE INFORMATION', 204 => 'NO CONTENT', 205 => 'RESET CONTENT', - 206 => 'PARTIAL CONTENT'); - return isset($map[$code]) ? $map[$code] : 'UNKNOWN ERROR'; + $map = array(505 => 'http version not supported', 504 => 'gateway timeout', + 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', + 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', + 416 => 'requested range not satisfiable', 415 => 'unsupported media type', + 414 => 'request uri too long', 413 => 'request entity too large', + 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', + 408 => 'request timeout', 407 => 'proxy authentication required', + 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', + 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', + 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', + 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', + 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', + 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', + 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', + 206 => 'partial content'); + return isset($map[$code]) ? $map[$code] : ''; } /** @@ -422,6 +422,7 @@ public function sendRedirect($location, $status = 302) { public function sendResponse() { $this->sendHeaders(); $this->sendBody(); + exit(); } /** @@ -433,7 +434,10 @@ public function sendHeaders() { foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } - header('HTTP/1.1 ' . $this->_status . " " . $this->codeMap($this->_status)); + if ($this->_status) { + header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); + header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); + } } /** diff --git a/wind/component/router/WindUrlRewriteRouter.php b/wind/component/router/WindUrlRewriteRouter.php index a81058bb..6481a873 100644 --- a/wind/component/router/WindUrlRewriteRouter.php +++ b/wind/component/router/WindUrlRewriteRouter.php @@ -331,7 +331,6 @@ private function getUrlParamValue($type, $defaultValue = '') { */ public function route() { // TODO Auto-generated method stub - } diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index 794a2924..d8d91ebf 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -87,10 +87,10 @@ public function compile($template, $suffix = '', $output = false) { */ protected function render($template) { list($_tmp, $_output) = $this->compile($template); - $_var = Wind::getApp()->getResponse()->getData('G'); + /*$_var = Wind::getApp()->getResponse()->getData('G'); if (isset($this->vars[$template])) - $_var += $this->vars[$template]; - @extract($_var, EXTR_REFS); + $_var += $this->vars[$template];*/ + @extract(@$this->vars[$template], EXTR_REFS); if (!@include ($_tmp)) { throw new WindViewException( '[component.viewer.ViewerResolver.render] template name ' . $template, diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index 62ce7bb0..ca900b8f 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -47,7 +47,7 @@ private function compileVarShare($input) { if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) return $input; list($templateName, $var) = explode(':', $input); - return '$this->getResponse()->getData(\'' . $templateName . '\', \'' . $var . '\')'; + return 'Wind::getApp()->getResponse()->getData(\'' . $templateName . '\', \'' . $var . '\')'; } /** From 56337abbc89df66390344a8029fc05656a2d11ce Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 04:12:50 +0000 Subject: [PATCH 0305/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2374 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/http/response/WindHttpResponse.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index d4d6d53a..25dd7af7 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -324,16 +324,15 @@ public function setHeader($name, $value, $replace = false) { $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { - if ($one['name'] == $name && $replace === false) { - $this->_headers[$key] = array('name' => $name, - 'value' => $value . '; ' . $one['value'], 'replace' => $replace); + if ($one['name'] == $name) { + $this->_headers[$key] = array('name' => $name, 'value' => $value, + 'replace' => $replace); $setted = true; break; } } - if ($setted === false) { + if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); - } } /** From ea71ca0ebb5e670df5a78205b6e11182ba9bfffe Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 06:19:19 +0000 Subject: [PATCH 0306/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2375 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index 99beeea9..7785bfa1 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -398,7 +398,48 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - self::$_classes = array(); + self::$_classes = array( + 'WindLogger' => 'log/WindLogger', + 'WindActionException' => 'core/exception/WindActionException', + 'WindException' => 'core/exception/WindException', + 'WindFinalException' => 'core/exception/WindFinalException', + 'IWindFactory' => 'core/factory/IWindFactory', + 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', + 'WindFactory' => 'core/factory/WindFactory', + 'IWindApplication' => 'core/IWindApplication', + 'IWindController' => 'core/IWindController', + 'IWindErrorMessage' => 'core/IWindErrorMessage', + 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', + 'WindFormListener' => 'core/web/listener/WindFormListener', + 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', + 'WindValidateListener' => 'core/web/listener/WindValidateListener', + 'WindController' => 'core/web/WindController', + 'WindDispatcher' => 'core/web/WindDispatcher', + 'WindErrorHandler' => 'core/web/WindErrorHandler', + 'WindErrorMessage' => 'core/web/WindErrorMessage', + 'WindForward' => 'core/web/WindForward', + 'WindHelper' => 'core/web/WindHelper', + 'WindSimpleController' => 'core/web/WindSimpleController', + 'WindSystemConfig' => 'core/web/WindSystemConfig', + 'WindUrlHelper' => 'core/web/WindUrlHelper', + 'WindWebApplication' => 'core/web/WindWebApplication', + 'WindEnableValidateModule' => 'core/WindEnableValidateModule', + 'WindModule' => 'core/WindModule', + 'WindFilter' => 'filter/WindFilter', + 'WindFilterChain' => 'filter/WindFilterChain', + 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', + 'WindConfigParser' => 'parser/WindConfigParser', + 'IWindRequest' => 'http/request/IWindRequest', + 'WindHttpRequest' => 'http/request/WindHttpRequest', + 'IWindResponse' => 'http/response/IWindResponse', + 'WindHttpResponse' => 'http/response/WindHttpResponse', + 'AbstractWindRouter' => 'router/AbstractWindRouter', + 'AbstractWindRoute' => 'router/route/AbstractWindRoute', + 'WindRewriteRoute' => 'router/route/WindRewriteRoute', + 'WindRoute' => 'router/route/WindRoute', + 'WindRouter' => 'router/WindRouter', + 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter'); } } Wind::init(); From c74526e29573ad59cf89d05676f964374c489ffa Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 06:50:28 +0000 Subject: [PATCH 0307/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2376 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/http/response/WindHttpResponse.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index 25dd7af7..42a1bf84 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -421,7 +421,6 @@ public function sendRedirect($location, $status = 302) { public function sendResponse() { $this->sendHeaders(); $this->sendBody(); - exit(); } /** From d130e0aa9b7b223c8ca61f789d8f57e84633bc8f Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 06:57:59 +0000 Subject: [PATCH 0308/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2377 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 83 ++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 7785bfa1..cd11719b 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -199,9 +199,8 @@ public static function getRootPath($namespace) { public static function autoLoad($className, $path = '') { if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; - if ($path === '') { + if ($path === '') throw new Exception('auto load ' . $className . ' failed.'); - } $path .= '.' . self::$_extensions; if ((@include $path) === false) { throw new Exception( @@ -398,48 +397,44 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - self::$_classes = array( - 'WindLogger' => 'log/WindLogger', - 'WindActionException' => 'core/exception/WindActionException', - 'WindException' => 'core/exception/WindException', - 'WindFinalException' => 'core/exception/WindFinalException', - 'IWindFactory' => 'core/factory/IWindFactory', - 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', - 'WindFactory' => 'core/factory/WindFactory', - 'IWindApplication' => 'core/IWindApplication', - 'IWindController' => 'core/IWindController', - 'IWindErrorMessage' => 'core/IWindErrorMessage', - 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', - 'WindFormListener' => 'core/web/listener/WindFormListener', - 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', - 'WindValidateListener' => 'core/web/listener/WindValidateListener', - 'WindController' => 'core/web/WindController', - 'WindDispatcher' => 'core/web/WindDispatcher', - 'WindErrorHandler' => 'core/web/WindErrorHandler', - 'WindErrorMessage' => 'core/web/WindErrorMessage', - 'WindForward' => 'core/web/WindForward', - 'WindHelper' => 'core/web/WindHelper', - 'WindSimpleController' => 'core/web/WindSimpleController', - 'WindSystemConfig' => 'core/web/WindSystemConfig', - 'WindUrlHelper' => 'core/web/WindUrlHelper', - 'WindWebApplication' => 'core/web/WindWebApplication', - 'WindEnableValidateModule' => 'core/WindEnableValidateModule', - 'WindModule' => 'core/WindModule', - 'WindFilter' => 'filter/WindFilter', - 'WindFilterChain' => 'filter/WindFilterChain', - 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', - 'WindConfigParser' => 'parser/WindConfigParser', - 'IWindRequest' => 'http/request/IWindRequest', - 'WindHttpRequest' => 'http/request/WindHttpRequest', - 'IWindResponse' => 'http/response/IWindResponse', - 'WindHttpResponse' => 'http/response/WindHttpResponse', - 'AbstractWindRouter' => 'router/AbstractWindRouter', - 'AbstractWindRoute' => 'router/route/AbstractWindRoute', - 'WindRewriteRoute' => 'router/route/WindRewriteRoute', - 'WindRoute' => 'router/route/WindRoute', - 'WindRouter' => 'router/WindRouter', - 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter'); + self::$_classes = array('WindLogger' => 'log/WindLogger', + 'WindActionException' => 'core/exception/WindActionException', + 'WindException' => 'core/exception/WindException', + 'WindFinalException' => 'core/exception/WindFinalException', + 'IWindFactory' => 'core/factory/IWindFactory', + 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', + 'WindFactory' => 'core/factory/WindFactory', + 'IWindApplication' => 'core/IWindApplication', + 'IWindController' => 'core/IWindController', + 'IWindErrorMessage' => 'core/IWindErrorMessage', + 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', + 'WindFormListener' => 'core/web/listener/WindFormListener', + 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', + 'WindValidateListener' => 'core/web/listener/WindValidateListener', + 'WindController' => 'core/web/WindController', + 'WindDispatcher' => 'core/web/WindDispatcher', + 'WindErrorHandler' => 'core/web/WindErrorHandler', + 'WindErrorMessage' => 'core/web/WindErrorMessage', + 'WindForward' => 'core/web/WindForward', 'WindHelper' => 'core/web/WindHelper', + 'WindSimpleController' => 'core/web/WindSimpleController', + 'WindSystemConfig' => 'core/web/WindSystemConfig', + 'WindUrlHelper' => 'core/web/WindUrlHelper', + 'WindWebApplication' => 'core/web/WindWebApplication', + 'WindEnableValidateModule' => 'core/WindEnableValidateModule', + 'WindModule' => 'core/WindModule', 'WindFilter' => 'filter/WindFilter', + 'WindFilterChain' => 'filter/WindFilterChain', + 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', + 'WindConfigParser' => 'parser/WindConfigParser', + 'IWindRequest' => 'http/request/IWindRequest', + 'WindHttpRequest' => 'http/request/WindHttpRequest', + 'IWindResponse' => 'http/response/IWindResponse', + 'WindHttpResponse' => 'http/response/WindHttpResponse', + 'AbstractWindRouter' => 'router/AbstractWindRouter', + 'AbstractWindRoute' => 'router/route/AbstractWindRoute', + 'WindRewriteRoute' => 'router/route/WindRewriteRoute', + 'WindRoute' => 'router/route/WindRoute', 'WindRouter' => 'router/WindRouter', + 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter'); } } Wind::init(); From 5b74063829c68173553356f206941329e59501b9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 07:03:29 +0000 Subject: [PATCH 0309/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2378 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index cd11719b..a1225935 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -202,10 +202,9 @@ public static function autoLoad($className, $path = '') { if ($path === '') throw new Exception('auto load ' . $className . ' failed.'); $path .= '.' . self::$_extensions; - if ((@include $path) === false) { + if ((@include $path) === false) throw new Exception( '[wind.Wind.autoLoad] Your requested \'' . $path . '\' was not found on this server.'); - } } /** From 2fd5c829cd66f1374eb8d64670c568eb88710d70 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 07:38:25 +0000 Subject: [PATCH 0310/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2379 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.xml | 91 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 wind/components_config.xml diff --git a/wind/components_config.xml b/wind/components_config.xml new file mode 100644 index 00000000..97486198 --- /dev/null +++ b/wind/components_config.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + template + htm + 0 + compile.template + 0 + + + + + + + + + + + + + + + + + + + + + + compile + default + + cache + + key + + value + + expire + + + + + compile.cache + php + 10 + + + + From 7625fc753bde737c25d0f2404beacfacf096acf8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 08:13:44 +0000 Subject: [PATCH 0311/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2380 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/{configtemplate => config}/db_config.xml | 0 .../dbcache_config.xml | 0 .../filecache_config.xml | 0 .../ini/compiler_config.ini | 0 .../ini/db_config.ini | 0 .../ini/dbcache_config.ini | 0 .../ini/filecache_config.ini | 0 .../ini/memcache.ini | 0 .../ini/wind_config.ini | 0 .../memcache_config.xml | 0 .../php/compiler_config.php | 0 .../php/db_config.php | 0 .../php/dbcache_config.php | 0 .../php/filecache_config.php | 0 .../php/memcache.php | 0 .../php/wind_config.php | 0 .../properties/db_config.properties | 0 .../properties/dbcache_config.properties | 0 .../properties/filecache_config.properties | 0 .../properties/memcache.properties | 0 .../properties/viewTemplateConfig.properties | 0 .../properties/wind_config.properties | 0 docs/config/router_config.xml | 25 +++++++++++++++++++ .../view_compiler_config.xml | 0 .../view_config.xml | 2 -- .../wind_config.xml | 0 26 files changed, 25 insertions(+), 2 deletions(-) rename docs/{configtemplate => config}/db_config.xml (100%) rename docs/{configtemplate => config}/dbcache_config.xml (100%) rename docs/{configtemplate => config}/filecache_config.xml (100%) rename docs/{configtemplate => config}/ini/compiler_config.ini (100%) rename docs/{configtemplate => config}/ini/db_config.ini (100%) rename docs/{configtemplate => config}/ini/dbcache_config.ini (100%) rename docs/{configtemplate => config}/ini/filecache_config.ini (100%) rename docs/{configtemplate => config}/ini/memcache.ini (100%) rename docs/{configtemplate => config}/ini/wind_config.ini (100%) rename docs/{configtemplate => config}/memcache_config.xml (100%) rename docs/{configtemplate => config}/php/compiler_config.php (100%) rename docs/{configtemplate => config}/php/db_config.php (100%) rename docs/{configtemplate => config}/php/dbcache_config.php (100%) rename docs/{configtemplate => config}/php/filecache_config.php (100%) rename docs/{configtemplate => config}/php/memcache.php (100%) rename docs/{configtemplate => config}/php/wind_config.php (100%) rename docs/{configtemplate => config}/properties/db_config.properties (100%) rename docs/{configtemplate => config}/properties/dbcache_config.properties (100%) rename docs/{configtemplate => config}/properties/filecache_config.properties (100%) rename docs/{configtemplate => config}/properties/memcache.properties (100%) rename docs/{configtemplate => config}/properties/viewTemplateConfig.properties (100%) rename docs/{configtemplate => config}/properties/wind_config.properties (100%) create mode 100644 docs/config/router_config.xml rename docs/{configtemplate => config}/view_compiler_config.xml (100%) rename docs/{configtemplate => config}/view_config.xml (70%) rename docs/{configtemplate => config}/wind_config.xml (100%) diff --git a/docs/configtemplate/db_config.xml b/docs/config/db_config.xml similarity index 100% rename from docs/configtemplate/db_config.xml rename to docs/config/db_config.xml diff --git a/docs/configtemplate/dbcache_config.xml b/docs/config/dbcache_config.xml similarity index 100% rename from docs/configtemplate/dbcache_config.xml rename to docs/config/dbcache_config.xml diff --git a/docs/configtemplate/filecache_config.xml b/docs/config/filecache_config.xml similarity index 100% rename from docs/configtemplate/filecache_config.xml rename to docs/config/filecache_config.xml diff --git a/docs/configtemplate/ini/compiler_config.ini b/docs/config/ini/compiler_config.ini similarity index 100% rename from docs/configtemplate/ini/compiler_config.ini rename to docs/config/ini/compiler_config.ini diff --git a/docs/configtemplate/ini/db_config.ini b/docs/config/ini/db_config.ini similarity index 100% rename from docs/configtemplate/ini/db_config.ini rename to docs/config/ini/db_config.ini diff --git a/docs/configtemplate/ini/dbcache_config.ini b/docs/config/ini/dbcache_config.ini similarity index 100% rename from docs/configtemplate/ini/dbcache_config.ini rename to docs/config/ini/dbcache_config.ini diff --git a/docs/configtemplate/ini/filecache_config.ini b/docs/config/ini/filecache_config.ini similarity index 100% rename from docs/configtemplate/ini/filecache_config.ini rename to docs/config/ini/filecache_config.ini diff --git a/docs/configtemplate/ini/memcache.ini b/docs/config/ini/memcache.ini similarity index 100% rename from docs/configtemplate/ini/memcache.ini rename to docs/config/ini/memcache.ini diff --git a/docs/configtemplate/ini/wind_config.ini b/docs/config/ini/wind_config.ini similarity index 100% rename from docs/configtemplate/ini/wind_config.ini rename to docs/config/ini/wind_config.ini diff --git a/docs/configtemplate/memcache_config.xml b/docs/config/memcache_config.xml similarity index 100% rename from docs/configtemplate/memcache_config.xml rename to docs/config/memcache_config.xml diff --git a/docs/configtemplate/php/compiler_config.php b/docs/config/php/compiler_config.php similarity index 100% rename from docs/configtemplate/php/compiler_config.php rename to docs/config/php/compiler_config.php diff --git a/docs/configtemplate/php/db_config.php b/docs/config/php/db_config.php similarity index 100% rename from docs/configtemplate/php/db_config.php rename to docs/config/php/db_config.php diff --git a/docs/configtemplate/php/dbcache_config.php b/docs/config/php/dbcache_config.php similarity index 100% rename from docs/configtemplate/php/dbcache_config.php rename to docs/config/php/dbcache_config.php diff --git a/docs/configtemplate/php/filecache_config.php b/docs/config/php/filecache_config.php similarity index 100% rename from docs/configtemplate/php/filecache_config.php rename to docs/config/php/filecache_config.php diff --git a/docs/configtemplate/php/memcache.php b/docs/config/php/memcache.php similarity index 100% rename from docs/configtemplate/php/memcache.php rename to docs/config/php/memcache.php diff --git a/docs/configtemplate/php/wind_config.php b/docs/config/php/wind_config.php similarity index 100% rename from docs/configtemplate/php/wind_config.php rename to docs/config/php/wind_config.php diff --git a/docs/configtemplate/properties/db_config.properties b/docs/config/properties/db_config.properties similarity index 100% rename from docs/configtemplate/properties/db_config.properties rename to docs/config/properties/db_config.properties diff --git a/docs/configtemplate/properties/dbcache_config.properties b/docs/config/properties/dbcache_config.properties similarity index 100% rename from docs/configtemplate/properties/dbcache_config.properties rename to docs/config/properties/dbcache_config.properties diff --git a/docs/configtemplate/properties/filecache_config.properties b/docs/config/properties/filecache_config.properties similarity index 100% rename from docs/configtemplate/properties/filecache_config.properties rename to docs/config/properties/filecache_config.properties diff --git a/docs/configtemplate/properties/memcache.properties b/docs/config/properties/memcache.properties similarity index 100% rename from docs/configtemplate/properties/memcache.properties rename to docs/config/properties/memcache.properties diff --git a/docs/configtemplate/properties/viewTemplateConfig.properties b/docs/config/properties/viewTemplateConfig.properties similarity index 100% rename from docs/configtemplate/properties/viewTemplateConfig.properties rename to docs/config/properties/viewTemplateConfig.properties diff --git a/docs/configtemplate/properties/wind_config.properties b/docs/config/properties/wind_config.properties similarity index 100% rename from docs/configtemplate/properties/wind_config.properties rename to docs/config/properties/wind_config.properties diff --git a/docs/config/router_config.xml b/docs/config/router_config.xml new file mode 100644 index 00000000..b79960ba --- /dev/null +++ b/docs/config/router_config.xml @@ -0,0 +1,25 @@ + + + + + + + + m/c-a/* + + htm + + / + + - + + myvar_ + 1 + + + + + + + + \ No newline at end of file diff --git a/docs/configtemplate/view_compiler_config.xml b/docs/config/view_compiler_config.xml similarity index 100% rename from docs/configtemplate/view_compiler_config.xml rename to docs/config/view_compiler_config.xml diff --git a/docs/configtemplate/view_config.xml b/docs/config/view_config.xml similarity index 70% rename from docs/configtemplate/view_config.xml rename to docs/config/view_config.xml index 3d6e8c5a..42ec5395 100644 --- a/docs/configtemplate/view_config.xml +++ b/docs/config/view_config.xml @@ -9,6 +9,4 @@ data.template false - - diff --git a/docs/configtemplate/wind_config.xml b/docs/config/wind_config.xml similarity index 100% rename from docs/configtemplate/wind_config.xml rename to docs/config/wind_config.xml From 1875863ae5fe2ed26a60f1162fe140a04d099a50 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 08:14:40 +0000 Subject: [PATCH 0312/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2381 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 46 ++++++++++++++++++++++++++++++++++++++++ _compile/web_compile.php | 5 +++++ 2 files changed, 51 insertions(+) create mode 100644 _compile/compile.php create mode 100644 _compile/web_compile.php diff --git a/_compile/compile.php b/_compile/compile.php new file mode 100644 index 00000000..e4a9377c --- /dev/null +++ b/_compile/compile.php @@ -0,0 +1,46 @@ + $value) { + $_key = Wind::getRealPath($key); + $fileList[$_key] = array($key, $value); + $content[$value] = parseFilePath($key); +} +$pack->packFromFileList($fileList, _COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); +/* import信息写入编译文件 */ +WindFile::write(WIND_PATH . 'wind_imports.php', + 'parse(_COMPILE_PATH . 'components_config.xml'); +WindFile::write($_systemConfig, ' \ No newline at end of file From d4113e106d57c9988d0fccad8bc50889b6f63180 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 08:23:14 +0000 Subject: [PATCH 0313/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2382 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/_compile/compile.php | 46 --------------- wind/_compile/components_config.xml | 91 ----------------------------- 2 files changed, 137 deletions(-) delete mode 100644 wind/_compile/compile.php delete mode 100644 wind/_compile/components_config.xml diff --git a/wind/_compile/compile.php b/wind/_compile/compile.php deleted file mode 100644 index e4a9377c..00000000 --- a/wind/_compile/compile.php +++ /dev/null @@ -1,46 +0,0 @@ - $value) { - $_key = Wind::getRealPath($key); - $fileList[$_key] = array($key, $value); - $content[$value] = parseFilePath($key); -} -$pack->packFromFileList($fileList, _COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); -/* import信息写入编译文件 */ -WindFile::write(WIND_PATH . 'wind_imports.php', - 'parse(_COMPILE_PATH . 'components_config.xml'); -WindFile::write($_systemConfig, ' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template - htm - 0 - compile.template - 0 - - - - - - - - - - - - - - - - - - - - - - compile - default - - cache - - key - - value - - expire - - - - - compile.cache - php - 10 - - - - From 1aacbd53c12d4059bee32732f88f1bd339614e87 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 08:25:36 +0000 Subject: [PATCH 0314/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2383 18ba2127-5a84-46d4-baec-3457e417f034 From f0557be476b3963a3b489fc33218719b70015d0c Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 08:26:38 +0000 Subject: [PATCH 0315/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2384 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/errorPage/404.htm | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 wind/component/viewer/errorPage/404.htm diff --git a/wind/component/viewer/errorPage/404.htm b/wind/component/viewer/errorPage/404.htm new file mode 100644 index 00000000..b499243e --- /dev/null +++ b/wind/component/viewer/errorPage/404.htm @@ -0,0 +1,10 @@ + + + + +Insert title here + + + + + \ No newline at end of file From 5d3f4aa11b20ab44be7cae3a5b3e0fb0f84bd858 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 18 Aug 2011 08:27:10 +0000 Subject: [PATCH 0316/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2385 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index a1225935..da7cfd4e 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -32,7 +32,6 @@ class Wind { /** * 加载应用 - * * @param string $appName * @param string $config * @throws WindException @@ -58,18 +57,8 @@ public static function run($appName = 'default', $config = '', $rootPath = '') { self::afterRun($appName, $config, $rootPath); } - /** - * 开发环境脚本入口 - */ - public static function runWithCompile($appName = 'default', $config = '') { - require_once (self::getRealPath('WIND:_compile.compile')); - self::run($appName, $config); - - } - /** * 返回当前appName - * * @return string */ public static function getAppName() { @@ -80,7 +69,6 @@ public static function getAppName() { /** * 返回当前的app应用 - * * @param string $appName * @return WindWebApplication */ @@ -392,10 +380,10 @@ private static function _registerAutoloader() { /** * 加载核心层库函数 - * * @return */ private static function _loadBaseLib() { + self::$_classes = array('WindLogger' => 'log/WindLogger', 'WindActionException' => 'core/exception/WindActionException', 'WindException' => 'core/exception/WindException', From 5055172dae9d88b322b05ca76552a6eef0f2431b Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:02:59 +0000 Subject: [PATCH 0317/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2386 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 75 ++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 55 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index da7cfd4e..cfec6d27 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -20,6 +20,7 @@ * @package */ class Wind { + private static $_components = 'WIND:components_config'; private static $_extensions = 'php'; private static $_isAutoLoad = true; private static $_logger = null; @@ -31,30 +32,31 @@ class Wind { private static $_currentApp = array(); /** - * 加载应用 * @param string $appName - * @param string $config - * @throws WindException - * @return + * @param string|array|WindSystemConfig $config + * @param string $rootPath + * @return IWindApplication */ - public static function run($appName = 'default', $config = '', $rootPath = '') { + public static function run($appName = 'default', $config = array(), $rootPath = '') { self::beforRun($appName, $config, $rootPath); if (!isset(self::$_app[$appName])) { Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); - $factory = new WindFactory(@include (self::getRealPath('WIND:components_config'))); - $config = new WindSystemConfig($config, Wind::getAppName(), $factory); - $factory->loadClassDefinitions($config->getComponents()); - $application = $factory->getInstance($config->getAppClass('windWebApp'), - array($config, $factory)); - if ($application === null) { - throw new WindException('[wind.run] ' . $config->getAppClass('windWebApp'), - WindException::ERROR_CLASS_NOT_EXIST); - } + $factory = new WindFactory(@include (Wind::getRealPath(self::$_components))); + if ($config && !is_array($config)) + $config = $factory->getInstance('configParser')->parse($config); + $appClass = @$config['class'] ? $config['class'] : 'windWebApp'; + $application = $factory->getInstance($appClass, array($config, $factory)); + if (!$application instanceof IWindApplication) + throw new WindException('[Wind.application] ' . get_class($application), + WindException::ERROR_CLASS_TYPE_ERROR); + $rootPath = $rootPath ? $rootPath : (@$config['root-path'] ? $config['root-path'] : dirname( + $_SERVER['SCRIPT_FILENAME'])); + Wind::register($rootPath, $appName, true); self::$_app[$appName] = $application; } self::getApp()->run(); - self::afterRun($appName, $config, $rootPath); + self::afterRun(); } /** @@ -321,7 +323,7 @@ protected static function beforRun($appName, $config, $rootPath) { /** * @return */ - protected static function afterRun($appName, $config, $rootPath) { + protected static function afterRun() { array_pop(self::$_currentApp); if (self::$_logger) self::$_logger->flush(); @@ -383,45 +385,8 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - - self::$_classes = array('WindLogger' => 'log/WindLogger', - 'WindActionException' => 'core/exception/WindActionException', - 'WindException' => 'core/exception/WindException', - 'WindFinalException' => 'core/exception/WindFinalException', - 'IWindFactory' => 'core/factory/IWindFactory', - 'WindClassProxy' => 'core/factory/proxy/WindClassProxy', - 'WindFactory' => 'core/factory/WindFactory', - 'IWindApplication' => 'core/IWindApplication', - 'IWindController' => 'core/IWindController', - 'IWindErrorMessage' => 'core/IWindErrorMessage', - 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', - 'WindFormListener' => 'core/web/listener/WindFormListener', - 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', - 'WindValidateListener' => 'core/web/listener/WindValidateListener', - 'WindController' => 'core/web/WindController', - 'WindDispatcher' => 'core/web/WindDispatcher', - 'WindErrorHandler' => 'core/web/WindErrorHandler', - 'WindErrorMessage' => 'core/web/WindErrorMessage', - 'WindForward' => 'core/web/WindForward', 'WindHelper' => 'core/web/WindHelper', - 'WindSimpleController' => 'core/web/WindSimpleController', - 'WindSystemConfig' => 'core/web/WindSystemConfig', - 'WindUrlHelper' => 'core/web/WindUrlHelper', - 'WindWebApplication' => 'core/web/WindWebApplication', - 'WindEnableValidateModule' => 'core/WindEnableValidateModule', - 'WindModule' => 'core/WindModule', 'WindFilter' => 'filter/WindFilter', - 'WindFilterChain' => 'filter/WindFilterChain', - 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', - 'WindConfigParser' => 'parser/WindConfigParser', - 'IWindRequest' => 'http/request/IWindRequest', - 'WindHttpRequest' => 'http/request/WindHttpRequest', - 'IWindResponse' => 'http/response/IWindResponse', - 'WindHttpResponse' => 'http/response/WindHttpResponse', - 'AbstractWindRouter' => 'router/AbstractWindRouter', - 'AbstractWindRoute' => 'router/route/AbstractWindRoute', - 'WindRewriteRoute' => 'router/route/WindRewriteRoute', - 'WindRoute' => 'router/route/WindRoute', 'WindRouter' => 'router/WindRouter', - 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter'); + Wind::import('WIND:core.*', true); + Wind::import('COM:log.WindLogger'); } } Wind::init(); From 5f22b71eea711d7bbee434fb940d12b96b604f7f Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:03:11 +0000 Subject: [PATCH 0318/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2387 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/filter/WindFilterChain.php | 1 - wind/component/filter/WindHandlerInterceptorChain.php | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/filter/WindFilterChain.php b/wind/component/filter/WindFilterChain.php index 989519b1..5deb89ac 100644 --- a/wind/component/filter/WindFilterChain.php +++ b/wind/component/filter/WindFilterChain.php @@ -47,7 +47,6 @@ public function addFilter($filter, $beforFilter = '') { } /** - * Enter description here ... * @param array $filters */ private function _initFilters($filters = array()) { diff --git a/wind/component/filter/WindHandlerInterceptorChain.php b/wind/component/filter/WindHandlerInterceptorChain.php index 71a5f316..b2f7761d 100644 --- a/wind/component/filter/WindHandlerInterceptorChain.php +++ b/wind/component/filter/WindHandlerInterceptorChain.php @@ -1,4 +1,5 @@ * @author Qiong Wu From dfd0c9b4cb9c11b9d0f1aa3f56ceecfb29ee65d1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:03:19 +0000 Subject: [PATCH 0319/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2388 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/http/request/WindHttpRequest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wind/component/http/request/WindHttpRequest.php b/wind/component/http/request/WindHttpRequest.php index c79f5a3a..29608259 100644 --- a/wind/component/http/request/WindHttpRequest.php +++ b/wind/component/http/request/WindHttpRequest.php @@ -1,4 +1,5 @@ * @author Qiong Wu @@ -526,9 +527,11 @@ public function getAcceptLanguage() { /** * @return WindHttpResponse */ - public function getResponse() { + public function getResponse($charset) { $response = new WindHttpResponse(); - $response->setHeader('Content-type', 'text/html;charset=UTF-8'); + !$charset && $charset = 'utf-8'; + $response->setHeader('Content-type', 'text/html;charset=' . $charset); + $response->setCharset($charset); return $response; } From 37ff80b0f608660866abb071e024861ffc96ac82 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:03:26 +0000 Subject: [PATCH 0320/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2389 18ba2127-5a84-46d4-baec-3457e417f034 --- .../http/response/WindHttpResponse.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php index 42a1bf84..a7016946 100644 --- a/wind/component/http/response/WindHttpResponse.php +++ b/wind/component/http/response/WindHttpResponse.php @@ -1,4 +1,5 @@ _headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } + /** + * @return string + */ + public function getCharset() { + return $this->_charset; + } + + /** + * @param string $_charset + */ + public function setCharset($_charset) { + $this->_charset = $_charset; + } + /** * 设置响应头状态码 * From 411656fb2d76d574bf2b8ca4d069346ea962cb57 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:03:36 +0000 Subject: [PATCH 0321/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2390 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/AbstractWindRouter.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/component/router/AbstractWindRouter.php b/wind/component/router/AbstractWindRouter.php index 218b4d4d..d0e171c2 100644 --- a/wind/component/router/AbstractWindRouter.php +++ b/wind/component/router/AbstractWindRouter.php @@ -1,4 +1,5 @@ Date: Fri, 19 Aug 2011 08:03:42 +0000 Subject: [PATCH 0322/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2391 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/route/AbstractWindRoute.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/component/router/route/AbstractWindRoute.php b/wind/component/router/route/AbstractWindRoute.php index 2ee3e8c4..0799c22c 100644 --- a/wind/component/router/route/AbstractWindRoute.php +++ b/wind/component/router/route/AbstractWindRoute.php @@ -1,4 +1,5 @@ * @author Qiong Wu From 7391e6a85e538f252e2d934c009a4630a014b321 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:03:54 +0000 Subject: [PATCH 0323/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2392 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/utility/WindHtmlHelper.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/wind/component/utility/WindHtmlHelper.php b/wind/component/utility/WindHtmlHelper.php index 582c2299..a2850db7 100644 --- a/wind/component/utility/WindHtmlHelper.php +++ b/wind/component/utility/WindHtmlHelper.php @@ -14,7 +14,7 @@ class WindHtmlHelper { * @return string | string The converted string */ public static function encode($text) { - return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getWindSystemConfig()->getCharset()); + return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } /** @@ -25,11 +25,12 @@ public static function encode($text) { */ public static function encodeArray($data) { $_tmp = array(); + $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { - if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, - Wind::getApp()->getWindSystemConfig()->getCharset()); + if (is_string($key)) + $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) - $value = htmlspecialchars($value, ENT_QUOTES, Wind::getApp()->getWindSystemConfig()->getCharset()); + $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; From 20583e83a191cbedb2bff9164e3e639f7adb5aab Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:04:05 +0000 Subject: [PATCH 0324/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2393 18ba2127-5a84-46d4-baec-3457e417f034 --- .../viewer/errorPage/default_error.htm | 1 - wind/core/IWindApplication.php | 12 -- wind/core/WindModule.php | 30 ++--- .../factory/{proxy => }/WindClassProxy.php | 99 ++++++----------- wind/core/factory/WindFactory.php | 104 +++++++++--------- 5 files changed, 93 insertions(+), 153 deletions(-) rename wind/core/factory/{proxy => }/WindClassProxy.php (59%) diff --git a/wind/component/viewer/errorPage/default_error.htm b/wind/component/viewer/errorPage/default_error.htm index 9bbfc757..b5aadeb6 100644 --- a/wind/component/viewer/errorPage/default_error.htm +++ b/wind/component/viewer/errorPage/default_error.htm @@ -11,7 +11,6 @@

{$errorHeader}

$key = $key + 1; #-->{$key}. {$error}
-

Click here go back!

\ No newline at end of file diff --git a/wind/core/IWindApplication.php b/wind/core/IWindApplication.php index 857e3d21..76691622 100644 --- a/wind/core/IWindApplication.php +++ b/wind/core/IWindApplication.php @@ -8,17 +8,10 @@ interface IWindApplication { /** - * Enter description here ... * @return */ public function run(); - /** - * 请求转发 - * @param WindForward $forward - */ - public function doDispatch($forward); - /** * @return WindHttpRequest $request */ @@ -29,11 +22,6 @@ public function getRequest(); */ public function getResponse(); - /** - * @return WindSystemConfig $windSystemConfig - */ - public function getWindSystemConfig(); - /** * @return WindFactory $windFactory */ diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index e12d4668..7c7e567f 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -69,25 +69,24 @@ public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); - if ($_prefix == '_set') { - $this->$_propertyName = $args[0]; - } elseif ($_prefix == '_get') { - if ($this->$_propertyName) - return $this->$_propertyName; - if (isset($this->delayAttributes[$_propertyName])) { - $_value = null; + if ($_prefix == '_get') { + if (@$this->delayAttributes[$_propertyName] !== null) { $_property = $this->delayAttributes[$_propertyName]; - if (isset($_property['value'])) { + $_value = null; + if (@$_property['value'] !== null) { $_value = $_property['value']; - } elseif (isset($_property['ref'])) { + } elseif (@$_property['ref'] !== null) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); - } elseif (isset($_property['path'])) { + } elseif (@$_property['path'] !== null) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; + unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; + } elseif ($_prefix == '_set') { + $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', @@ -198,8 +197,8 @@ public function setConfig($config) { if (!$config) return; if (is_string($config)) { - $configParser = $this->getSystemFactory()->getInstance(COMPONENT_CONFIGPARSER); - $config = $configParser->parse($config, get_class($this), 'cache_wind_config'); + $configParser = $this->getSystemFactory()->getInstance('configParser'); + $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); @@ -227,13 +226,6 @@ protected function writeTableCloneProperty() { return array(); } - /** - * @return WindSystemConfig - */ - protected function getSystemConfig() { - return Wind::getApp()->getWindSystemConfig(); - } - /** * @return WindFactory */ diff --git a/wind/core/factory/proxy/WindClassProxy.php b/wind/core/factory/WindClassProxy.php similarity index 59% rename from wind/core/factory/proxy/WindClassProxy.php rename to wind/core/factory/WindClassProxy.php index 97a2c653..7c255c14 100644 --- a/wind/core/factory/proxy/WindClassProxy.php +++ b/wind/core/factory/WindClassProxy.php @@ -23,49 +23,41 @@ class WindClassProxy { protected $_listener = array(); /** - * @param string|object $targetObj + * @param object $targetObj */ - public function __construct($targetObject = null, $args = array()) { - try { - if (is_object($targetObject)) { - $this->_setClassName(get_class($targetObject)); - $this->_instance = $targetObject; - } elseif (is_string($targetObject) && !empty($targetObject)) { - $this->_setClassPath($targetObject); - $reflection = new ReflectionClass($this->_className); - if ($reflection->isAbstract() || $reflection->isInterface()) { - throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); - } - $this->_reflection = $reflection; - $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); - } else - throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); - - $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); - foreach ($types as $type) { - $this->_listener[$type] = array(); - } - - if ($this->_instance !== null) return; - - } catch (Exception $e) { - Wind::log('[core.factory.proxy.WindClassProxy.initClassProxy] Initialization proxy failed.' . $e->getMessage(), WindLogger::LEVEL_DEBUG, 'wind.core'); - } - - //$this->initClassProxy($targetObj, $args); + public function __construct($targetObject = null) { + $targetObject && $this->registerTargetObject($targetObject); } /* (non-PHPdoc) * @see IWindClassProxy::registerAspect() */ public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { - if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { - throw new WindException('[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); + if (!in_array($type, + array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { + throw new WindException( + '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, + WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } + /** + * 注册目标对象,如果已经注册了不重复注册 + * @param object $targetObject + */ + public function registerTargetObject($targetObject) { + if ($this->_instance !== null || !is_object($targetObject)) + return; + $this->_setClassName(get_class($targetObject)); + $this->_instance = $targetObject; + $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); + foreach ($types as $type) + $this->_listener[$type] = array(); + return $this; + } + /** * @param string $propertyName * @param $value @@ -78,7 +70,8 @@ public function __set($propertyName, $value) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); - if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); + if (empty($listeners)) + return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); @@ -95,7 +88,8 @@ public function __get($propertyName) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); - if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); + if (empty($listeners)) + return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); @@ -109,46 +103,14 @@ public function __get($propertyName) { */ public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); - if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); + if (empty($listeners)) + return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } - /** - * 初始化类代理对象 - * - * @param string|object $targetObject - * @param array $args - * @throws WindException - */ - protected function initClassProxy($targetObject, $args = array()) { - try { - if (is_object($targetObject)) { - $this->_setClassName(get_class($targetObject)); - $this->_instance = $targetObject; - } elseif (is_string($targetObject) && !empty($targetObject)) { - $this->_setClassPath($targetObject); - $reflection = new ReflectionClass($this->_className); - if ($reflection->isAbstract() || $reflection->isInterface()) { - throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); - } - $this->_reflection = $reflection; - $this->_instance = call_user_func_array(array($this->_reflection, 'newInstance'), $args); - } else - throw new WindException($this->_className, WindException::ERROR_CLASS_NOT_EXIST); - - $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); - foreach ($types as $type) { - $this->_listener[$type] = array(); - } - - } catch (Exception $e) { - Wind::log('[core.factory.proxy.WindClassProxy.initClassProxy] Initialization proxy failed.' . $e->getMessage(), WindLogger::LEVEL_DEBUG, 'wind.core'); - } - } - /** * @param string $event * @return @@ -160,7 +122,8 @@ private function _getInterceptorChain($event = '') { if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else - throw new WindException('[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); + throw new WindException( + '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index d8cc7d5a..0d2d5115 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -12,7 +12,7 @@ * @package */ class WindFactory implements IWindFactory { - protected $proxyType = 'WIND:core.factory.proxy.WindClassProxy'; + protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); @@ -39,29 +39,41 @@ public function getInstance($alias, $args = array()) { return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; - $this->buildDefinition($definition); - $_constructorArgs = $definition['constructorArgs']; - foreach ($_constructorArgs as $_var) { - if (isset($_var['value'])) { + + if (@$definition['className'] === null) + $definition['className'] = Wind::import(@$definition['path']); + foreach ((array) @$definition['constructorArgs'] as $_var) { + if (@$_var['value'] !== null) { $args[] = $_var['value']; - } elseif (isset($_var['ref'])) + } elseif (@$_var['ref'] !== null) $args[] = $this->getInstance($_var['ref']); } - $config = $this->buildConfig($definition, $alias); $instance = $this->createInstance($definition['className'], $args); - if (!empty($config)) - $instance->setConfig($config); - if ($definition['properties']) + if (@$definition['config']) + $this->resolveConfig($definition['config'], $alias, $instance); + if (@$definition['properties']) $this->buildProperties($definition['properties'], $instance); - if ($definition['initMethod']) + if (@$definition['initMethod']) $this->executeInitMethod($definition['initMethod'], $instance); - if ($definition['proxy']) + if (@$definition['proxy']) $instance = $this->setProxyForClass($definition['proxy'], $instance); - $this->setScope($alias, $definition['scope'], $instance); return $instance; } + /** + * 对象组件对象到应用工厂中 + * @param object $instance + * @param string $alias + * @param string $scope + * @return boolean + */ + public function registInstance($instance, $alias, $scope = 'singleton') { + if (!is_object($instance) || !$alias) + return false; + return $this->setScope($alias, $scope, $instance); + } + /* (non-PHPdoc) * @see AbstractWindFactory::createInstance() */ @@ -71,9 +83,9 @@ static public function createInstance($className, $args = array()) { Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); } - if (empty($args)) + if (empty($args)){ return new $className(); - else { + }else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } @@ -116,6 +128,8 @@ public function addClassDefinitions($alias, $classDefinition) { */ public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { + if (!is_array($definition)) + continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; @@ -158,6 +172,7 @@ protected function setScope($alias, $scope, $instance) { break; } + return true; } /** @@ -165,22 +180,18 @@ protected function setScope($alias, $scope, $instance) { * * @param array|string $config * @param string $alias + * @param WindModule $instance * @return */ - protected function buildConfig(&$definition, $alias) { - if (!($config = $definition['config'])) - return array(); - if (isset($config['resource']) && !empty($config['resource'])) { + protected function resolveConfig($config, $alias, $instance) { + if (@$config['resource']) { $_configPath = Wind::getRealPath($config['resource'], true); - $configParser = $this->getInstance(COMPONENT_CONFIGPARSER); - $cache = $alias !== COMPONENT_CACHE ? $this->getInstance(COMPONENT_CACHE) : null; - $config = $configParser->parse($_configPath, $alias, 'components_config_cache', $cache); + $configParser = $this->getInstance('configParser'); + $config = $configParser->parse($_configPath, $alias, true, + $this->getInstance('windCache')); } - if (isset($config['class']) && !$definition['path']) { - $definition['path'] = $config['class']; - $definition['className'] = Wind::import($definition['path']); - } - return $config; + if ($config && method_exists($instance, 'setConfig')) + $instance->setConfig($config); } /** @@ -210,8 +221,11 @@ protected function executeInitMethod($initMethod, $instance) { protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; - $proxy = Wind::import($this->proxyType); - return $this->createInstance($proxy, array($instance)); + + if ($proxy === 'true' || $proxy === true) + $proxy = $this->proxyType; + $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); + return $this->getInstance($proxy)->registerTargetObject($instance); } /** @@ -221,38 +235,22 @@ protected function setProxyForClass($proxy, $instance) { * @param WindModule $instance */ protected function buildProperties($properties, $instance) { - if (isset($properties['delay']) && ($properties['delay'] === 'false' || $properties['delay'] === false)) { + if (@$properties['delay'] === 'false' || @$properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; - if (isset($subDefinition['value'])) + if (@$subDefinition['value'] !== null) $_value = $subDefinition['value']; - elseif (isset($subDefinition['ref'])) + elseif (@$subDefinition['ref'] !== null) $_value = $this->getInstance($subDefinition['ref']); - elseif (isset($subDefinition['path'])) { + elseif (@$subDefinition['path'] != null) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } - if ($_value) { - $_setter = 'set' . ucfirst(trim($key, '_')); + $_setter = 'set' . ucfirst(trim($key, '_')); + if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); - } } - } - $instance->setDelayAttributes($properties); - } - - /** - * 验证类定义的正确性 - * - * @param array definition - * @return boolean - */ - private function buildDefinition(&$definition) { - $_definition = array('path' => '', 'className' => '', 'factoryMethod' => '', - 'initMethod' => '', 'scope' => 'application', 'proxy' => false, 'properties' => array(), - 'config' => array(), 'constructorArgs' => array()); - $definition = array_merge($_definition, $definition); - $definition['className'] = Wind::import($definition['path']); + } else + $instance->setDelayAttributes($properties); } - } \ No newline at end of file From 2ba0094490ca628b75034553ef5e348f59334cf5 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:04:15 +0000 Subject: [PATCH 0325/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2394 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindController.php | 1 + wind/core/web/WindSimpleController.php | 29 +++ wind/core/web/WindSystemConfig.php | 243 ------------------------- wind/core/web/WindWebApplication.php | 133 +++++++++----- 4 files changed, 121 insertions(+), 285 deletions(-) delete mode 100644 wind/core/web/WindSystemConfig.php diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php index c56de63c..5e8d9c34 100644 --- a/wind/core/web/WindController.php +++ b/wind/core/web/WindController.php @@ -39,6 +39,7 @@ final public function preAction($handlerAdapter) { $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } + return true; } /* (non-PHPdoc) diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index b41dace6..ca9d43cb 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -279,4 +279,33 @@ protected function getErrorMessage() { } } +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindController { + + /** + * 处理请求并返回Forward对象 + * @param WindUrlBasedRouter $handlerAdapter + * @return WindForward + */ + public function doAction($handlerAdapter); + + /** + * Action预处理方法 + * @param WindUrlBasedRouter $handlerAdapter + * @return + */ + public function preAction($handlerAdapter); + + /** + * Action后处理方法 + * @param WindUrlBasedRouter $handlerAdapter + * @return + */ + public function postAction($handlerAdapter); +} ?> \ No newline at end of file diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php deleted file mode 100644 index 54b8f800..00000000 --- a/wind/core/web/WindSystemConfig.php +++ /dev/null @@ -1,243 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindSystemConfig extends WindModule { - private $appName = ''; - private $modules = array(); - - /** - * @param string $config - * @param string $appName - * @param WindFactory $factory - */ - public function __construct($config, $appName, $factory) { - $this->appName = $appName; - $this->setConfig($config, $factory); - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config, $factory = null) { - if (empty($config)) - return; - if (is_string($config)) { - $configParser = $factory->getInstance('configParser'); - $config = $configParser->parse($config); - if (isset($config[$this->appName])) - $this->_config = $config[$this->appName]; - } else - $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; - } - - /** - * @return the $appName - */ - public function getAppName() { - return $this->appName; - } - - /** - * 返回当前应用的启动脚本位置 - */ - public function getAppClass($default = '') { - return $this->getConfig('class', '', $default); - } - - /** - * 返回应用编码信息 - */ - public function getCharset() { - return $this->getConfig('charset', '', 'utf-8'); - } - - /** - * 返回配置定义中定义的过滤链列表 - * 如果定义$name则返回在filters定义标签内对应的属性值 - * - * @param string $name - * @return array|string - */ - public function getFilters() { - return $this->getConfig('filters'); - } - - /** - * 返回filterChain的类型 - * - * @return array - */ - public function getFilterClass() { - return $this->getConfig('filters', 'class'); - } - - /** - * @param string $name - * @return array|string - */ - public function getRouter() { - return $this->getConfig('router'); - } - - /** - * 返回路由类型定义 - * @return string - */ - public function getRouterClass() { - return $this->getConfig('router', 'class', COMPONENT_ROUTER); - } - - /** - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * @param string $name - * @return array|string - */ - public function getModules($name = '') { - return $this->getConfig('modules', $name, array()); - } - - /** - * 添加module - * controller - * - * Controller - * - * WIND:core.web.WindErrorHandler - * - * - * - * template - * - * htm - * - * @param string $name - * @param array $config - * @return - */ - public function setModules($name, $config = array()) { - if (!$_default = @$this->_config['modules']['default']) { - $_default = $this->getDefaultConfigStruct('modules'); - $this->_config['modules']['default'] = $_default; - } - if (!$config) - $this->_config['modules'][$name] = $_default; - else - $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); - return $this->_config['modules'][$name]; - } - - /** - * 返回module模板定义 - * @param unknown_type $name - * @param unknown_type $default - */ - public function getModuleTemplateDir($name, $default = '') { - return $this->getConfig('template-dir', '', $default, $this->getModules($name)); - } - - /** - * 根据module名称返回错误的处理句柄 - * @param string $name - * @param string $default - * @return string - */ - public function getModuleErrorHandler($name, $default = '') { - return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); - } - - /** - * 返回指定moduleName的controller路径信息 - * @param string $name - * @return string - */ - public function getModuleControllerPath($name, $default = '') { - return $this->getConfig('controller-path', '', $default, $this->getModules($name)); - } - - /** - * 返回指定moduleName的controller后缀 - * @param string $name - * @return string - */ - public function getModuleControllerSuffix($name, $default = '') { - return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); - } - - /** - * 返回指定ComponentName的Component配置信息 - * @param string $name - * @return string - */ - public function getComponents($name = '', $default = array()) { - return $this->getConfig('components', $name, $default); - } - - /** - * 获得DB配置,根据DB名义的别名来获取DB链接配置信息. - * 当别名为空时,返回全部DB链接配置. - * - * @param string $dbName - */ - public function getDbConfig($dbName = '') { - $config = $this->getConfig('db'); - if (isset($config['resource']) && !empty($config['resource'])) { - $_resource = Wind::getRealPath($config['resource'], true); - $this->_config['db'] = $this->parseConfig($_resource, 'db'); - } - return $this->getConfig('db', $dbName); - } - - /** - * 配置解析方法 - * @param string $config - * @param string $key - * @param string|boolean $append - * @param factory - */ - private function parseConfig($config, $key = 'config', $append = true) { - if (!$config) - return array(); - $configParser = $this->getSystemConfig()->getInstance('configParser'); - return $configParser->parse($config); - } - - /** - * 返回对应的配置结构及默认值 - * @param string $configName - * @throws WindException - * @return string - */ - public function getDefaultConfigStruct($configName) { - $_tmp = array(); - $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); - $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', - 'Controller'); - $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', - 'WIND:core.web.WindErrorHandler'); - return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); - } -} \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 2ecfd027..bfac67cd 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -1,4 +1,6 @@ * @author Qiong Wu @@ -14,10 +16,6 @@ class WindWebApplication extends WindModule implements IWindApplication { * @var WindHttpResponse */ private $response; - /** - * @var WindSystemConfig - */ - protected $windSystemConfig = null; /** * @var WindFactory */ @@ -30,14 +28,20 @@ class WindWebApplication extends WindModule implements IWindApplication { * @var WindRouter */ protected $handlerAdapter = null; + protected $filterChain = 'COM:filter.WindFilterChain'; /** - * @param WindSystemConfig $config + * 应用初始化操作 + * + * @param array|string $config * @param WindFactory $factory + * @param string $runCallBack */ public function __construct($config, $factory) { - $this->windSystemConfig = $config; + $this->request = new WindHttpRequest(); + $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; + $this->setConfig($config); } /* (non-PHPdoc) @@ -46,12 +50,11 @@ public function __construct($config, $factory) { public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); - $this->request = new WindHttpRequest(); - $this->response = $this->request->getResponse(); + $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); - if (null == ($filterChain = $this->getFilterChain())) + if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); - else { + } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } @@ -67,7 +70,7 @@ public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); - if (!($module = $this->windSystemConfig->getModules($moduleName))) + if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); @@ -90,13 +93,13 @@ public function processRequest() { if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); - $module = $this->windSystemConfig->setModules($moduleName); + $module = $this->setModules($moduleName); } else { - if (!($module = $this->windSystemConfig->getModules($moduleName))) + if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); - $module = $this->windSystemConfig->setModules($moduleName, $module); + $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; @@ -106,25 +109,20 @@ public function processRequest() { '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); - if (strpos($handlerPath, ':') === false) - $handlerPath = Wind::getAppName() . ':' . $handlerPath; - if (!$this->getSystemFactory()->checkAlias($handlerPath)) { - $this->getSystemFactory()->addClassDefinitions($handlerPath, - array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, - 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), - 'forward' => array('ref' => 'forward'), - 'urlHelper' => array('ref' => 'urlHelper')))); - } + strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; + $this->getSystemFactory()->addClassDefinitions($handlerPath, + array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, + 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), + 'forward' => array('ref' => 'forward'), + 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); - if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); - call_user_func_array(array($handler, 'preAction'), array($this->handlerAdapter)); - $forward = call_user_func_array(array($handler, 'doAction'), - array($this->handlerAdapter)); - call_user_func_array(array($handler, 'postAction'), array($this->handlerAdapter)); + $handler->preAction($this->handlerAdapter); + $forward = $handler->doAction($this->handlerAdapter); + $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); @@ -140,7 +138,7 @@ public function processRequest() { */ protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); - if ($moduleName === 'error' || !($module = $this->windSystemConfig->getModules($moduleName))) + if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException( '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); @@ -154,7 +152,7 @@ protected function sendErrorMessage($exception) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; - $this->windSystemConfig->setModules('error', + $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } @@ -169,18 +167,76 @@ protected function sendErrorMessage($exception) { * @return WindFilterChain */ protected function getFilterChain() { - if (!($filters = $this->getWindSystemConfig()->getFilters())) + if (!$filters = $this->getConfig('filters')) return null; - if (!($filterChainPath = $this->getWindSystemConfig()->getFilterClass())) + $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; + unset($filters['class']); + if (empty($filters)) return null; - return $this->getWindFactory()->createInstance($filterChainPath, array($filters)); + $this->windFactory->addClassDefinitions($filterChainPath, + array('path' => $filterChainPath, 'scope' => 'singleton')); + return $this->windFactory->getInstance($filterChainPath, array($filters)); + } + + /** + * 添加module + * controller + * + * Controller + * + * WIND:core.web.WindErrorHandler + * + * + * + * template + * + * htm + * + * @param string $name + * @param array $config + * @return array + */ + public function setModules($name, $config = array()) { + if (!$_default = @$this->_config['modules']['default']) { + $_default = array('controller-path' => 'controller', + 'controller-suffix' => 'Controller', + 'error-handler' => 'WIND:core.web.WindErrorHandler'); + $this->_config['modules']['default'] = $_default; + } + if (!$config) + $this->_config['modules'][$name] = $_default; + else + $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); + return $this->_config['modules'][$name]; + } + + /** + * @param string $name + * @throws WindActionException + * @throws WindException + * @return array + */ + public function getModules($name = '') { + return $this->getConfig('modules', $name, array()); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + if (!$config) + return; + $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; + $this->_config = $config; } /** - * @param string $componentName * @param object $componentInstance + * @param string $componentName */ - public function registeComponent($componentName, $componentInstance) {} + public function registeComponent($componentName, $componentInstance, $scope) { + return $this->windFactory->registInstance($componentInstance, $componentName); + } /** * @param string $componentName @@ -203,13 +259,6 @@ public function getResponse() { return $this->response; } - /** - * @return WindSystemConfig $windSystemConfig - */ - public function getWindSystemConfig() { - return $this->windSystemConfig; - } - /** * @return WindFactory $windFactory */ From 6dcdb7eff9dc9a3c43c673eab85a34e934c15265 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 19 Aug 2011 08:30:53 +0000 Subject: [PATCH 0326/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2395 18ba2127-5a84-46d4-baec-3457e417f034 --- .../viewer/errorPage/default_error.htm | 43 ++++++++++++++++--- wind/core/web/WindErrorHandler.php | 2 +- wind/core/web/WindHelper.php | 8 +++- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/wind/component/viewer/errorPage/default_error.htm b/wind/component/viewer/errorPage/default_error.htm index b5aadeb6..97e2593f 100644 --- a/wind/component/viewer/errorPage/default_error.htm +++ b/wind/component/viewer/errorPage/default_error.htm @@ -3,14 +3,43 @@ {@G:title} -{@G:head} + -

{$errorHeader}

-

{$key}. {$error}
- -

+
+ + + + +
+

{$errorHeader}:

+

+ {$key}. {$error}
+

+

You Can Get Help In:

+

{@WindHelper::errorInfo()}

+
+
\ No newline at end of file diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php index d4b7e3f7..0706df7a 100644 --- a/wind/core/web/WindErrorHandler.php +++ b/wind/core/web/WindErrorHandler.php @@ -31,7 +31,7 @@ public function run() { $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else - $topic = "Error message:"; + $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); diff --git a/wind/core/web/WindHelper.php b/wind/core/web/WindHelper.php index 0aef953e..41395aac 100644 --- a/wind/core/web/WindHelper.php +++ b/wind/core/web/WindHelper.php @@ -47,6 +47,12 @@ public static function exceptionHandle($exception) { exit(); } + public static function errorInfo() { + $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; + $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; + return $info; + } + /** * @param string $message * @param string $file @@ -101,7 +107,7 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { $errfile = "$file"; $msg = "$errfile\n$errsample\n$errtrace\n"; } - $msg .= "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; + $msg .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; From 4b7333625f65af80dc3d665bd2ac19040e32f77d Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 03:43:08 +0000 Subject: [PATCH 0327/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2397 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 93 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 wind/components_config.php diff --git a/wind/components_config.php b/wind/components_config.php new file mode 100644 index 00000000..a49b89cc --- /dev/null +++ b/wind/components_config.php @@ -0,0 +1,93 @@ + array( + 'path' => 'WIND:core.web.WindWebApplication', + 'scope' => 'singleton', + 'properties' => array( + 'dispatcher' => array( + 'ref' => 'dispatcher', + ), + 'handlerAdapter' => array( + 'ref' => 'router', + ), + ), + ), + 'dispatcher' => array( + 'path' => 'WIND:core.web.WindDispatcher', + 'scope' => 'prototype', + 'properties' => array( + 'urlHelper' => array( + 'ref' => 'urlHelper', + ), + ), + ), + 'forward' => array( + 'path' => 'WIND:core.web.WindForward', + 'scope' => 'prototype', + ), + 'router' => array( + 'path' => 'COM:router.WindRouter', + 'scope' => 'prototype', + ), + 'urlRewriteRouter' => array( + 'path' => 'COM:router.WindUrlRewriteRouter', + 'scope' => 'singleton', + ), + 'urlHelper' => array( + 'path' => 'WIND:core.web.WindUrlHelper', + 'scope' => 'singleton', + ), + 'windView' => array( + 'path' => 'COM:viewer.WindView', + 'scope' => 'prototype', + 'config' => array( + 'template-dir' => 'template', + 'template-ext' => 'htm', + 'is-compile' => '', + 'compile-dir' => 'compile.template', + 'is-cache' => '', + ), + 'properties' => array( + 'viewResolver' => array( + 'ref' => 'viewResolver', + ), + 'viewCache' => array( + 'ref' => 'viewCache', + ), + ), + ), + 'viewResolver' => array( + 'path' => 'COM:viewer.WindViewerResolver', + 'scope' => 'prototype', + ), + 'template' => array( + 'path' => 'COM:viewer.compiler.WindViewTemplate', + 'scope' => 'prototype', + ), + 'errorMessage' => array( + 'path' => 'WIND:core.web.WindErrorMessage', + 'scope' => 'prototype', + ), + 'configParser' => array( + 'path' => 'COM:parser.WindConfigParser', + 'scope' => 'singleton', + ), + 'windCache' => array( + 'path' => 'COM:cache.strategy.WindFileCache', + 'config' => array( + 'dir' => 'compile', + 'dbconfig-name' => 'default', + 'table-name' => 'cache', + 'field-key' => 'key', + 'field-value' => 'value', + 'field-expire' => 'expire', + ), + ), + 'viewCache' => array( + 'path' => 'COM:cache.strategy.WindFileCache', + 'config' => array( + 'dir' => 'compile.cache', + 'suffix' => 'php', + 'expires' => '10', + ), + ), +); \ No newline at end of file From d8764d02244ade7e4e33026deeb4982fc3968b8d Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:18:31 +0000 Subject: [PATCH 0328/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2398 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 29 +++++---- _compile/components_config.php | 93 +++++++++++++++++++++++++++ _compile/config/components_config.xml | 91 ++++++++++++++++++++++++++ _compile/web_compile.php | 5 -- _compile/wind_basic.php | 1 + 5 files changed, 202 insertions(+), 17 deletions(-) create mode 100644 _compile/components_config.php create mode 100644 _compile/config/components_config.xml delete mode 100644 _compile/web_compile.php create mode 100644 _compile/wind_basic.php diff --git a/_compile/compile.php b/_compile/compile.php index e4a9377c..26217128 100644 --- a/_compile/compile.php +++ b/_compile/compile.php @@ -3,22 +3,19 @@ * 动态编译脚本,开发环境执行此文件,动态生成过程文件 * @author wuq **/ -define('_COMPILE_PATH', WIND_PATH . '_compile' . D_S); -define('_COMPILE_LIBRARY_PATH', WIND_PATH . 'wind_basic.php'); +error_reporting(E_ALL); +include '../wind/Wind.php'; +define('_COMPILE_PATH', dirname(__FILE__) . '/'); Wind::clear(); Wind::import('COM:log.WindLogger'); Wind::import('WIND:core.*', true); -Wind::import('COM:filter.*', true); -Wind::import('COM:parser.WindConfigParser', true); -Wind::import('COM:http.request.*', true); -Wind::import('COM:http.response.*', true); -Wind::import('COM:router.*', true); $imports = Wind::getImports(); /* 载入需要的文件信息 */ Wind::import('COM:utility.WindPack'); Wind::import('COM:utility.WindFile'); Wind::import('COM:utility.WindString'); +Wind::import('COM:parser.WindConfigParser'); /* 打包 */ $pack = new WindPack(); $fileList = array(); @@ -28,16 +25,24 @@ $fileList[$_key] = array($key, $value); $content[$value] = parseFilePath($key); } -$pack->packFromFileList($fileList, _COMPILE_LIBRARY_PATH, WindPack::STRIP_PHP, true); +$pack->packFromFileList($fileList, _COMPILE_PATH . 'wind_basic.php', WindPack::STRIP_PHP, true); /* import信息写入编译文件 */ -WindFile::write(WIND_PATH . 'wind_imports.php', +WindFile::write(_COMPILE_PATH . 'wind_imports.php', 'parse(_COMPILE_PATH . 'components_config.xml'); -WindFile::write($_systemConfig, 'parse(_COMPILE_PATH . 'config/' . $file); + $file = preg_replace('/\.(\w)*$/i', '', $file); + WindFile::write(_COMPILE_PATH . $file . '.php', + ' array( + 'path' => 'WIND:core.web.WindWebApplication', + 'scope' => 'singleton', + 'properties' => array( + 'dispatcher' => array( + 'ref' => 'dispatcher', + ), + 'handlerAdapter' => array( + 'ref' => 'router', + ), + ), + ), + 'dispatcher' => array( + 'path' => 'WIND:core.web.WindDispatcher', + 'scope' => 'prototype', + 'properties' => array( + 'urlHelper' => array( + 'ref' => 'urlHelper', + ), + ), + ), + 'forward' => array( + 'path' => 'WIND:core.web.WindForward', + 'scope' => 'prototype', + ), + 'router' => array( + 'path' => 'COM:router.WindRouter', + 'scope' => 'prototype', + ), + 'urlRewriteRouter' => array( + 'path' => 'COM:router.WindUrlRewriteRouter', + 'scope' => 'singleton', + ), + 'urlHelper' => array( + 'path' => 'WIND:core.web.WindUrlHelper', + 'scope' => 'singleton', + ), + 'windView' => array( + 'path' => 'COM:viewer.WindView', + 'scope' => 'prototype', + 'config' => array( + 'template-dir' => 'template', + 'template-ext' => 'htm', + 'is-compile' => '', + 'compile-dir' => 'compile.template', + 'is-cache' => '', + ), + 'properties' => array( + 'viewResolver' => array( + 'ref' => 'viewResolver', + ), + 'viewCache' => array( + 'ref' => 'viewCache', + ), + ), + ), + 'viewResolver' => array( + 'path' => 'COM:viewer.WindViewerResolver', + 'scope' => 'prototype', + ), + 'template' => array( + 'path' => 'COM:viewer.compiler.WindViewTemplate', + 'scope' => 'prototype', + ), + 'errorMessage' => array( + 'path' => 'WIND:core.web.WindErrorMessage', + 'scope' => 'prototype', + ), + 'configParser' => array( + 'path' => 'COM:parser.WindConfigParser', + 'scope' => 'singleton', + ), + 'windCache' => array( + 'path' => 'COM:cache.strategy.WindFileCache', + 'config' => array( + 'dir' => 'compile', + 'dbconfig-name' => 'default', + 'table-name' => 'cache', + 'field-key' => 'key', + 'field-value' => 'value', + 'field-expire' => 'expire', + ), + ), + 'viewCache' => array( + 'path' => 'COM:cache.strategy.WindFileCache', + 'config' => array( + 'dir' => 'compile.cache', + 'suffix' => 'php', + 'expires' => '10', + ), + ), +); \ No newline at end of file diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml new file mode 100644 index 00000000..97486198 --- /dev/null +++ b/_compile/config/components_config.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + template + htm + 0 + compile.template + 0 + + + + + + + + + + + + + + + + + + + + + + compile + default + + cache + + key + + value + + expire + + + + + compile.cache + php + 10 + + + + diff --git a/_compile/web_compile.php b/_compile/web_compile.php deleted file mode 100644 index ba2e1f69..00000000 --- a/_compile/web_compile.php +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php new file mode 100644 index 00000000..e7747f46 --- /dev/null +++ b/_compile/wind_basic.php @@ -0,0 +1 @@ +$_setter($value); else Wind::log( '[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); else Wind::log( '[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (@$this->delayAttributes[$_propertyName] !== null) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (@$_property['value'] !== null) { $_value = $_property['value']; } elseif (@$_property['ref'] !== null) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (@$_property['path'] !== null) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) { Wind::log( "[core.WindModule.__clone] unexcepted value type or the property is not setted.(" . $value . ") need an object type in here. ", WindLogger::LEVEL_DEBUG, 'wind.core'); continue; } $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { Wind::log( '[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } if (!($_writeTableProperties = $this->writeTableForProperty())) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { if ($value instanceof $_writeTableProperties[$propertyName]) return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. ", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } return true; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); public function __construct($logDir = '', $writeType = 0) { $this->_logDir = $logDir; $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_INFO, $type); } public function trace($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_TRACE, $type); } public function debug($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_DEBUG, $type); } public function error($msg, $type = 'wind.core') { $this->log($msg, self::LEVEL_ERROR, $type); } public function profileBegin($msg, $type = 'wind.core') { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type); } public function profileEnd($msg, $type = 'wind.core') { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { $this->_types[] = $type; } } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { switch ($key) { case self::LEVEL_INFO: $key = 'info'; break; case self::LEVEL_ERROR: $key = 'error'; break; case self::LEVEL_DEBUG: $key = 'debug'; break; case self::LEVEL_TRACE: $key = 'trace'; break; case self::LEVEL_PROFILE: $key = 'profile'; break; default: $key = 'all'; break; } if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . " timer: " . sprintf('%0.5f', ($timer - DEBUG_TIME)) . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; if (@$definition['className'] === null) $definition['className'] = Wind::import(@$definition['path']); foreach ((array) @$definition['constructorArgs'] as $_var) { if (@$_var['value'] !== null) { $args[] = $_var['value']; } elseif (@$_var['ref'] !== null) $args[] = $this->getInstance($_var['ref']); } $instance = $this->createInstance($definition['className'], $args); if (@$definition['config']) $this->resolveConfig($definition['config'], $alias, $instance); if (@$definition['properties']) $this->buildProperties($definition['properties'], $instance); if (@$definition['initMethod']) $this->executeInitMethod($definition['initMethod'], $instance); if (@$definition['proxy']) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); } if (empty($args)){ return new $className(); }else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (!is_string($alias) || empty($alias)) { throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (@$config['resource']) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (@$properties['delay'] === 'false' || @$properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (@$subDefinition['value'] !== null) $_value = $subDefinition['value']; elseif (@$subDefinition['ref'] !== null) $_value = $this->getInstance($subDefinition['ref']); elseif (@$subDefinition['path'] != null) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException( '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $errsample = ''; if ($_errhtml && is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $errsample = implode("\n", $fileLines) . "\n"; } } if ($_errhtml) $errfile = "$file"; else $errfile = "$file"; $msg = "$errfile\n$errsample\n$errtrace\n"; } $msg .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; if ($_errhtml) { $msg = "$topic

$topic

$errmessage\n$msg
"; } else $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . '('; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } ?> \ No newline at end of file From 9ff944e754ec6611bf9e990b6da076b571ece509 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:21:05 +0000 Subject: [PATCH 0329/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2399 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/filter/WindFilter.php | 24 --------- .../filter/WindHandlerInterceptor.php | 50 ------------------- 2 files changed, 74 deletions(-) delete mode 100644 wind/component/filter/WindFilter.php delete mode 100644 wind/component/filter/WindHandlerInterceptor.php diff --git a/wind/component/filter/WindFilter.php b/wind/component/filter/WindFilter.php deleted file mode 100644 index d2b15fae..00000000 --- a/wind/component/filter/WindFilter.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @author xiaoxia xu - * @version $Id$ - * @package - */ -class WindFilter extends WindHandlerInterceptor { - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - - } - -} \ No newline at end of file diff --git a/wind/component/filter/WindHandlerInterceptor.php b/wind/component/filter/WindHandlerInterceptor.php deleted file mode 100644 index c6ca0890..00000000 --- a/wind/component/filter/WindHandlerInterceptor.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHandlerInterceptor extends WindModule { - protected $result = null; - protected $interceptorChain = null; - - /** - * Enter description here ... - */ - public function preHandle() {} - - /** - * Enter description here ... - */ - public function postHandle() {} - - /** - * Enter description here ... - * @return mixed - */ - public function handle() { - $args = func_get_args(); - $this->result = call_user_func_array(array($this, 'preHandle'), $args); - if ($this->result !== null) { - return $this->result; - } - if (null !== ($handler = $this->interceptorChain->getHandler())) { - $this->result = call_user_func_array(array($handler, 'handle'), $args); - } else { - $this->result = $this->interceptorChain->execute(); - } - call_user_func_array(array($this, 'postHandle'), $args); - return $this->result; - } - - /** - * 设置过滤链对象 - * - * @param WindHandlerInterceptorChain $interceptorChain - */ - public function setHandlerInterceptorChain($interceptorChain) { - $this->interceptorChain = $interceptorChain; - } -} -?> \ No newline at end of file From 8179a3f0d2dda7f3521c8a50601be28253177748 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:21:46 +0000 Subject: [PATCH 0330/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2400 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.xml | 91 -------------------------------------- 1 file changed, 91 deletions(-) delete mode 100644 wind/components_config.xml diff --git a/wind/components_config.xml b/wind/components_config.xml deleted file mode 100644 index 97486198..00000000 --- a/wind/components_config.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template - htm - 0 - compile.template - 0 - - - - - - - - - - - - - - - - - - - - - - compile - default - - cache - - key - - value - - expire - - - - - compile.cache - php - 10 - - - - From a6ad93aa318dfa1d4f483d09ee21e0214a2b8ed8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:22:12 +0000 Subject: [PATCH 0331/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2401 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index cfec6d27..775e5d89 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -154,7 +154,7 @@ public static function register($path, $alias = '', $includePath = false, $reset $alias = strtolower($alias); if (!empty($alias)) { if (!isset(self::$_namespace[$alias]) || $reset) - self::$_namespace[$alias] = $path; + self::$_namespace[$alias] = rtrim($path, D_S) . D_S; } if ($includePath) { if (empty(self::$_includePaths)) { @@ -226,7 +226,7 @@ public static function getRealPath($filePath, $suffix = '') { } } $filePath = str_replace('.', D_S, $filePath); - $namespace && $filePath = $namespace . D_S . $filePath; + $namespace && $filePath = $namespace . $filePath; return $suffix ? $filePath . '.' . $suffix : $filePath; } @@ -335,7 +335,7 @@ protected static function afterRun() { */ private static function _setDefaultSystemNamespace() { self::register(WIND_PATH, 'WIND', true); - self::register(WIND_PATH . 'component', 'COM', true); + self::register(WIND_PATH . 'component' . D_S, 'COM', true); } /** @@ -385,8 +385,31 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - Wind::import('WIND:core.*', true); - Wind::import('COM:log.WindLogger'); + self::$_classes = array('WindLogger' => 'log/WindLogger', + 'WindActionException' => 'core/exception/WindActionException', + 'WindException' => 'core/exception/WindException', + 'WindFinalException' => 'core/exception/WindFinalException', + 'IWindFactory' => 'core/factory/IWindFactory', + 'WindClassProxy' => 'core/factory/WindClassProxy', + 'WindFactory' => 'core/factory/WindFactory', 'WindFilter' => 'core/filter/WindFilter', + 'WindFilterChain' => 'core/filter/WindFilterChain', + 'WindHandlerInterceptor' => 'core/filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'core/filter/WindHandlerInterceptorChain', + 'IWindApplication' => 'core/IWindApplication', + 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', + 'WindFormListener' => 'core/web/listener/WindFormListener', + 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', + 'WindValidateListener' => 'core/web/listener/WindValidateListener', + 'WindController' => 'core/web/WindController', + 'WindDispatcher' => 'core/web/WindDispatcher', + 'WindErrorHandler' => 'core/web/WindErrorHandler', + 'WindForward' => 'core/web/WindForward', + 'WindSimpleController' => 'core/web/WindSimpleController', + 'WindUrlHelper' => 'core/web/WindUrlHelper', + 'WindWebApplication' => 'core/web/WindWebApplication', + 'WindEnableValidateModule' => 'core/WindEnableValidateModule', + 'WindErrorMessage' => 'core/WindErrorMessage', 'WindHelper' => 'core/WindHelper', + 'WindModule' => 'core/WindModule'); } } Wind::init(); From 3b3d9bfb9b11ea517921e259f97ed6d500675f8c Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:22:50 +0000 Subject: [PATCH 0332/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2402 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/AbstractWindRouter.php | 1 - wind/component/router/route/AbstractWindRoute.php | 1 - 2 files changed, 2 deletions(-) diff --git a/wind/component/router/AbstractWindRouter.php b/wind/component/router/AbstractWindRouter.php index d0e171c2..218b4d4d 100644 --- a/wind/component/router/AbstractWindRouter.php +++ b/wind/component/router/AbstractWindRouter.php @@ -1,5 +1,4 @@ * @author Qiong Wu From 564b64eea87480388615e768e32066dce60a44c6 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:24:49 +0000 Subject: [PATCH 0333/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2403 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindController.php | 7 +- wind/core/web/WindSimpleController.php | 12 +- wind/core/web/WindSystemConfig.php | 243 +++++++++++++++++++++++++ wind/core/web/WindWebApplication.php | 2 +- 4 files changed, 246 insertions(+), 18 deletions(-) create mode 100644 wind/core/web/WindSystemConfig.php diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php index 5e8d9c34..0700b908 100644 --- a/wind/core/web/WindController.php +++ b/wind/core/web/WindController.php @@ -5,7 +5,7 @@ * @version $Id$ * @package */ -class WindController extends WindSimpleController { +abstract class WindController extends WindSimpleController { /** * 验证类 * @@ -19,11 +19,6 @@ class WindController extends WindSimpleController { */ protected $formClass = ''; - /* (non-PHPdoc) - * @see WindSimpleController::run() - */ - public function run() {} - /* (non-PHPdoc) * @see WindSimpleController::preAction() */ diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index ca9d43cb..08e72819 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -12,10 +12,6 @@ abstract class WindSimpleController extends WindModule implements IWindControlle * @var WindForward */ protected $forward = null; - /** - * @var WindUrlHelper - */ - protected $urlHelper = null; /** * @var WindErrorMessage */ @@ -264,13 +260,6 @@ protected function getForward() { return $this->_getForward(); } - /** - * @return WindUrlHelper - */ - protected function getUrlHelper() { - return $this->_getUrlHelper(); - } - /** * @return WindErrorMessage */ @@ -279,6 +268,7 @@ protected function getErrorMessage() { } } + /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php new file mode 100644 index 00000000..54b8f800 --- /dev/null +++ b/wind/core/web/WindSystemConfig.php @@ -0,0 +1,243 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindSystemConfig extends WindModule { + private $appName = ''; + private $modules = array(); + + /** + * @param string $config + * @param string $appName + * @param WindFactory $factory + */ + public function __construct($config, $appName, $factory) { + $this->appName = $appName; + $this->setConfig($config, $factory); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config, $factory = null) { + if (empty($config)) + return; + if (is_string($config)) { + $configParser = $factory->getInstance('configParser'); + $config = $configParser->parse($config); + if (isset($config[$this->appName])) + $this->_config = $config[$this->appName]; + } else + $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; + } + + /** + * @return the $appName + */ + public function getAppName() { + return $this->appName; + } + + /** + * 返回当前应用的启动脚本位置 + */ + public function getAppClass($default = '') { + return $this->getConfig('class', '', $default); + } + + /** + * 返回应用编码信息 + */ + public function getCharset() { + return $this->getConfig('charset', '', 'utf-8'); + } + + /** + * 返回配置定义中定义的过滤链列表 + * 如果定义$name则返回在filters定义标签内对应的属性值 + * + * @param string $name + * @return array|string + */ + public function getFilters() { + return $this->getConfig('filters'); + } + + /** + * 返回filterChain的类型 + * + * @return array + */ + public function getFilterClass() { + return $this->getConfig('filters', 'class'); + } + + /** + * @param string $name + * @return array|string + */ + public function getRouter() { + return $this->getConfig('router'); + } + + /** + * 返回路由类型定义 + * @return string + */ + public function getRouterClass() { + return $this->getConfig('router', 'class', COMPONENT_ROUTER); + } + + /** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * @param string $name + * @return array|string + */ + public function getModules($name = '') { + return $this->getConfig('modules', $name, array()); + } + + /** + * 添加module + * controller + * + * Controller + * + * WIND:core.web.WindErrorHandler + * + * + * + * template + * + * htm + * + * @param string $name + * @param array $config + * @return + */ + public function setModules($name, $config = array()) { + if (!$_default = @$this->_config['modules']['default']) { + $_default = $this->getDefaultConfigStruct('modules'); + $this->_config['modules']['default'] = $_default; + } + if (!$config) + $this->_config['modules'][$name] = $_default; + else + $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); + return $this->_config['modules'][$name]; + } + + /** + * 返回module模板定义 + * @param unknown_type $name + * @param unknown_type $default + */ + public function getModuleTemplateDir($name, $default = '') { + return $this->getConfig('template-dir', '', $default, $this->getModules($name)); + } + + /** + * 根据module名称返回错误的处理句柄 + * @param string $name + * @param string $default + * @return string + */ + public function getModuleErrorHandler($name, $default = '') { + return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); + } + + /** + * 返回指定moduleName的controller路径信息 + * @param string $name + * @return string + */ + public function getModuleControllerPath($name, $default = '') { + return $this->getConfig('controller-path', '', $default, $this->getModules($name)); + } + + /** + * 返回指定moduleName的controller后缀 + * @param string $name + * @return string + */ + public function getModuleControllerSuffix($name, $default = '') { + return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); + } + + /** + * 返回指定ComponentName的Component配置信息 + * @param string $name + * @return string + */ + public function getComponents($name = '', $default = array()) { + return $this->getConfig('components', $name, $default); + } + + /** + * 获得DB配置,根据DB名义的别名来获取DB链接配置信息. + * 当别名为空时,返回全部DB链接配置. + * + * @param string $dbName + */ + public function getDbConfig($dbName = '') { + $config = $this->getConfig('db'); + if (isset($config['resource']) && !empty($config['resource'])) { + $_resource = Wind::getRealPath($config['resource'], true); + $this->_config['db'] = $this->parseConfig($_resource, 'db'); + } + return $this->getConfig('db', $dbName); + } + + /** + * 配置解析方法 + * @param string $config + * @param string $key + * @param string|boolean $append + * @param factory + */ + private function parseConfig($config, $key = 'config', $append = true) { + if (!$config) + return array(); + $configParser = $this->getSystemConfig()->getInstance('configParser'); + return $configParser->parse($config); + } + + /** + * 返回对应的配置结构及默认值 + * @param string $configName + * @throws WindException + * @return string + */ + public function getDefaultConfigStruct($configName) { + $_tmp = array(); + $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); + $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', + 'Controller'); + $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', + 'WIND:core.web.WindErrorHandler'); + return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); + } +} \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index bfac67cd..66403512 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -28,7 +28,7 @@ class WindWebApplication extends WindModule implements IWindApplication { * @var WindRouter */ protected $handlerAdapter = null; - protected $filterChain = 'COM:filter.WindFilterChain'; + protected $filterChain = 'WIND:filter.WindFilterChain'; /** * 应用初始化操作 From eed633637f8f0dc9f9243dcbc3ef4a5ead534c4f Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:25:03 +0000 Subject: [PATCH 0334/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2404 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/filter/WindUrlFilter.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wind/core/web/filter/WindUrlFilter.php b/wind/core/web/filter/WindUrlFilter.php index ec4622d6..201a3dc8 100644 --- a/wind/core/web/filter/WindUrlFilter.php +++ b/wind/core/web/filter/WindUrlFilter.php @@ -11,9 +11,7 @@ class WindUrlFilter extends WindFilter { * @see WindFilter::preHandle() */ public function preHandle($request = null, $response = null) { - $windFactory = $request->getAttribute(WindFrontController::WIND_FACTORY); - $this->urlHelper = $windFactory->getInstance(COMPONENT_URLHELPER); - $this->urlHelper->parseUrl(); + } /* (non-PHPdoc) From c0d69ff8820638628f0a04afe21eed3be0de2d97 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:25:13 +0000 Subject: [PATCH 0335/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2405 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/listener/WindFormListener.php | 39 +++++++++++-------- wind/core/web/listener/WindLoggerListener.php | 11 ++++-- .../web/listener/WindValidateListener.php | 26 ++++++++----- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/wind/core/web/listener/WindFormListener.php b/wind/core/web/listener/WindFormListener.php index b61198d6..9ae635f9 100644 --- a/wind/core/web/listener/WindFormListener.php +++ b/wind/core/web/listener/WindFormListener.php @@ -7,14 +7,14 @@ * @package */ class WindFormListener extends WindHandlerInterceptor { - + /** * @var WindHttpRequest */ private $request = null; - + private $formPath = ''; - + private $errorMessage = null; /** @@ -32,31 +32,38 @@ public function __construct($request, $formPath, $errorMessage) { */ public function preHandle() { $className = Wind::import($this->formPath); - if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); - if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException('the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); + if (!class_exists($className)) + throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); + if ('WindEnableValidateModule' != get_parent_class($className)) + throw new WindException( + 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { - if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; + if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) + continue; $_tmp[0] = strtolower($_tmp[0]); - $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet($_tmp); - if (null === $value) continue; + $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( + $_tmp); + if (null === $value) + continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { - list($errorController, $errorAction) = $form->getErrorControllerAndAction(); - $this->sendError($errorController, $errorAction, $error); + list($errorController, $errorAction) = $form->getErrorControllerAndAction(); + $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } - + private function sendError($errorController, $errorAction, $errors) { - if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); - $this->errorMessage->setErrorController($errorController); - $this->errorMessage->setErrorAction($errorAction); - $this->errorMessage->addError($errors); - $this->errorMessage->sendError(); + if (!$this->errorMessage instanceof WindErrorMessage) + $this->errorMessage = new WindErrorMessage(); + $this->errorMessage->setErrorController($errorController); + $this->errorMessage->setErrorAction($errorAction); + $this->errorMessage->addError($errors); + $this->errorMessage->sendError(); } /* (non-PHPdoc) diff --git a/wind/core/web/listener/WindLoggerListener.php b/wind/core/web/listener/WindLoggerListener.php index 824b6a9e..7f1137c1 100644 --- a/wind/core/web/listener/WindLoggerListener.php +++ b/wind/core/web/listener/WindLoggerListener.php @@ -1,5 +1,5 @@ $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; - if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; + if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) + continue; $function = isset($trace['function']) ? $trace['function'] : ''; - ($class == 'WindClassProxy' && $function == '__call') && $method = trim($trace['args'][0]); + ($class == 'WindClassProxy' && $function == '__call') && $method = trim( + $trace['args'][0]); ($function == $method) && $flag = true; - if (!isset($trace['file'])) continue; + if (!isset($trace['file'])) + continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } diff --git a/wind/core/web/listener/WindValidateListener.php b/wind/core/web/listener/WindValidateListener.php index 012a825d..71be225a 100644 --- a/wind/core/web/listener/WindValidateListener.php +++ b/wind/core/web/listener/WindValidateListener.php @@ -1,4 +1,5 @@ @@ -7,18 +8,18 @@ * @package */ class WindValidateListener extends WindHandlerInterceptor { - + /** * @var WindHttpRequest */ private $request = null; - + private $validateRules = array(); - + private $validator = null; - + private $validatorClass = ''; - + private $defaultMessage = '验证失败'; /** @@ -44,14 +45,18 @@ public function preHandle() { } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { - if (!is_array($rule)) continue; + if (!is_array($rule)) + continue; $key = $rule['field']; - $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost($key); + $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( + $key); $args = $rule['args']; array_unshift($args, $value); - if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { + if (call_user_func_array(array($this->getValidator(), $rule['validator']), + (array) $args) === false) { if (null === $rule['default']) - $errorMessage->addError(($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); + $errorMessage->addError( + ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } @@ -73,7 +78,8 @@ private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); - if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); + if ($this->validator === null) + throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } From f1d2912ee81ee41799cfb352a86bb8f17000cea4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 04:25:27 +0000 Subject: [PATCH 0336/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2406 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/filter/WindFilter.php | 25 ++++++ wind/core/filter/WindFilterChain.php | 63 ++++++++++++++ wind/core/filter/WindHandlerInterceptor.php | 50 +++++++++++ .../filter/WindHandlerInterceptorChain.php | 87 +++++++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 wind/core/filter/WindFilter.php create mode 100644 wind/core/filter/WindFilterChain.php create mode 100644 wind/core/filter/WindHandlerInterceptor.php create mode 100644 wind/core/filter/WindHandlerInterceptorChain.php diff --git a/wind/core/filter/WindFilter.php b/wind/core/filter/WindFilter.php new file mode 100644 index 00000000..fca9bb69 --- /dev/null +++ b/wind/core/filter/WindFilter.php @@ -0,0 +1,25 @@ + + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindFilter extends WindHandlerInterceptor { + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + + } + +} \ No newline at end of file diff --git a/wind/core/filter/WindFilterChain.php b/wind/core/filter/WindFilterChain.php new file mode 100644 index 00000000..5deb89ac --- /dev/null +++ b/wind/core/filter/WindFilterChain.php @@ -0,0 +1,63 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFilterChain extends WindHandlerInterceptorChain { + + /** + * @param array $filterConfig + */ + public function __construct($filterConfig) { + $this->_initFilters($filterConfig); + } + + /** + * @param string $filterName + */ + public function deleteFilter($alias) { + unset($this->_interceptors[$alias]); + } + + /** + * 在filter链中动态的添加一个filter + * 当befor为空时,添加到程序结尾处 + * 如果befor有值,则遍历数组,找到befor的位置,将新的过滤器添加到befor后面, + * 并将所有原befor位置后的过滤器往后移一位 + * + * @param string $filterName + * @param string $path + * @param string $beforFilter + */ + public function addFilter($filter, $beforFilter = '') { + if ($beforFilter === '') { + $this->addInterceptors(array(get_class($filter) => $filter)); + return true; + } + $_interceptors = array(); + foreach ($this->_interceptors as $key => $interceptor) { + if ($beforFilter === $key) break; + $_interceptors[$key] = $interceptor; + unset($this->_interceptors[$key]); + } + $_interceptors[get_class($filter)] = $filter; + $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; + } + + /** + * @param array $filters + */ + private function _initFilters($filters = array()) { + $_temp = array(); + foreach ((array) $filters as $key => $filter) { + if (!is_array($filter)) continue; + $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); + if (!class_exists($filterClass)) continue; + $_temp[$key] = new $filterClass(); + } + $this->addInterceptors($_temp); + } + +} \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptor.php b/wind/core/filter/WindHandlerInterceptor.php new file mode 100644 index 00000000..c6ca0890 --- /dev/null +++ b/wind/core/filter/WindHandlerInterceptor.php @@ -0,0 +1,50 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHandlerInterceptor extends WindModule { + protected $result = null; + protected $interceptorChain = null; + + /** + * Enter description here ... + */ + public function preHandle() {} + + /** + * Enter description here ... + */ + public function postHandle() {} + + /** + * Enter description here ... + * @return mixed + */ + public function handle() { + $args = func_get_args(); + $this->result = call_user_func_array(array($this, 'preHandle'), $args); + if ($this->result !== null) { + return $this->result; + } + if (null !== ($handler = $this->interceptorChain->getHandler())) { + $this->result = call_user_func_array(array($handler, 'handle'), $args); + } else { + $this->result = $this->interceptorChain->execute(); + } + call_user_func_array(array($this, 'postHandle'), $args); + return $this->result; + } + + /** + * 设置过滤链对象 + * + * @param WindHandlerInterceptorChain $interceptorChain + */ + public function setHandlerInterceptorChain($interceptorChain) { + $this->interceptorChain = $interceptorChain; + } +} +?> \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptorChain.php b/wind/core/filter/WindHandlerInterceptorChain.php new file mode 100644 index 00000000..71a5f316 --- /dev/null +++ b/wind/core/filter/WindHandlerInterceptorChain.php @@ -0,0 +1,87 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHandlerInterceptorChain extends WindModule { + protected $_interceptors = array(); + protected $_callBack = null; + protected $_args = array(); + protected $_state = 0; + + /** + * 设置回调方法 + * + * @param string|array $callBack + * @param array $args + * @return + */ + public function setCallBack($callBack, $args = array()) { + $this->_callBack = $callBack; + $this->_args = $args; + } + + /** + * 执行callback方法 + * + * @throws WindException + * @return void|mixed + */ + public function execute() { + if ($this->_callBack === null) + return null; + if (is_string($this->_callBack) && !function_exists($this->_callBack)) { + throw new WindException( + '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, + WindException::ERROR_FUNCTION_NOT_EXIST); + } + return call_user_func_array($this->_callBack, (array) $this->_args); + } + + /** + * 返回处理句柄 + * + * @return WindHandlerInterceptor + */ + public function getHandler() { + if (count($this->_interceptors) <= 0) { + $this->addInterceptors(new WindHandlerInterceptor()); + } + if ($this->_state >= count($this->_interceptors)) + return null; + $handler = $this->_interceptors[$this->_state++]; + if ($handler instanceof WindHandlerInterceptor) { + $handler->setHandlerInterceptorChain($this); + return $handler; + } + return $this->getHandler(); + } + + /** + * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 + * + * @param $interceptors + * @return + */ + public function addInterceptors($interceptors) { + if (is_array($interceptors)) + $this->_interceptors += $interceptors; + else + $this->_interceptors[] = $interceptors; + } + + /** + * 重置初始化信息 + * @return boolean + */ + public function reset() { + $this->_interceptors = array(); + $this->_callBack = null; + $this->_args = array(); + $this->_state = 0; + return true; + } +} +?> \ No newline at end of file From 263d4d817594fe14a5f59c79f93e2617ddd171a9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 06:59:14 +0000 Subject: [PATCH 0337/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2407 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/IWindController.php | 31 -------------------- wind/core/IWindErrorMessage.php | 36 ------------------------ wind/core/{web => }/WindErrorMessage.php | 32 +++++++++++++++++++++ wind/core/{web => }/WindHelper.php | 0 4 files changed, 32 insertions(+), 67 deletions(-) delete mode 100644 wind/core/IWindController.php delete mode 100644 wind/core/IWindErrorMessage.php rename wind/core/{web => }/WindErrorMessage.php (74%) rename wind/core/{web => }/WindHelper.php (100%) diff --git a/wind/core/IWindController.php b/wind/core/IWindController.php deleted file mode 100644 index d0e4cef3..00000000 --- a/wind/core/IWindController.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindController { - - /** - * 处理请求并返回Forward对象 - * @param WindUrlBasedRouter $handlerAdapter - * @return WindForward - */ - public function doAction($handlerAdapter); - - /** - * Action预处理方法 - * @param WindUrlBasedRouter $handlerAdapter - * @return - */ - public function preAction($handlerAdapter); - - /** - * Action后处理方法 - * @param WindUrlBasedRouter $handlerAdapter - * @return - */ - public function postAction($handlerAdapter); -} -?> \ No newline at end of file diff --git a/wind/core/IWindErrorMessage.php b/wind/core/IWindErrorMessage.php deleted file mode 100644 index 8ce16b3d..00000000 --- a/wind/core/IWindErrorMessage.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindErrorMessage { - - /** - * 添加错误信息 - * @param string $message - * @param string $key - */ - public function addError($message, $key = ''); - - /** - * 获得一条Error信息 - * @param string $key - */ - public function getError($key = ''); - - /** - * 清空Error信息 - */ - public function clearError(); - - /** - * 发送错误信息 - */ - public function sendError(); -} - -?> \ No newline at end of file diff --git a/wind/core/web/WindErrorMessage.php b/wind/core/WindErrorMessage.php similarity index 74% rename from wind/core/web/WindErrorMessage.php rename to wind/core/WindErrorMessage.php index d053458a..eeca7b82 100644 --- a/wind/core/web/WindErrorMessage.php +++ b/wind/core/WindErrorMessage.php @@ -72,4 +72,36 @@ public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } +} + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindErrorMessage { + + /** + * 添加错误信息 + * @param string $message + * @param string $key + */ + public function addError($message, $key = ''); + + /** + * 获得一条Error信息 + * @param string $key + */ + public function getError($key = ''); + + /** + * 清空Error信息 + */ + public function clearError(); + + /** + * 发送错误信息 + */ + public function sendError(); } \ No newline at end of file diff --git a/wind/core/web/WindHelper.php b/wind/core/WindHelper.php similarity index 100% rename from wind/core/web/WindHelper.php rename to wind/core/WindHelper.php From da5c92939508711a49546f133277259dfa2cafee Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 07:00:06 +0000 Subject: [PATCH 0338/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2408 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 54 +++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 775e5d89..c25fc9f9 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -385,31 +385,35 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - self::$_classes = array('WindLogger' => 'log/WindLogger', - 'WindActionException' => 'core/exception/WindActionException', - 'WindException' => 'core/exception/WindException', - 'WindFinalException' => 'core/exception/WindFinalException', - 'IWindFactory' => 'core/factory/IWindFactory', - 'WindClassProxy' => 'core/factory/WindClassProxy', - 'WindFactory' => 'core/factory/WindFactory', 'WindFilter' => 'core/filter/WindFilter', - 'WindFilterChain' => 'core/filter/WindFilterChain', - 'WindHandlerInterceptor' => 'core/filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'core/filter/WindHandlerInterceptorChain', - 'IWindApplication' => 'core/IWindApplication', - 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', - 'WindFormListener' => 'core/web/listener/WindFormListener', - 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', - 'WindValidateListener' => 'core/web/listener/WindValidateListener', - 'WindController' => 'core/web/WindController', - 'WindDispatcher' => 'core/web/WindDispatcher', - 'WindErrorHandler' => 'core/web/WindErrorHandler', - 'WindForward' => 'core/web/WindForward', - 'WindSimpleController' => 'core/web/WindSimpleController', - 'WindUrlHelper' => 'core/web/WindUrlHelper', - 'WindWebApplication' => 'core/web/WindWebApplication', - 'WindEnableValidateModule' => 'core/WindEnableValidateModule', - 'WindErrorMessage' => 'core/WindErrorMessage', 'WindHelper' => 'core/WindHelper', - 'WindModule' => 'core/WindModule'); + self::$_classes = array( + 'WindLogger' => 'log/WindLogger', + 'WindActionException' => 'core/exception/WindActionException', + 'WindException' => 'core/exception/WindException', + 'WindFinalException' => 'core/exception/WindFinalException', + 'IWindFactory' => 'core/factory/IWindFactory', + 'WindClassProxy' => 'core/factory/WindClassProxy', + 'WindFactory' => 'core/factory/WindFactory', + 'WindFilter' => 'core/filter/WindFilter', + 'WindFilterChain' => 'core/filter/WindFilterChain', + 'WindHandlerInterceptor' => 'core/filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'core/filter/WindHandlerInterceptorChain', + 'IWindApplication' => 'core/IWindApplication', + 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', + 'WindFormListener' => 'core/web/listener/WindFormListener', + 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', + 'WindValidateListener' => 'core/web/listener/WindValidateListener', + 'WindController' => 'core/web/WindController', + 'WindDispatcher' => 'core/web/WindDispatcher', + 'WindErrorHandler' => 'core/web/WindErrorHandler', + 'WindForward' => 'core/web/WindForward', + 'WindSimpleController' => 'core/web/WindSimpleController', + 'WindSystemConfig' => 'core/web/WindSystemConfig', + 'WindUrlHelper' => 'core/web/WindUrlHelper', + 'WindWebApplication' => 'core/web/WindWebApplication', + 'WindEnableValidateModule' => 'core/WindEnableValidateModule', + 'WindErrorMessage' => 'core/WindErrorMessage', + 'WindHelper' => 'core/WindHelper', + 'WindModule' => 'core/WindModule'); } } Wind::init(); From 1a27163fc8279100612132bb15d782ea779dc20f Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 07:49:30 +0000 Subject: [PATCH 0339/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2409 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindHelper.php | 1 + wind/core/WindModule.php | 8 +++--- wind/core/factory/WindFactory.php | 39 +++++++++++++++------------- wind/core/web/WindWebApplication.php | 4 ++- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php index 41395aac..59318bf0 100644 --- a/wind/core/WindHelper.php +++ b/wind/core/WindHelper.php @@ -19,6 +19,7 @@ class WindHelper { * @param string $errline */ public static function errorHandle($errno, $errstr, $errfile, $errline) { + echo $errno,$errfile,'.....',$errline,'
'; if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 7c7e567f..5ce3bbc4 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -70,14 +70,14 @@ public function __call($methodName, $args) { $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { - if (@$this->delayAttributes[$_propertyName] !== null) { + if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; - if (@$_property['value'] !== null) { + if (isset($_property['value'])) { $_value = $_property['value']; - } elseif (@$_property['ref'] !== null) { + } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); - } elseif (@$_property['path'] !== null) { + } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 0d2d5115..ca751cbc 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -40,22 +40,23 @@ public function getInstance($alias, $args = array()) { if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; - if (@$definition['className'] === null) + if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); - foreach ((array) @$definition['constructorArgs'] as $_var) { - if (@$_var['value'] !== null) { - $args[] = $_var['value']; - } elseif (@$_var['ref'] !== null) - $args[] = $this->getInstance($_var['ref']); - } + if (isset($definition['constructorArgs'])) + foreach ((array) $definition['constructorArgs'] as $_var) { + if (isset($_var['value'])) { + $args[] = $_var['value']; + } elseif (isset($_var['ref'])) + $args[] = $this->getInstance($_var['ref']); + } $instance = $this->createInstance($definition['className'], $args); - if (@$definition['config']) + if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); - if (@$definition['properties']) + if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); - if (@$definition['initMethod']) + if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); - if (@$definition['proxy']) + if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; @@ -83,9 +84,9 @@ static public function createInstance($className, $args = array()) { Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); } - if (empty($args)){ + if (empty($args)) { return new $className(); - }else { + } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } @@ -184,7 +185,7 @@ protected function setScope($alias, $scope, $instance) { * @return */ protected function resolveConfig($config, $alias, $instance) { - if (@$config['resource']) { + if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, @@ -235,14 +236,16 @@ protected function setProxyForClass($proxy, $instance) { * @param WindModule $instance */ protected function buildProperties($properties, $instance) { - if (@$properties['delay'] === 'false' || @$properties['delay'] === false) { + if (!isset($properties['delay'])) { + $instance->setDelayAttributes($properties); + } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; - if (@$subDefinition['value'] !== null) + if (isset($subDefinition['value'])) $_value = $subDefinition['value']; - elseif (@$subDefinition['ref'] !== null) + elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); - elseif (@$subDefinition['path'] != null) { + elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 66403512..dc9d5490 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -197,7 +197,9 @@ protected function getFilterChain() { * @return array */ public function setModules($name, $config = array()) { - if (!$_default = @$this->_config['modules']['default']) { + if (isset($this->_config['modules']['default'])) + $_default = $this->_config['modules']['default']; + else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); From 18cc5dbbe6d5dfc1c197c558b4ecf02c0acc2b34 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 08:08:37 +0000 Subject: [PATCH 0340/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2410 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 2 ++ _compile/wind_basic.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/_compile/compile.php b/_compile/compile.php index 26217128..7fc5bafa 100644 --- a/_compile/compile.php +++ b/_compile/compile.php @@ -9,6 +9,8 @@ Wind::clear(); Wind::import('COM:log.WindLogger'); Wind::import('WIND:core.*', true); +Wind::import('COM:parser.*', true); +Wind::import('COM:router.*', true); $imports = Wind::getImports(); /* 载入需要的文件信息 */ diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php index e7747f46..2614f6f3 100644 --- a/_compile/wind_basic.php +++ b/_compile/wind_basic.php @@ -1 +1 @@ -$_setter($value); else Wind::log( '[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); else Wind::log( '[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (@$this->delayAttributes[$_propertyName] !== null) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (@$_property['value'] !== null) { $_value = $_property['value']; } elseif (@$_property['ref'] !== null) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (@$_property['path'] !== null) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) { Wind::log( "[core.WindModule.__clone] unexcepted value type or the property is not setted.(" . $value . ") need an object type in here. ", WindLogger::LEVEL_DEBUG, 'wind.core'); continue; } $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { Wind::log( '[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } if (!($_writeTableProperties = $this->writeTableForProperty())) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { if ($value instanceof $_writeTableProperties[$propertyName]) return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. ", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } return true; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); public function __construct($logDir = '', $writeType = 0) { $this->_logDir = $logDir; $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_INFO, $type); } public function trace($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_TRACE, $type); } public function debug($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_DEBUG, $type); } public function error($msg, $type = 'wind.core') { $this->log($msg, self::LEVEL_ERROR, $type); } public function profileBegin($msg, $type = 'wind.core') { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type); } public function profileEnd($msg, $type = 'wind.core') { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { $this->_types[] = $type; } } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { switch ($key) { case self::LEVEL_INFO: $key = 'info'; break; case self::LEVEL_ERROR: $key = 'error'; break; case self::LEVEL_DEBUG: $key = 'debug'; break; case self::LEVEL_TRACE: $key = 'trace'; break; case self::LEVEL_PROFILE: $key = 'profile'; break; default: $key = 'all'; break; } if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . " timer: " . sprintf('%0.5f', ($timer - DEBUG_TIME)) . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; if (@$definition['className'] === null) $definition['className'] = Wind::import(@$definition['path']); foreach ((array) @$definition['constructorArgs'] as $_var) { if (@$_var['value'] !== null) { $args[] = $_var['value']; } elseif (@$_var['ref'] !== null) $args[] = $this->getInstance($_var['ref']); } $instance = $this->createInstance($definition['className'], $args); if (@$definition['config']) $this->resolveConfig($definition['config'], $alias, $instance); if (@$definition['properties']) $this->buildProperties($definition['properties'], $instance); if (@$definition['initMethod']) $this->executeInitMethod($definition['initMethod'], $instance); if (@$definition['proxy']) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); } if (empty($args)){ return new $className(); }else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (!is_string($alias) || empty($alias)) { throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (@$config['resource']) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (@$properties['delay'] === 'false' || @$properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (@$subDefinition['value'] !== null) $_value = $subDefinition['value']; elseif (@$subDefinition['ref'] !== null) $_value = $this->getInstance($subDefinition['ref']); elseif (@$subDefinition['path'] != null) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException( '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $errsample = ''; if ($_errhtml && is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $errsample = implode("\n", $fileLines) . "\n"; } } if ($_errhtml) $errfile = "$file"; else $errfile = "$file"; $msg = "$errfile\n$errsample\n$errtrace\n"; } $msg .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; if ($_errhtml) { $msg = "$topic

$topic

$errmessage\n$msg
"; } else $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . '('; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } ?> \ No newline at end of file +$_setter($value); else Wind::log( '[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); else Wind::log( '[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) { Wind::log( "[core.WindModule.__clone] unexcepted value type or the property is not setted.(" . $value . ") need an object type in here. ", WindLogger::LEVEL_DEBUG, 'wind.core'); continue; } $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { Wind::log( '[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } if (!($_writeTableProperties = $this->writeTableForProperty())) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { if ($value instanceof $_writeTableProperties[$propertyName]) return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. ", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } return true; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); public function __construct($logDir = '', $writeType = 0) { $this->_logDir = $logDir; $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_INFO, $type); } public function trace($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_TRACE, $type); } public function debug($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_DEBUG, $type); } public function error($msg, $type = 'wind.core') { $this->log($msg, self::LEVEL_ERROR, $type); } public function profileBegin($msg, $type = 'wind.core') { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type); } public function profileEnd($msg, $type = 'wind.core') { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { $this->_types[] = $type; } } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { switch ($key) { case self::LEVEL_INFO: $key = 'info'; break; case self::LEVEL_ERROR: $key = 'error'; break; case self::LEVEL_DEBUG: $key = 'debug'; break; case self::LEVEL_TRACE: $key = 'trace'; break; case self::LEVEL_PROFILE: $key = 'profile'; break; default: $key = 'all'; break; } if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . " timer: " . sprintf('%0.5f', ($timer - DEBUG_TIME)) . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); if (isset($definition['constructorArgs'])) foreach ((array) $definition['constructorArgs'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); } if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (!is_string($alias) || empty($alias)) { throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException( '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { echo $errno,$errfile,'.....',$errline,'
'; if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $errsample = ''; if ($_errhtml && is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $errsample = implode("\n", $fileLines) . "\n"; } } if ($_errhtml) $errfile = "$file"; else $errfile = "$file"; $msg = "$errfile\n$errsample\n$errtrace\n"; } $msg .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; if ($_errhtml) { $msg = "$topic

$topic

$errmessage\n$msg
"; } else $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . '('; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { $this->getRequest()->setAttribute($value, $key); if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } ?> \ No newline at end of file From b16a39b8c19db561e8447e0faa3d94484de76813 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 08:09:06 +0000 Subject: [PATCH 0341/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2411 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/ftp/WindFtp.php | 2 +- wind/component/ftp/WindSocketFtp.php | 2 +- .../http/transfer/WindHttpSocket.php | 2 +- wind/component/utility/WindMimeTypes.php | 243 ------------------ 4 files changed, 3 insertions(+), 246 deletions(-) delete mode 100644 wind/component/utility/WindMimeTypes.php diff --git a/wind/component/ftp/WindFtp.php b/wind/component/ftp/WindFtp.php index 49756a6d..76959bc0 100644 --- a/wind/component/ftp/WindFtp.php +++ b/wind/component/ftp/WindFtp.php @@ -63,7 +63,7 @@ public function delete($filename) { * (non-PHPdoc) * see AbstractWindFtp::upload() */ - public function upload($sourceFile, $desFile, $mode = 'auto') { + public function upload($sourceFile, $desFile, $mode) { $mode = $this->getMode($sourceFile, $mode); if (!in_array(($savedir = dirname($desFile)), array('.', '/'))) { $this->mkdirs($savedir); diff --git a/wind/component/ftp/WindSocketFtp.php b/wind/component/ftp/WindSocketFtp.php index 1d92e6c5..1719a0a9 100644 --- a/wind/component/ftp/WindSocketFtp.php +++ b/wind/component/ftp/WindSocketFtp.php @@ -56,7 +56,7 @@ protected function pwd() { * (non-PHPdoc) * @see AbstractWindFtp::upload() */ - public function upload($localfile, $remotefile, $mode = 'I') { + public function upload($localfile, $remotefile, $mode) { if ($this->checkFile($localfile)) { $this->showError("Error:illegal file type!({$localfile})"); } diff --git a/wind/component/http/transfer/WindHttpSocket.php b/wind/component/http/transfer/WindHttpSocket.php index 1eea5979..06c6d5f8 100644 --- a/wind/component/http/transfer/WindHttpSocket.php +++ b/wind/component/http/transfer/WindHttpSocket.php @@ -35,7 +35,7 @@ public function open() { $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; - $this->httpResource = fsockopen($this->host, $this->port, &$this->eno, &$this->err, $this->timeout); + $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } diff --git a/wind/component/utility/WindMimeTypes.php b/wind/component/utility/WindMimeTypes.php deleted file mode 100644 index d7407c27..00000000 --- a/wind/component/utility/WindMimeTypes.php +++ /dev/null @@ -1,243 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -return $mimes = array( - 'ai' => 'application/postscript', - 'aif' => 'audio/x-aiff', - 'aifc' => 'audio/x-aiff', - 'aiff' => 'audio/x-aiff', - 'asc' => 'text/plain', - 'au' => 'audio/basic', - 'avi' => 'video/x-msvideo', - 'bcpio' => 'application/x-bcpio', - 'bin' => 'application/macbinary', - 'bmp' => 'image/bmp', - 'c' => 'text/plain', - 'cc' => 'text/plain', - 'ccad' => 'application/clariscad', - 'cdf' => 'application/x-netcdf', - 'class' => 'application/octet-stream', - 'cpio' => 'application/x-cpio', - 'cpt' => 'application/mac-compactpro', - 'csh' => 'application/x-csh', - 'css' => 'text/css', - 'dcr' => 'application/x-director', - 'dir' => 'application/x-director', - 'dms' => 'application/octet-stream', - 'doc' => 'application/msword', - 'drw' => 'application/drafting', - 'dvi' => 'application/x-dvi', - 'dwg' => 'application/acad', - 'dxf' => 'application/dxf', - 'dxr' => 'application/x-director', - 'eps' => 'application/postscript', - 'etx' => 'text/x-setext', - 'exe' => 'application/octet-stream', - 'ez' => 'application/andrew-inset', - 'f' => 'text/plain', - 'f90' => 'text/plain', - 'fli' => 'video/x-fli', - 'flv' => 'video/x-flv', - 'gif' => 'image/gif', - 'gtar' => 'application/x-gtar', - 'gz' => 'application/x-gzip', - 'h' => 'text/plain', - 'hdf' => 'application/x-hdf', - 'hh' => 'text/plain', - 'hqx' => 'application/mac-binhex40', - 'htm' => 'text/html', - 'html' => 'text/html', - 'ice' => 'x-conference/x-cooltalk', - 'ief' => 'image/ief', - 'iges' => 'model/iges', - 'igs' => 'model/iges', - 'ips' => 'application/x-ipscript', - 'ipx' => 'application/x-ipix', - 'jpe' => array( - 'image/jpeg', - 'image/pjpeg', - ), - 'jpeg' => array( - 'image/jpeg', - 'image/pjpeg', - ), - 'jpg' => array( - 'image/jpeg', - 'image/pjpeg', - ), - 'js' => 'application/x-javascript', - 'kar' => 'audio/midi', - 'latex' => 'application/x-latex', - 'lha' => 'application/octet-stream', - 'lsp' => 'application/x-lisp', - 'lzh' => 'application/octet-stream', - 'm' => 'text/plain', - 'man' => 'application/x-troff-man', - 'me' => 'application/x-troff-me', - 'mesh' => 'model/mesh', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mif' => 'application/vnd.mif', - 'mime' => 'www/mime', - 'mov' => 'video/quicktime', - 'movie' => 'video/x-sgi-movie', - 'mp2' => 'audio/mpeg', - 'mp3' => array( - 'audio/mpeg', - 'audio/mpg', - ), - 'mpe' => 'video/mpeg', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpga' => 'audio/mpeg', - 'ms' => 'application/x-troff-ms', - 'msh' => 'model/mesh', - 'nc' => 'application/x-netcdf', - 'oda' => 'application/oda', - 'pbm' => 'image/x-portable-bitmap', - 'pdb' => 'chemical/x-pdb', - 'pdf' => array( - 'application/pdf', - 'application/x-download', - ), - 'pgm' => 'image/x-portable-graymap', - 'pgn' => 'application/x-chess-pgn', - 'png' => array( - 'image/png', - 'image/x-png', - ), - 'pnm' => 'image/x-portable-anymap', - 'pot' => 'application/mspowerpoint', - 'ppm' => 'image/x-portable-pixmap', - 'pps' => 'application/mspowerpoint', - 'ppt' => array( - 'application/powerpoint', - 'application/vnd.ms-powerpoint', - ), - 'ppz' => 'application/mspowerpoint', - 'pre' => 'application/x-freelance', - 'prt' => 'application/pro_eng', - 'ps' => 'application/postscript', - 'qt' => 'video/quicktime', - 'ra' => 'audio/x-realaudio', - 'ram' => 'audio/x-pn-realaudio', - 'ras' => 'image/cmu-raster', - 'rgb' => 'image/x-rgb', - 'rm' => 'audio/x-pn-realaudio', - 'roff' => 'application/x-troff', - 'rpm' => 'audio/x-pn-realaudio-plugin', - 'rtf' => 'text/rtf', - 'rtx' => 'text/richtext', - 'scm' => 'application/x-lotusscreencam', - 'set' => 'application/set', - 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', - 'sh' => 'application/x-sh', - 'shar' => 'application/x-shar', - 'silo' => 'model/mesh', - 'sit' => 'application/x-stuffit', - 'skd' => 'application/x-koan', - 'skm' => 'application/x-koan', - 'skp' => 'application/x-koan', - 'skt' => 'application/x-koan', - 'smi' => 'application/smil', - 'smil' => 'application/smil', - 'snd' => 'audio/basic', - 'sol' => 'application/solids', - 'spl' => 'application/x-futuresplash', - 'src' => 'application/x-wais-source', - 'step' => 'application/STEP', - 'stl' => 'application/SLA', - 'stp' => 'application/STEP', - 'sv4cpio' => 'application/x-sv4cpio', - 'sv4crc' => 'application/x-sv4crc', - 'swf' => 'application/x-shockwave-flash', - 't' => 'application/x-troff', - 'tar' => 'application/x-tar', - 'tcl' => 'application/x-tcl', - 'tex' => 'application/x-tex', - 'texi' => 'application/x-texinfo', - 'texinfo' => 'application/x-texinfo', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'tr' => 'application/x-troff', - 'tsi' => 'audio/TSP-audio', - 'tsp' => 'application/dsptype', - 'tsv' => 'text/tab-separated-values', - 'txt' => 'text/plain', - 'unv' => 'application/i-deas', - 'ustar' => 'application/x-ustar', - 'vcd' => 'application/x-cdlink', - 'vda' => 'application/vda', - 'viv' => 'video/vnd.vivo', - 'vivo' => 'video/vnd.vivo', - 'vrml' => 'model/vrml', - 'wav' => 'audio/x-wav', - 'wrl' => 'model/vrml', - 'xbm' => 'image/x-xbitmap', - 'xlc' => 'application/vnd.ms-excel', - 'xll' => 'application/vnd.ms-excel', - 'xlm' => 'application/vnd.ms-excel', - 'xls' => array( - 'application/excel', - 'application/vnd.ms-excel', - 'application/msexcel', - ), - 'xlw' => 'application/vnd.ms-excel', - 'xml' => 'text/xml', - 'xpm' => 'image/x-xpixmap', - 'xwd' => 'image/x-xwindowdump', - 'xyz' => 'chemical/x-pdb', - 'zip' => array( - 'application/x-zip', - 'application/zip', - 'application/x-zip-compressed', - ), - 'csv' => array( - 'text/x-comma-separated-values', - 'text/comma-separated-values', - 'application/octet-stream', - 'application/vnd.ms-excel', - 'text/csv', - 'application/csv', - 'application/excel', - 'application/vnd.msexcel', - ), - 'psd' => 'application/x-photoshop', - 'so' => 'application/octet-stream', - 'sea' => 'application/octet-stream', - 'dll' => 'application/octet-stream', - 'wbxml' => 'application/wbxml', - 'wmlc' => 'application/wmlc', - 'php' => 'application/x-httpd-php', - 'php4' => 'application/x-httpd-php', - 'php3' => 'application/x-httpd-php', - 'phtml' => 'application/x-httpd-php', - 'phps' => 'application/x-httpd-php-source', - 'tgz' => 'application/x-tar', - 'xhtml' => 'application/xhtml+xml', - 'xht' => 'application/xhtml+xml', - 'rv' => 'video/vnd.rn-realvideo', - 'shtml' => 'text/html', - 'text' => 'text/plain', - 'log' => array( - 'text/plain', - 'text/x-log', - ), - 'xsl' => 'text/xml', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'word' => array( - 'application/msword', - 'application/octet-stream', - ), - 'xl' => 'application/excel', - 'eml' => 'message/rfc822', -); - - From 4b5e9ea23d995138202120e603e021a875d94ffa Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 08:09:23 +0000 Subject: [PATCH 0342/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2412 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 75 +++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index c25fc9f9..1200ed48 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -125,11 +125,10 @@ public static function import($filePath, $recursivePackage = false) { } else { if (($pos = strrpos($file, '.')) === false) { $fileName = $file; - } else { - if (substr($file, $pos + 1) === self::$_extensions) { - $fileName = substr($file, 0, $pos); - } - } + } elseif (substr($file, $pos + 1) === self::$_extensions) { + $fileName = substr($file, 0, $pos); + } else + continue; self::_setImport($fileName, $filePath . '.' . $fileName); } } @@ -192,7 +191,7 @@ public static function autoLoad($className, $path = '') { if ($path === '') throw new Exception('auto load ' . $className . ' failed.'); $path .= '.' . self::$_extensions; - if ((@include $path) === false) + if ((include $path) === false) throw new Exception( '[wind.Wind.autoLoad] Your requested \'' . $path . '\' was not found on this server.'); } @@ -385,35 +384,41 @@ private static function _registerAutoloader() { * @return */ private static function _loadBaseLib() { - self::$_classes = array( - 'WindLogger' => 'log/WindLogger', - 'WindActionException' => 'core/exception/WindActionException', - 'WindException' => 'core/exception/WindException', - 'WindFinalException' => 'core/exception/WindFinalException', - 'IWindFactory' => 'core/factory/IWindFactory', - 'WindClassProxy' => 'core/factory/WindClassProxy', - 'WindFactory' => 'core/factory/WindFactory', - 'WindFilter' => 'core/filter/WindFilter', - 'WindFilterChain' => 'core/filter/WindFilterChain', - 'WindHandlerInterceptor' => 'core/filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'core/filter/WindHandlerInterceptorChain', - 'IWindApplication' => 'core/IWindApplication', - 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', - 'WindFormListener' => 'core/web/listener/WindFormListener', - 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', - 'WindValidateListener' => 'core/web/listener/WindValidateListener', - 'WindController' => 'core/web/WindController', - 'WindDispatcher' => 'core/web/WindDispatcher', - 'WindErrorHandler' => 'core/web/WindErrorHandler', - 'WindForward' => 'core/web/WindForward', - 'WindSimpleController' => 'core/web/WindSimpleController', - 'WindSystemConfig' => 'core/web/WindSystemConfig', - 'WindUrlHelper' => 'core/web/WindUrlHelper', - 'WindWebApplication' => 'core/web/WindWebApplication', - 'WindEnableValidateModule' => 'core/WindEnableValidateModule', - 'WindErrorMessage' => 'core/WindErrorMessage', - 'WindHelper' => 'core/WindHelper', - 'WindModule' => 'core/WindModule'); + self::$_classes = array('WindLogger' => 'log/WindLogger', + 'WindActionException' => 'core/exception/WindActionException', + 'WindException' => 'core/exception/WindException', + 'WindFinalException' => 'core/exception/WindFinalException', + 'IWindFactory' => 'core/factory/IWindFactory', + 'WindClassProxy' => 'core/factory/WindClassProxy', + 'WindFactory' => 'core/factory/WindFactory', 'WindFilter' => 'core/filter/WindFilter', + 'WindFilterChain' => 'core/filter/WindFilterChain', + 'WindHandlerInterceptor' => 'core/filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'core/filter/WindHandlerInterceptorChain', + 'IWindApplication' => 'core/IWindApplication', + 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', + 'WindFormListener' => 'core/web/listener/WindFormListener', + 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', + 'WindValidateListener' => 'core/web/listener/WindValidateListener', + 'WindController' => 'core/web/WindController', + 'WindDispatcher' => 'core/web/WindDispatcher', + 'WindErrorHandler' => 'core/web/WindErrorHandler', + 'WindForward' => 'core/web/WindForward', + 'WindSimpleController' => 'core/web/WindSimpleController', + 'WindSystemConfig' => 'core/web/WindSystemConfig', + 'WindUrlHelper' => 'core/web/WindUrlHelper', + 'WindWebApplication' => 'core/web/WindWebApplication', + 'WindEnableValidateModule' => 'core/WindEnableValidateModule', + 'WindErrorMessage' => 'core/WindErrorMessage', 'WindHelper' => 'core/WindHelper', + 'WindModule' => 'core/WindModule', 'IWindConfigParser' => 'parser/IWindConfigParser', + 'WindConfigParser' => 'parser/WindConfigParser', + 'WindIniParser' => 'parser/WindIniParser', + 'WindPropertiesParser' => 'parser/WindPropertiesParser', + 'WindXmlParser' => 'parser/WindXmlParser', + 'AbstractWindRouter' => 'router/AbstractWindRouter', + 'AbstractWindRoute' => 'router/route/AbstractWindRoute', + 'WindRewriteRoute' => 'router/route/WindRewriteRoute', + 'WindRoute' => 'router/route/WindRoute', 'WindRouter' => 'router/WindRouter', + 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter'); } } Wind::init(); From d6b610f56d36d3dbe714dc77410e73e7a1e57c47 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 08:09:48 +0000 Subject: [PATCH 0343/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2413 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 1200ed48..cfd7f08e 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -424,7 +424,7 @@ private static function _loadBaseLib() { Wind::init(); /* 组件定义 */ -define('COMPONENT_WEBAPP', 'windWebApp'); +/*define('COMPONENT_WEBAPP', 'windWebApp'); define('COMPONENT_ERRORHANDLER', 'errorHandler'); define('COMPONENT_LOGGER', 'windLogger'); define('COMPONENT_FORWARD', 'forward'); @@ -437,6 +437,6 @@ private static function _loadBaseLib() { define('COMPONENT_DB', 'db'); define('COMPONENT_DISPATCHER', 'dispatcher'); define('COMPONENT_CONFIGPARSER', 'configParser'); -define('COMPONENT_CACHE', 'windCache'); +define('COMPONENT_CACHE', 'windCache');*/ //TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 //********************约定变量*********************************** From b27914b2a60757bb97a6fb5c043427704cc03fd0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 08:21:09 +0000 Subject: [PATCH 0344/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2414 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index cfd7f08e..f9a16dfc 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -30,6 +30,7 @@ class Wind { private static $_includePaths = array(); private static $_app = array(); private static $_currentApp = array(); + private static $_currentAppName; /** * @param string $appName @@ -64,9 +65,9 @@ public static function run($appName = 'default', $config = array(), $rootPath = * @return string */ public static function getAppName() { - if (empty(self::$_currentApp)) + if (!self::$_currentAppName) throw new WindException('Get appName failed.', WindException::ERROR_SYSTEM_ERROR); - return end(self::$_currentApp); + return self::$_currentAppName; //end(self::$_currentApp); } /** @@ -75,7 +76,7 @@ public static function getAppName() { * @return WindWebApplication */ public static function getApp() { - $_appName = self::getAppName(); + $_appName = self::$_currentAppName; //self::getAppName(); if (isset(self::$_app[$_appName])) return self::$_app[$_appName]; else @@ -317,6 +318,7 @@ protected static function beforRun($appName, $config, $rootPath) { if (!$appName || in_array($appName, self::$_currentApp)) throw new WindException('Nested request', WindException::ERROR_SYSTEM_ERROR); array_push(self::$_currentApp, $appName); + self::$_currentAppName = $appName; } /** @@ -324,6 +326,7 @@ protected static function beforRun($appName, $config, $rootPath) { */ protected static function afterRun() { array_pop(self::$_currentApp); + self::$_currentAppName = end(self::$_currentApp); if (self::$_logger) self::$_logger->flush(); } From 73d36ff3fff6ede64a48262dc1aee49672bc5313 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 08:25:42 +0000 Subject: [PATCH 0345/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2415 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 1 + _compile/wind_basic.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/_compile/compile.php b/_compile/compile.php index 7fc5bafa..e90813b6 100644 --- a/_compile/compile.php +++ b/_compile/compile.php @@ -11,6 +11,7 @@ Wind::import('WIND:core.*', true); Wind::import('COM:parser.*', true); Wind::import('COM:router.*', true); +Wind::import('COM:http.*', true); $imports = Wind::getImports(); /* 载入需要的文件信息 */ diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php index 2614f6f3..b6bd2685 100644 --- a/_compile/wind_basic.php +++ b/_compile/wind_basic.php @@ -1 +1 @@ -$_setter($value); else Wind::log( '[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); else Wind::log( '[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) { Wind::log( "[core.WindModule.__clone] unexcepted value type or the property is not setted.(" . $value . ") need an object type in here. ", WindLogger::LEVEL_DEBUG, 'wind.core'); continue; } $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { Wind::log( '[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } if (!($_writeTableProperties = $this->writeTableForProperty())) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { if ($value instanceof $_writeTableProperties[$propertyName]) return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. ", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } return true; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); public function __construct($logDir = '', $writeType = 0) { $this->_logDir = $logDir; $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_INFO, $type); } public function trace($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_TRACE, $type); } public function debug($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_DEBUG, $type); } public function error($msg, $type = 'wind.core') { $this->log($msg, self::LEVEL_ERROR, $type); } public function profileBegin($msg, $type = 'wind.core') { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type); } public function profileEnd($msg, $type = 'wind.core') { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { $this->_types[] = $type; } } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { switch ($key) { case self::LEVEL_INFO: $key = 'info'; break; case self::LEVEL_ERROR: $key = 'error'; break; case self::LEVEL_DEBUG: $key = 'debug'; break; case self::LEVEL_TRACE: $key = 'trace'; break; case self::LEVEL_PROFILE: $key = 'profile'; break; default: $key = 'all'; break; } if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . " timer: " . sprintf('%0.5f', ($timer - DEBUG_TIME)) . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); if (isset($definition['constructorArgs'])) foreach ((array) $definition['constructorArgs'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); } if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (!is_string($alias) || empty($alias)) { throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException( '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { echo $errno,$errfile,'.....',$errline,'
'; if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $errsample = ''; if ($_errhtml && is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $errsample = implode("\n", $fileLines) . "\n"; } } if ($_errhtml) $errfile = "$file"; else $errfile = "$file"; $msg = "$errfile\n$errsample\n$errtrace\n"; } $msg .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; if ($_errhtml) { $msg = "$topic

$topic

$errmessage\n$msg
"; } else $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . '('; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { $this->getRequest()->setAttribute($value, $key); if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } ?> \ No newline at end of file +$_setter($value); else Wind::log( '[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); else Wind::log( '[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) { Wind::log( "[core.WindModule.__clone] unexcepted value type or the property is not setted.(" . $value . ") need an object type in here. ", WindLogger::LEVEL_DEBUG, 'wind.core'); continue; } $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { Wind::log( '[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } if (!($_writeTableProperties = $this->writeTableForProperty())) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { if ($value instanceof $_writeTableProperties[$propertyName]) return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. ", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } return true; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); public function __construct($logDir = '', $writeType = 0) { $this->_logDir = $logDir; $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_INFO, $type); } public function trace($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_TRACE, $type); } public function debug($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_DEBUG, $type); } public function error($msg, $type = 'wind.core') { $this->log($msg, self::LEVEL_ERROR, $type); } public function profileBegin($msg, $type = 'wind.core') { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type); } public function profileEnd($msg, $type = 'wind.core') { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { $this->_types[] = $type; } } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { switch ($key) { case self::LEVEL_INFO: $key = 'info'; break; case self::LEVEL_ERROR: $key = 'error'; break; case self::LEVEL_DEBUG: $key = 'debug'; break; case self::LEVEL_TRACE: $key = 'trace'; break; case self::LEVEL_PROFILE: $key = 'profile'; break; default: $key = 'all'; break; } if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . " timer: " . sprintf('%0.5f', ($timer - DEBUG_TIME)) . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); if (isset($definition['constructorArgs'])) foreach ((array) $definition['constructorArgs'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); } if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (!is_string($alias) || empty($alias)) { throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException( '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { echo $errno,$errfile,'.....',$errline,'
'; if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $errsample = ''; if ($_errhtml && is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $errsample = implode("\n", $fileLines) . "\n"; } } if ($_errhtml) $errfile = "$file"; else $errfile = "$file"; $msg = "$errfile\n$errsample\n$errtrace\n"; } $msg .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; if ($_errhtml) { $msg = "$topic

$topic

$errmessage\n$msg
"; } else $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . '('; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { $this->getRequest()->setAttribute($value, $key); if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } }?> \ No newline at end of file From 561f11816fd3b2cb2ef20222b9ef0bb1e3ed717f Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 08:25:54 +0000 Subject: [PATCH 0346/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2416 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index f9a16dfc..a00252b3 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -421,7 +421,20 @@ private static function _loadBaseLib() { 'AbstractWindRoute' => 'router/route/AbstractWindRoute', 'WindRewriteRoute' => 'router/route/WindRewriteRoute', 'WindRoute' => 'router/route/WindRoute', 'WindRouter' => 'router/WindRouter', - 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter'); + 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter', + 'WindCookie' => 'http/cookie/WindCookie', + 'WindCookieObject' => 'http/cookie/WindCookieObject', + 'IWindRequest' => 'http/request/IWindRequest', + 'WindHttpRequest' => 'http/request/WindHttpRequest', + 'IWindResponse' => 'http/response/IWindResponse', + 'WindHttpResponse' => 'http/response/WindHttpResponse', + 'AbstractWindUserSession' => 'http/session/AbstractWindUserSession', + 'WindDbSession' => 'http/session/WindDbSession', + 'WindSession' => 'http/session/WindSession', + 'AbstractWindHttp' => 'http/transfer/AbstractWindHttp', + 'WindHttpCurl' => 'http/transfer/WindHttpCurl', + 'WindHttpSocket' => 'http/transfer/WindHttpSocket', + 'WindHttpStream' => 'http/transfer/WindHttpStream'); } } Wind::init(); From f1e814f7b4307596e09795e4817d16fae7c912e1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 08:38:33 +0000 Subject: [PATCH 0347/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2417 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 1 + 1 file changed, 1 insertion(+) diff --git a/_compile/compile.php b/_compile/compile.php index e90813b6..80375043 100644 --- a/_compile/compile.php +++ b/_compile/compile.php @@ -19,6 +19,7 @@ Wind::import('COM:utility.WindFile'); Wind::import('COM:utility.WindString'); Wind::import('COM:parser.WindConfigParser'); + /* 打包 */ $pack = new WindPack(); $fileList = array(); From 17e98831e0cbe0d101c92bece0f8386f11886395 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 09:57:12 +0000 Subject: [PATCH 0348/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2418 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 140 ++++++++++++++++-------------- 1 file changed, 74 insertions(+), 66 deletions(-) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index fba0a5d5..cfef3da2 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -104,7 +104,8 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) - $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); + $message = $this->_build($msg, $level, $type, microtime(true), + $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else @@ -122,7 +123,8 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { * @return boolean */ public function flush() { - if (empty($this->_logs)) return false; + if (empty($this->_logs)) + return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); if ($this->_writeType == self::WRITE_LEVEL) { @@ -152,7 +154,8 @@ public function flush() { $key = 'all'; break; } - if (!$fileName = $this->_getFileName($key)) continue; + if (!$fileName = $this->_getFileName($key)) + continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { @@ -162,7 +165,8 @@ public function flush() { $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { - if (!$fileName = $this->_getFileName($key)) continue; + if (!$fileName = $this->_getFileName($key)) + continue; WindFile::write($fileName, join("", $value), 'a'); } } @@ -214,7 +218,7 @@ private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: - $msg .= "\t(" . $type . " timer: " . sprintf('%0.5f', ($timer - DEBUG_TIME)) . ")\r\n"; + $msg .= "\t(" . $type . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: @@ -241,14 +245,15 @@ private function _buildProfile($msg, $type, $timer, $mem) { if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); - $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, - $timer, $mem); + $this->_profiles[] = array($_token, + substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { - if ($profile[0] !== $_token) continue; + if ($profile[0] !== $_token) + continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else @@ -328,71 +333,74 @@ private function _getTrace() { $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { - if ($num >= 7) break; - if ((isset($trace['class']) && $trace['class'] == __CLASS__) || - isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; - $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; - $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; - if ($function == 'WindBase::log') continue; - $args = array_map(array($this, '_buildArg'), $trace['args']); - $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; - } - return $info; + if ($num >= 7) + break; + if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( + $trace['file'], __CLASS__ . '.php') !== false) + continue; + $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; + $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; + if ($function == 'WindBase::log') + continue; + $args = array_map(array($this, '_buildArg'), $trace['args']); + $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } + return $info; + } - /** - * 组装输出的trace中的参数组装 - * @param mixed $arg - */ - private function _buildArg($arg) { - switch (gettype($arg)) { - case 'array': - return 'Array'; - break; - case 'object': - return 'Object ' . get_class($arg); - break; - default: - return "'" . $arg . "'"; - break; - } + /** + * 组装输出的trace中的参数组装 + * @param mixed $arg + */ + private function _buildArg($arg) { + switch (gettype($arg)) { + case 'array': + return 'Array'; + break; + case 'object': + return 'Object ' . get_class($arg); + break; + default: + return "'" . $arg . "'"; + break; } + } - /** - * 取得日志文件名 - * @return string - */ - private function _getFileName($suffix = '') { - $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; - $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; - if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { - $counter = 0; - do { - $counter++; - $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); - } while (is_file($_newFile)); - @rename($_logfile, $_newFile); - } - return $_logfile; + /** + * 取得日志文件名 + * @return string + */ + private function _getFileName($suffix = '') { + $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; + $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; + if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { + $counter = 0; + do { + $counter++; + $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); + } while (is_file($_newFile)); + @rename($_logfile, $_newFile); } + return $_logfile; + } - public function __destruct() { - $this->flush(); - } + public function __destruct() { + $this->flush(); + } - /** - * @param field_type $_logFile - */ - public function setLogDir($logDir) { - $this->_logDir = $logDir; - } + /** + * @param field_type $_logFile + */ + public function setLogDir($logDir) { + $this->_logDir = $logDir; + } - /** - * @param field_type $_maxFileSize - */ - public function setMaxFileSize($maxFileSize) { - $this->_maxFileSize = (int) $maxFileSize; - } - } + /** + * @param field_type $_maxFileSize + */ + public function setMaxFileSize($maxFileSize) { + $this->_maxFileSize = (int) $maxFileSize; + } +} \ No newline at end of file From 1350363a3f033b81f907207bdbc4c7b3e79c578f Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 09:59:20 +0000 Subject: [PATCH 0349/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2419 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindModule.php | 54 +--------------------------- wind/core/factory/WindFactory.php | 4 --- wind/core/web/WindWebApplication.php | 7 ++++ 3 files changed, 8 insertions(+), 57 deletions(-) diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 5ce3bbc4..4dd51521 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -36,10 +36,6 @@ public function __set($propertyName, $value) { $_setter = 'set' . ucfirst($propertyName); if (method_exists($this, $_setter)) $this->$_setter($value); - else - Wind::log( - '[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, - WindLogger::LEVEL_DEBUG, 'wind.core'); } /** @@ -52,10 +48,6 @@ public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); - else - Wind::log( - '[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, - WindLogger::LEVEL_DEBUG, 'wind.core'); } /** @@ -98,13 +90,8 @@ public function __call($methodName, $args) { */ public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { - if (!is_object($this->$value) || !isset($this->$value)) { - Wind::log( - "[core.WindModule.__clone] unexcepted value type or the property - is not setted.(" . $value . ") need an object type in here. - ", WindLogger::LEVEL_DEBUG, 'wind.core'); + if (!is_object($this->$value) || !isset($this->$value)) continue; - } $this->$value = clone $this->$value; } } @@ -125,45 +112,6 @@ public function toArray() { return $_result; } - /** - * 验证白名单是否为空,或属性值是否存在于定义的白名单中 - * @deprecated - * @param string $propertyName - * @return boolean - */ - protected function validatePropertyName($propertyName, $value = null) { - if (isset($this->delayAttributes[$propertyName])) { - Wind::log( - '[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', - WindLogger::LEVEL_DEBUG, 'wind.core'); - return true; - } - if (!($_writeTableProperties = $this->writeTableForProperty())) { - Wind::log( - "[core.WindModule.validatePropertyName] - writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); - return false; - } - if (!array_key_exists($propertyName, $_writeTableProperties)) { - Wind::log( - "[core.WindModule.validatePropertyName] - writeTableForProperty is empty or your input is not exists. - (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); - return false; - } - if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { - if ($value instanceof $_writeTableProperties[$propertyName]) - return true; - Wind::log( - "[core.WindModule.validatePropertyName] - type of the property " . $propertyName . " is not defined. - ", WindLogger::LEVEL_DEBUG, 'wind.core'); - return false; - } - return true; - } - /** * 根据配置名取得相应的配置 * diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index ca751cbc..5acba900 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -80,10 +80,6 @@ public function registInstance($instance, $alias, $scope = 'singleton') { */ static public function createInstance($className, $args = array()) { try { - if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { - Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, - WindLogger::LEVEL_DEBUG, 'core.factory'); - } if (empty($args)) { return new $className(); } else { diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index dc9d5490..a78c277d 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -247,6 +247,13 @@ public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } + /** + * @return WindLogger + */ + public function getLogger() { + return $this->windFactory->getInstance('windLogger'); + } + /** * @return WindHttpRequest $request */ From db284ea0570272f63a17036b27effecf6ebcf7ff Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 09:59:34 +0000 Subject: [PATCH 0350/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2420 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/parser/WindConfigParser.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php index 01d7807e..624dae50 100644 --- a/wind/component/parser/WindConfigParser.php +++ b/wind/component/parser/WindConfigParser.php @@ -5,7 +5,6 @@ * 配置文件格式允许有4中格式:xml, php, properties, ini * * 根据用户传入的配置文件所在位置解析配置文件, - * 并将生成的配置缓存文件, 以php格式默认放在‘COMPILE_PATH’下面 * * the last known user to change this file in the repository <$LastChangedBy$> * @author xiaoxia xu From 15b4e45e8265b2cf8ba41912b75d9d6906bf6c71 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 10:00:36 +0000 Subject: [PATCH 0351/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2421 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 52 --------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index a00252b3..10f14a56 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -5,14 +5,8 @@ /* 路径相关配置信息 */ define('D_S', DIRECTORY_SEPARATOR); define('WIND_PATH', dirname(__FILE__) . D_S); -!defined('COMPILE_PATH') && define('COMPILE_PATH', WIND_PATH . D_S); - /* debug/log */ !defined('IS_DEBUG') && define('IS_DEBUG', 1); -!defined('LOG_DIR') && define('LOG_DIR', COMPILE_PATH . 'log'); -!defined('LOG_WRITE_LEVEL') && define('LOG_WRITE_LEVEL', 0); -define('DEBUG_TIME', microtime(true)); - /** * the last known user to change this file in the repository <$LastChangedBy: yishuo $> * @author Qiong Wu @@ -23,7 +17,6 @@ class Wind { private static $_components = 'WIND:components_config'; private static $_extensions = 'php'; private static $_isAutoLoad = true; - private static $_logger = null; private static $_namespace = array(); private static $_imports = array(); private static $_classes = array(); @@ -257,51 +250,6 @@ public static function init() { self::_loadBaseLib(); } - /** - * @param string $message - * @param int $level - */ - public static function log($message, $level = WindLogger::LEVEL_INFO, $type = 'wind.core') { - if (IS_DEBUG && $level >= IS_DEBUG && $level != WindLogger::LEVEL_PROFILE) { - self::getLogger()->log($message, $level, $type); - } - } - - /** - * @param $token - * @param $message - * @param $type - */ - public static function profileBegin($token, $message = '', $type = 'wind.core') { - if (IS_DEBUG && WindLogger::LEVEL_PROFILE >= IS_DEBUG) { - $msg = $token . ':' . $message; - self::getLogger()->profileBegin($msg, $type); - } - } - - /** - * @param $token - * @param $message - * @param $type - */ - public static function profileEnd($token, $message = '', $type = 'wend.core') { - if (IS_DEBUG && WindLogger::LEVEL_PROFILE >= IS_DEBUG) { - $msg = $token . ':' . $message; - self::getLogger()->profileEnd($msg, $type); - } - } - - /** - * 返回系统日志对象 - * @return WindLogger - */ - public static function getLogger() { - if (self::$_logger === null) { - self::$_logger = new WindLogger(LOG_DIR, LOG_WRITE_LEVEL); - } - return self::$_logger; - } - /** * 清理Wind import变量信息 * @return From 0efe0962228eaff3bcf93a185f9c139853e196bb Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 10:00:46 +0000 Subject: [PATCH 0352/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2422 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/wind/components_config.php b/wind/components_config.php index a49b89cc..8dd52bd3 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -11,9 +11,13 @@ ), ), ), + 'windLog' => array( + 'path' => 'COM:log.WindLogger', + 'scope' => 'application', + ), 'dispatcher' => array( 'path' => 'WIND:core.web.WindDispatcher', - 'scope' => 'prototype', + 'scope' => 'application', 'properties' => array( 'urlHelper' => array( 'ref' => 'urlHelper', @@ -26,7 +30,7 @@ ), 'router' => array( 'path' => 'COM:router.WindRouter', - 'scope' => 'prototype', + 'scope' => 'application', ), 'urlRewriteRouter' => array( 'path' => 'COM:router.WindUrlRewriteRouter', @@ -34,7 +38,7 @@ ), 'urlHelper' => array( 'path' => 'WIND:core.web.WindUrlHelper', - 'scope' => 'singleton', + 'scope' => 'application', ), 'windView' => array( 'path' => 'COM:viewer.WindView', From 5cb6036ca67c52e2ca9c7a440f0e0c72174748cd Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 10:01:44 +0000 Subject: [PATCH 0353/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2423 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 10f14a56..2c39b07d 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -275,8 +275,6 @@ protected static function beforRun($appName, $config, $rootPath) { protected static function afterRun() { array_pop(self::$_currentApp); self::$_currentAppName = end(self::$_currentApp); - if (self::$_logger) - self::$_logger->flush(); } /** From b8fd0b5f6f8d52b2d1d1c3ee182900a8c05c1133 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 10:21:43 +0000 Subject: [PATCH 0354/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2424 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDaoFactory.php | 3 --- wind/component/viewer/WindView.php | 3 +++ wind/component/viewer/WindViewerResolver.php | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index 64728594..0bf4d1f5 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -49,9 +49,6 @@ public function getDao($className) { $this->createCacheHandler($daoInstance); return $daoInstance; } catch (Exception $exception) { - Wind::log( - '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . $exception->getMessage(), - WindLogger::LEVEL_DEBUG, 'wind.component'); throw new WindDaoException( '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . $exception->getMessage()); } diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 5fa92e79..6cf7015a 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -141,6 +141,9 @@ public function getCompileFile($template = '') { if (!$this->compileDir) return; !$template && $template = $this->templateName; $dir = Wind::getRealDir($this->compileDir); + if (!is_dir($dir)) + throw new WindViewException( + '[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); $_tmp = explode('.', $template); foreach ($_tmp as $_dir) { !is_dir($dir) && @mkdir($dir); diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index d8d91ebf..63ae67f2 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -64,17 +64,15 @@ public function windAssign($vars, $key = '') { */ public function compile($template, $suffix = '', $output = false) { $templateFile = $this->windView->getViewTemplate($template, $suffix); - if (!is_file($templateFile)) { + if (!is_file($templateFile)) throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, WindViewException::VIEW_NOT_EXIST); - } if (!($compileFile = $this->windView->getCompileFile($template))) return array($templateFile, ''); /* @var $_windTemplate WindViewTemplate */ $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); $_output = $_windTemplate->compile($templateFile, $this); - if (!$compileFile && !$_output) return array('', ''); WindFile::write($compileFile, $_output); From 907ae3e9d6b3d2792bee773c47b87abeb87dbfec Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 10:21:53 +0000 Subject: [PATCH 0355/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2425 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindHelper.php | 2 +- wind/core/web/WindWebApplication.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php index 59318bf0..2175c327 100644 --- a/wind/core/WindHelper.php +++ b/wind/core/WindHelper.php @@ -120,8 +120,8 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { $msg = "$topic

$topic

$errmessage\n$msg
"; } else $msg = "$topic\n$errmessage\n$msg"; - ob_end_clean(); + $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); die($msg); } diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index a78c277d..9508c578 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -61,6 +61,7 @@ public function run() { restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); + Wind::resetApp(); } /* (non-PHPdoc) From da09a7daffa269ca7beada8e927f9ddfd7a9edf4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 10:22:02 +0000 Subject: [PATCH 0356/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2426 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 2c39b07d..d0ab461a 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -31,8 +31,12 @@ class Wind { * @param string $rootPath * @return IWindApplication */ - public static function run($appName = 'default', $config = array(), $rootPath = '') { - self::beforRun($appName, $config, $rootPath); + public static function application($appName = 'default', $config = array(), $rootPath = '') { + //self::beforRun($appName, $config, $rootPath); + if (!$appName || in_array($appName, self::$_currentApp)) + throw new WindException('Nested request', WindException::ERROR_SYSTEM_ERROR); + array_push(self::$_currentApp, $appName); + self::$_currentAppName = $appName; if (!isset(self::$_app[$appName])) { Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, true); @@ -49,8 +53,7 @@ public static function run($appName = 'default', $config = array(), $rootPath = Wind::register($rootPath, $appName, true); self::$_app[$appName] = $application; } - self::getApp()->run(); - self::afterRun(); + return self::$_app[$appName]; } /** @@ -77,6 +80,14 @@ public static function getApp() { WindException::ERROR_CLASS_NOT_EXIST); } + /** + * @return + */ + public static function resetApp() { + array_pop(self::$_currentApp); + self::$_currentAppName = end(self::$_currentApp); + } + /** * 加载一个类或者加载一个包 * 如果加载的包中有子文件夹不进行循环加载 @@ -269,14 +280,6 @@ protected static function beforRun($appName, $config, $rootPath) { self::$_currentAppName = $appName; } - /** - * @return - */ - protected static function afterRun() { - array_pop(self::$_currentApp); - self::$_currentAppName = end(self::$_currentApp); - } - /** * 系统命名空间注册方法 * @return From e5116d7114cd1fc22657d1967b7d64edae2060c3 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 10:25:45 +0000 Subject: [PATCH 0357/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2427 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/components_config.php | 10 +++++++--- _compile/config/components_config.xml | 25 ++++++++++--------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/_compile/components_config.php b/_compile/components_config.php index a49b89cc..8dd52bd3 100644 --- a/_compile/components_config.php +++ b/_compile/components_config.php @@ -11,9 +11,13 @@ ), ), ), + 'windLog' => array( + 'path' => 'COM:log.WindLogger', + 'scope' => 'application', + ), 'dispatcher' => array( 'path' => 'WIND:core.web.WindDispatcher', - 'scope' => 'prototype', + 'scope' => 'application', 'properties' => array( 'urlHelper' => array( 'ref' => 'urlHelper', @@ -26,7 +30,7 @@ ), 'router' => array( 'path' => 'COM:router.WindRouter', - 'scope' => 'prototype', + 'scope' => 'application', ), 'urlRewriteRouter' => array( 'path' => 'COM:router.WindUrlRewriteRouter', @@ -34,7 +38,7 @@ ), 'urlHelper' => array( 'path' => 'WIND:core.web.WindUrlHelper', - 'scope' => 'singleton', + 'scope' => 'application', ), 'windView' => array( 'path' => 'COM:viewer.WindView', diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index 97486198..632e69cb 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -8,7 +8,6 @@ - @@ -16,26 +15,28 @@ + + + + + + + scope='application'> - - - - + + + scope='application'> - - template @@ -55,17 +56,12 @@ - - - - - compile @@ -87,5 +83,4 @@ 10 - From a60850762f87d5a59aed8acb061580f8e2e467f0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 10:26:03 +0000 Subject: [PATCH 0358/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2428 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/readme | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 _compile/readme diff --git a/_compile/readme b/_compile/readme new file mode 100644 index 00000000..e69de29b From 6815a365bc9e26ba345b1ebbdc6751044c7c6da7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 11:36:18 +0000 Subject: [PATCH 0359/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2429 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/readme | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_compile/readme b/_compile/readme index e69de29b..628cc6a4 100644 --- a/_compile/readme +++ b/_compile/readme @@ -0,0 +1,2 @@ +运行: +compile.php From 862f7943920335ab716e78d89fda678548e8297d Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 22 Aug 2011 11:37:47 +0000 Subject: [PATCH 0360/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2430 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wind/Wind.php b/wind/Wind.php index d0ab461a..7e59e818 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -2,9 +2,11 @@ /* 框架版本信息 */ define('VERSION', '0.5.0'); define('PHPVERSION', '5.1.2'); + /* 路径相关配置信息 */ define('D_S', DIRECTORY_SEPARATOR); define('WIND_PATH', dirname(__FILE__) . D_S); + /* debug/log */ !defined('IS_DEBUG') && define('IS_DEBUG', 1); /** From 1fda5e881e111f9b439addcc5258235dc54feddb Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 03:45:12 +0000 Subject: [PATCH 0361/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2431 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 5acba900..05ef0ed7 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -40,8 +40,6 @@ public function getInstance($alias, $args = array()) { if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; - if (!isset($definition['className'])) - $definition['className'] = Wind::import(@$definition['path']); if (isset($definition['constructorArgs'])) foreach ((array) $definition['constructorArgs'] as $_var) { if (isset($_var['value'])) { @@ -49,6 +47,8 @@ public function getInstance($alias, $args = array()) { } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } + if (!isset($definition['className'])) + $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); From 713d5d9081c7943aa094f94519394a768c2acce1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 03:45:23 +0000 Subject: [PATCH 0362/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2432 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/AbstractWindRouter.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wind/component/router/AbstractWindRouter.php b/wind/component/router/AbstractWindRouter.php index 218b4d4d..536b8458 100644 --- a/wind/component/router/AbstractWindRouter.php +++ b/wind/component/router/AbstractWindRouter.php @@ -53,13 +53,15 @@ public function setConfig($config) { */ protected function setParams($params) { foreach ($params as $key => $value) { - $this->getRequest()->setAttribute($value, $key); if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); + else { + $this->getRequest()->setAttribute($value, $key); + } } } From c5d6824c47ee1cfe699179a5c242b75858fc24ff Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 03:47:05 +0000 Subject: [PATCH 0363/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2433 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/filter/WindFilterChain.php | 63 ------------- .../filter/WindHandlerInterceptorChain.php | 88 ------------------- 2 files changed, 151 deletions(-) delete mode 100644 wind/component/filter/WindFilterChain.php delete mode 100644 wind/component/filter/WindHandlerInterceptorChain.php diff --git a/wind/component/filter/WindFilterChain.php b/wind/component/filter/WindFilterChain.php deleted file mode 100644 index 5deb89ac..00000000 --- a/wind/component/filter/WindFilterChain.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindFilterChain extends WindHandlerInterceptorChain { - - /** - * @param array $filterConfig - */ - public function __construct($filterConfig) { - $this->_initFilters($filterConfig); - } - - /** - * @param string $filterName - */ - public function deleteFilter($alias) { - unset($this->_interceptors[$alias]); - } - - /** - * 在filter链中动态的添加一个filter - * 当befor为空时,添加到程序结尾处 - * 如果befor有值,则遍历数组,找到befor的位置,将新的过滤器添加到befor后面, - * 并将所有原befor位置后的过滤器往后移一位 - * - * @param string $filterName - * @param string $path - * @param string $beforFilter - */ - public function addFilter($filter, $beforFilter = '') { - if ($beforFilter === '') { - $this->addInterceptors(array(get_class($filter) => $filter)); - return true; - } - $_interceptors = array(); - foreach ($this->_interceptors as $key => $interceptor) { - if ($beforFilter === $key) break; - $_interceptors[$key] = $interceptor; - unset($this->_interceptors[$key]); - } - $_interceptors[get_class($filter)] = $filter; - $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; - } - - /** - * @param array $filters - */ - private function _initFilters($filters = array()) { - $_temp = array(); - foreach ((array) $filters as $key => $filter) { - if (!is_array($filter)) continue; - $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); - if (!class_exists($filterClass)) continue; - $_temp[$key] = new $filterClass(); - } - $this->addInterceptors($_temp); - } - -} \ No newline at end of file diff --git a/wind/component/filter/WindHandlerInterceptorChain.php b/wind/component/filter/WindHandlerInterceptorChain.php deleted file mode 100644 index b2f7761d..00000000 --- a/wind/component/filter/WindHandlerInterceptorChain.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHandlerInterceptorChain extends WindModule { - protected $_interceptors = array(); - protected $_callBack = null; - protected $_args = array(); - protected $_state = 0; - - /** - * 设置回调方法 - * - * @param string|array $callBack - * @param array $args - * @return - */ - public function setCallBack($callBack, $args = array()) { - $this->_callBack = $callBack; - $this->_args = $args; - } - - /** - * 执行callback方法 - * - * @throws WindException - * @return void|mixed - */ - public function execute() { - if ($this->_callBack === null) - return null; - if (is_string($this->_callBack) && !function_exists($this->_callBack)) { - throw new WindException( - '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, - WindException::ERROR_FUNCTION_NOT_EXIST); - } - return call_user_func_array($this->_callBack, (array) $this->_args); - } - - /** - * 返回处理句柄 - * - * @return WindHandlerInterceptor - */ - public function getHandler() { - if (count($this->_interceptors) <= 0) { - $this->addInterceptors(new WindHandlerInterceptor()); - } - if ($this->_state >= count($this->_interceptors)) - return null; - $handler = $this->_interceptors[$this->_state++]; - if ($handler instanceof WindHandlerInterceptor) { - $handler->setHandlerInterceptorChain($this); - return $handler; - } - return $this->getHandler(); - } - - /** - * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 - * - * @param $interceptors - * @return - */ - public function addInterceptors($interceptors) { - if (is_array($interceptors)) - $this->_interceptors += $interceptors; - else - $this->_interceptors[] = $interceptors; - } - - /** - * 重置初始化信息 - * @return boolean - */ - public function reset() { - $this->_interceptors = array(); - $this->_callBack = null; - $this->_args = array(); - $this->_state = 0; - return true; - } -} -?> \ No newline at end of file From 2108da56cb7339607781b0e1eac3100073ffd8f3 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 07:12:14 +0000 Subject: [PATCH 0364/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2434 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindView.php | 9 +++- wind/component/viewer/WindViewerResolver.php | 21 +++++---- .../compiler/WindTemplateCompilerEcho.php | 44 ++++--------------- .../compiler/WindTemplateCompilerTemplate.php | 34 +++++++------- 4 files changed, 48 insertions(+), 60 deletions(-) diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 6cf7015a..8f9eb96d 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -124,7 +124,11 @@ public function setConfig($config) { * @return string | false */ public function getViewTemplate($template = '', $ext = '') { - !$template && $template = $this->templateName; + if ($template) { + if (is_file($template)) + return $template; + } else + $template = $this->templateName; !$ext && $ext = $this->templateExt; return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); } @@ -138,7 +142,8 @@ public function getViewTemplate($template = '', $ext = '') { * @return string | false */ public function getCompileFile($template = '') { - if (!$this->compileDir) return; + if (!$this->compileDir) + return; !$template && $template = $this->templateName; $dir = Wind::getRealDir($this->compileDir); if (!is_dir($dir)) diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index 63ae67f2..c63c6948 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -53,10 +53,14 @@ public function windAssign($vars, $key = '') { if ($key === '') $key = $this->windView->templateName; $this->vars[$key] = $vars; + Wind::getApp()->getResponse()->setData($vars, $key); } /** - * 编译模板并返回编译后模板名称 + * 编译模板并返回编译后模板名称, + * $output==true: 直接返回编译结果,不将结果写入编译文件中 + * $output==false:返回编译文件地址 + * * @param string $template * @param string $suffix * @param boolean $output @@ -67,16 +71,17 @@ public function compile($template, $suffix = '', $output = false) { if (!is_file($templateFile)) throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, WindViewException::VIEW_NOT_EXIST); - if (!($compileFile = $this->windView->getCompileFile($template))) - return array($templateFile, ''); /* @var $_windTemplate WindViewTemplate */ $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); $_output = $_windTemplate->compile($templateFile, $this); - if (!$compileFile && !$_output) - return array('', ''); - WindFile::write($compileFile, $_output); - return array($compileFile, $_output); + if ($output === true) + return array('', $_output); + else { + $compileFile = $this->windView->getCompileFile($template); + WindFile::write($compileFile, $_output); + return array($compileFile, $_output); + } } /** @@ -84,7 +89,7 @@ public function compile($template, $suffix = '', $output = false) { * @param template */ protected function render($template) { - list($_tmp, $_output) = $this->compile($template); + list($_tmp) = $this->compile($template); /*$_var = Wind::getApp()->getResponse()->getData('G'); if (isset($this->vars[$template])) $_var += $this->vars[$template];*/ diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index ca900b8f..0f4a0d41 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -20,42 +20,16 @@ class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { */ public function compile($key, $content) { $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content); - list($_output, $type) = $this->doCompile($_output); - if ($this->windViewerResolver->getWindView()->htmlspecialchars === true && $type == 'text') - return ''; - else + list($_output, $type) = explode('|', $_output . '|'); + if (strpos($_output, ':') !== false) { + list($_namespace, $_var) = explode(':', $_output); + $_output = 'Wind::getApp()->getResponse()->getData(\'' . $_namespace . '\', \'' . $_var . '\')'; + } + if ($this->windViewerResolver->getWindView()->htmlspecialchars === false || strcasecmp( + $type, 'html')) return ''; - } - - /** - * 处理变量 - * @param string $var - * @return array - */ - private function doCompile($var) { - $vars = explode('|', $var, 2); - $type = isset($vars[1]) ? strtolower($vars[1]) : 'text'; - !in_array($type, $this->getType()) && $type = 'text'; - return array($this->compileVarShare($vars[0]), $type); - } - - /** - * @param string $input - * @return string - */ - private function compileVarShare($input) { - if (strpos($input, '$') !== false || strpos($input, '::') !== false || strpos($input, ':') === false) - return $input; - list($templateName, $var) = explode(':', $input); - return 'Wind::getApp()->getResponse()->getData(\'' . $templateName . '\', \'' . $var . '\')'; - } - - /** - * 获得变量后的|之后的值 - * @return array - */ - private function getType() { - return array('html', 'text'); + else + return ''; } } ?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php index f78712f0..81bdb2ba 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php @@ -1,6 +1,11 @@ + * source: 模板文件源地址 + * suffix: 模板文件后缀 + * load: 是否将编译内容加载到本模板中 + * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ @@ -13,26 +18,25 @@ class WindTemplateCompilerTemplate extends AbstractWindTemplateCompiler { protected $suffix = ''; protected $load = 'true'; - - protected $includeFiles = ''; /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() */ public function compile($key, $content) { - if (!isset($this->source)) return $content; - preg_match('/[\$\(\/\\]]/i', $this->source, $result); - if (empty($result)) { - if ($this->load === 'false') { - list($_tmp) = $this->windViewerResolver->compile($this->source, $this->suffix); - $content = ''; - } else { - list($compileFile, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, true); - $this->includeFiles .= $this->source . ':' . filemtime($compileFile) . ' '; - } - } else - $content = 'source . '); ?>'; - + if (!isset($this->source)) + return $content; + preg_match('/^{?\$(\w+)}?$/Ui', trim($this->source), $result); + if (!empty($result)) { + $_tpl = $this->windViewerResolver->getWindView()->templateName; + $this->source = Wind::getApp()->getResponse()->getData($_tpl, $result[1]); + } + //TODO 暂时不支持 load 参数 默认全部以load模式加载子模板 + /*if ($this->load === 'false') { + list($compileFile) = $this->windViewerResolver->compile($this->source, $this->suffix); + $content = ''; + } else { + }*/ + list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, true); return $content; } From b116866e4c0b12bcfd9d3b6a6f1539e2889cb897 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 07:12:26 +0000 Subject: [PATCH 0365/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2435 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindHelper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php index 2175c327..003ba2a2 100644 --- a/wind/core/WindHelper.php +++ b/wind/core/WindHelper.php @@ -19,7 +19,6 @@ class WindHelper { * @param string $errline */ public static function errorHandle($errno, $errstr, $errfile, $errline) { - echo $errno,$errfile,'.....',$errline,'
'; if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); From df4f2bba9f63747f6332d2a98b1b25c7f5807ed5 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 07:16:59 +0000 Subject: [PATCH 0366/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20=E5=90=AF=E5=8A=A8=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=AD=96=E7=95=A5=E6=9C=BA=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=A0=BC=E5=BC=8F=E5=85=BC=E5=AE=B9component?= =?UTF-8?q?s=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2436 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/AbstractWindTemplateCompiler.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/component/viewer/AbstractWindTemplateCompiler.php b/wind/component/viewer/AbstractWindTemplateCompiler.php index c25ddf26..21f28ff3 100644 --- a/wind/component/viewer/AbstractWindTemplateCompiler.php +++ b/wind/component/viewer/AbstractWindTemplateCompiler.php @@ -1,5 +1,4 @@ Date: Tue, 23 Aug 2011 07:17:41 +0000 Subject: [PATCH 0367/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20WindTemplateCompilerEcho?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2437 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/compiler/WindTemplateCompilerEcho.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index 0f4a0d41..c0810f87 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -18,7 +18,7 @@ class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() */ - public function compile($key, $content) { + public function compile($key, $content) { $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content); list($_output, $type) = explode('|', $_output . '|'); if (strpos($_output, ':') !== false) { From 128d6579d5e5068add85f1f1021b61a1d7a24db6 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 07:21:05 +0000 Subject: [PATCH 0368/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20WindTemplateCompilerTemplate=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=8F=82=E6=95=B0=EF=BC=8C=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E9=9D=9Eload=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2438 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/compiler/WindTemplateCompilerTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php index 81bdb2ba..5b7c0ac2 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php @@ -26,7 +26,7 @@ public function compile($key, $content) { if (!isset($this->source)) return $content; preg_match('/^{?\$(\w+)}?$/Ui', trim($this->source), $result); - if (!empty($result)) { + if (!empty($result)) { $_tpl = $this->windViewerResolver->getWindView()->templateName; $this->source = Wind::getApp()->getResponse()->getData($_tpl, $result[1]); } From b58b7cce1c6da41585a1dfd8ef307f89a36e3563 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 07:51:28 +0000 Subject: [PATCH 0369/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20WindTemplateCompilerTemplate=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=8F=82=E6=95=B0=EF=BC=8C=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E9=9D=9Eload=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2439 18ba2127-5a84-46d4-baec-3457e417f034 --- .../viewer/compiler/WindTemplateCompilerEcho.php | 5 ++--- .../compiler/WindTemplateCompilerTemplate.php | 13 ++++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index c0810f87..93477c47 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -18,15 +18,14 @@ class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() */ - public function compile($key, $content) { + public function compile($key, $content) { $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content); list($_output, $type) = explode('|', $_output . '|'); if (strpos($_output, ':') !== false) { list($_namespace, $_var) = explode(':', $_output); $_output = 'Wind::getApp()->getResponse()->getData(\'' . $_namespace . '\', \'' . $_var . '\')'; } - if ($this->windViewerResolver->getWindView()->htmlspecialchars === false || strcasecmp( - $type, 'html')) + if (!strcasecmp($type, 'html')) return ''; else return ''; diff --git a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php index 5b7c0ac2..08585248 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php @@ -18,6 +18,8 @@ class WindTemplateCompilerTemplate extends AbstractWindTemplateCompiler { protected $suffix = ''; protected $load = 'true'; + + protected $getVar = true; /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() @@ -25,18 +27,19 @@ class WindTemplateCompilerTemplate extends AbstractWindTemplateCompiler { public function compile($key, $content) { if (!isset($this->source)) return $content; - preg_match('/^{?\$(\w+)}?$/Ui', trim($this->source), $result); + /*preg_match('/^{?\$(\w+)}?$/Ui', trim($this->source), $result); if (!empty($result)) { $_tpl = $this->windViewerResolver->getWindView()->templateName; $this->source = Wind::getApp()->getResponse()->getData($_tpl, $result[1]); - } + }*/ //TODO 暂时不支持 load 参数 默认全部以load模式加载子模板 - /*if ($this->load === 'false') { + if ($this->load === 'false') { list($compileFile) = $this->windViewerResolver->compile($this->source, $this->suffix); $content = ''; } else { - }*/ - list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, true); + list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, + true); + } return $content; } From b4c9e7ffbb815a7db8cc62a917bd86855c5c401b Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 07:51:38 +0000 Subject: [PATCH 0370/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20WindTemplateCompilerTemplate=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=8F=82=E6=95=B0=EF=BC=8C=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E9=9D=9Eload=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2440 18ba2127-5a84-46d4-baec-3457e417f034 --- .../viewer/AbstractWindTemplateCompiler.php | 26 +++++++++++++++---- wind/component/viewer/WindView.php | 14 ++++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/wind/component/viewer/AbstractWindTemplateCompiler.php b/wind/component/viewer/AbstractWindTemplateCompiler.php index 21f28ff3..b64b1b3b 100644 --- a/wind/component/viewer/AbstractWindTemplateCompiler.php +++ b/wind/component/viewer/AbstractWindTemplateCompiler.php @@ -24,6 +24,8 @@ abstract class AbstractWindTemplateCompiler extends WindHandlerInterceptor { protected $request = null; protected $response = null; + + protected $getVar = false; /** * 初始化标签解析器 @@ -73,9 +75,21 @@ protected function getProperties() { */ protected function compileProperty($content) { foreach ($this->getProperties() as $value) { - if (!$value) continue; - preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', $content, $result); - if ($result) $this->$value = trim(str_replace($result[1], '', $result[0])); + if (!$value) + continue; + preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', + $content, $result); + if (!$result) + continue; + $result = trim(str_replace($result[1], '', $result[0])); + if ($this->getVar) { + preg_match('/^{?\$(\w+)}?$/Ui', $result, $_tmp); + if (!empty($_tmp)) { + $_tpl = $this->windViewerResolver->getWindView()->templateName; + $result = Wind::getApp()->getResponse()->getData($_tpl, $_tmp[1]); + } + } + $this->$value = $result; } } @@ -83,10 +97,12 @@ protected function compileProperty($content) { * @see WindHandlerInterceptor::preHandle() */ public function preHandle() { - if ($this->windViewTemplate === null) return; + if ($this->windViewTemplate === null) + return; $this->preCompile(); foreach ($this->tags as $key => $value) { - if (!$value[0] || !$value[1]) continue; + if (!$value[0] || !$value[1]) + continue; $this->compileProperty($value[1]); $_output = $this->compile($value[0], $value[1]); $this->windViewTemplate->setCompiledBlockData($value[0], $_output); diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 8f9eb96d..3f630c98 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -124,11 +124,10 @@ public function setConfig($config) { * @return string | false */ public function getViewTemplate($template = '', $ext = '') { - if ($template) { - if (is_file($template)) - return $template; - } else + if (!$template) { $template = $this->templateName; + } elseif (is_file($template)) + return $template; !$ext && $ext = $this->templateExt; return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); } @@ -144,7 +143,12 @@ public function getViewTemplate($template = '', $ext = '') { public function getCompileFile($template = '') { if (!$this->compileDir) return; - !$template && $template = $this->templateName; + if (!$template) { + $template = $this->templateName; + } elseif (is_file($template)) { + $_info = pathinfo($template); + $template = $_info['filename']; + } $dir = Wind::getRealDir($this->compileDir); if (!is_dir($dir)) throw new WindViewException( From d864183d48e3a3075d111f5767d2caceffda379a Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 07:51:52 +0000 Subject: [PATCH 0371/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20WindTemplateCompilerTemplate=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=8F=82=E6=95=B0=EF=BC=8C=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E9=9D=9Eload=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2441 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 9508c578..5ef72c88 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -140,9 +140,9 @@ public function processRequest() { protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) - throw new WindException( - '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); + throw new WindException($exception->getMessage()); + $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { From 6dcd5c372e22583d9cef711bc8d2b144fac7c9da Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 07:52:40 +0000 Subject: [PATCH 0372/1065] =?UTF-8?q?bug=20fixed:=20=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E6=9C=AA=E5=A3=B0=E6=98=8E=E9=94=99=E8=AF=AF=EF=BC=8C=20errorm?= =?UTF-8?q?essage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2442 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 5ef72c88..8a324ea8 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -137,7 +137,7 @@ public function processRequest() { * @param WindActionException actionException * @return */ - protected function sendErrorMessage($exception) { + protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException($exception->getMessage()); From 5fb993b6d14eb84587ce61710b7093ff630361a5 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:30:41 +0000 Subject: [PATCH 0373/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9AWindLogger=20=E6=94=AF=E6=8C=81=20wind=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E6=A0=BC=E5=BC=8F=E5=8F=82=E6=95=B0,=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=8A=A8flush=E5=92=8C=E6=89=8B=E5=8A=A8flus?= =?UTF-8?q?h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2443 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 63 +++++++++++++------------------ 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index cfef3da2..6d6c4613 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -12,11 +12,11 @@ class WindLogger extends WindModule { const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; - const TOKEN_BEGIN = 'begin:'; - const TOKEN_END = 'end:'; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; + const TOKEN_BEGIN = 'begin:'; + const TOKEN_END = 'end:'; /** * 每次当日志数量达到100的时候,就写入文件一次 * @var int @@ -35,13 +35,14 @@ class WindLogger extends WindModule { */ private $_writeType = '0'; private $_types = array(); + private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); /** * @param string $logDir * @param int $writeType */ public function __construct($logDir = '', $writeType = 0) { - $this->_logDir = $logDir; + $this->setLogDir($logDir); $this->_writeType = $writeType; } @@ -49,48 +50,48 @@ public function __construct($logDir = '', $writeType = 0) { * 添加info级别的日志信息 * @param string $msg */ - public function info($msg, $type = 'wind.system') { - $this->log($msg, self::LEVEL_INFO, $type); + public function info($msg, $type = 'wind.system', $flush = false) { + $this->log($msg, self::LEVEL_INFO, $type, $flush); } /** * 添加trace级别的日志信息 * @param string $msg */ - public function trace($msg, $type = 'wind.system') { - $this->log($msg, self::LEVEL_TRACE, $type); + public function trace($msg, $type = 'wind.system', $flush = false) { + $this->log($msg, self::LEVEL_TRACE, $type, $flush); } /** * 添加debug的日志信息 * @param string $msg */ - public function debug($msg, $type = 'wind.system') { - $this->log($msg, self::LEVEL_DEBUG, $type); + public function debug($msg, $type = 'wind.system', $flush = false) { + $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } /** * 添加Error级别的日志信息 * @param string $msg */ - public function error($msg, $type = 'wind.core') { - $this->log($msg, self::LEVEL_ERROR, $type); + public function error($msg, $type = 'wind.core', $flush = false) { + $this->log($msg, self::LEVEL_ERROR, $type, $flush); } /** * @param $msg * @param $type */ - public function profileBegin($msg, $type = 'wind.core') { - $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type); + public function profileBegin($msg, $type = 'wind.core', $flush = false) { + $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } /** * @param $msg * @param $type */ - public function profileEnd($msg, $type = 'wind.core') { - $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type); + public function profileEnd($msg, $type = 'wind.core', $flush = false) { + $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } /** @@ -98,7 +99,7 @@ public function profileEnd($msg, $type = 'wind.core') { * @param string $msg 日志信息 * @param const $logType 日志类别 */ - public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { + public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else @@ -115,6 +116,8 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { $this->_types[] = $type; } + if ($flush) + $this->flush(); } /** @@ -127,6 +130,9 @@ public function flush() { return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); + $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', + self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', + self::LEVEL_PROFILE => 'profile'); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { @@ -134,26 +140,7 @@ public function flush() { $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { - switch ($key) { - case self::LEVEL_INFO: - $key = 'info'; - break; - case self::LEVEL_ERROR: - $key = 'error'; - break; - case self::LEVEL_DEBUG: - $key = 'debug'; - break; - case self::LEVEL_TRACE: - $key = 'trace'; - break; - case self::LEVEL_PROFILE: - $key = 'profile'; - break; - default: - $key = 'all'; - break; - } + $key = isset($_map[$key]) ? $_map[$key] : 'all'; if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); @@ -389,9 +376,11 @@ public function __destruct() { } /** - * @param field_type $_logFile + * @param string $logFile */ public function setLogDir($logDir) { + if (!is_dir($logDir)) + $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } From b9bb4c9e3c19860c12901fd9abd9959b0c3b81f2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:32:18 +0000 Subject: [PATCH 0374/1065] =?UTF-8?q?bug=20fixed:=20=20WindViewTemplate=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=B8=8B=E9=9D=A2=E6=A0=BC=E5=BC=8F=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=20function()=20{=20=20=20=20=20t=20=3D=20setTimeout(f?= =?UTF-8?q?unction(){$menu=5Fpost').hide()},=20100);=20}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2444 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/compiler/WindViewTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/viewer/compiler/WindViewTemplate.php b/wind/component/viewer/compiler/WindViewTemplate.php index 22bf1aba..25049e7f 100644 --- a/wind/component/viewer/compiler/WindViewTemplate.php +++ b/wind/component/viewer/compiler/WindViewTemplate.php @@ -101,7 +101,7 @@ protected function getTags() { /*标签解析结束*/ $_tags += (array) parent::getTags(); $_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', - '/({@|{\$)[^}{@=\n]*}/i'); + '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); return $_tags; } From e747ae83a47d7b30a30d1011d304b973b15a10b3 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:33:25 +0000 Subject: [PATCH 0375/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0=20windLogger=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2445 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/wind/components_config.php b/wind/components_config.php index 8dd52bd3..bb0a1aa2 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -11,9 +11,17 @@ ), ), ), - 'windLog' => array( + 'windLogger' => array( 'path' => 'COM:log.WindLogger', 'scope' => 'application', + 'constructor-arg' => array( + '0' => array( + 'value' => 'data.log', + ), + '1' => array( + 'value' => '0', + ), + ), ), 'dispatcher' => array( 'path' => 'WIND:core.web.WindDispatcher', From 1f72e071dd13f0d30c2d6800bfe0e22312341d3f Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:34:58 +0000 Subject: [PATCH 0376/1065] =?UTF-8?q?bug=20fixed:=20WindFactory=20?= =?UTF-8?q?=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0=E5=8F=82=E6=95=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2446 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index 05ef0ed7..a93a88ee 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -40,8 +40,8 @@ public function getInstance($alias, $args = array()) { if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; - if (isset($definition['constructorArgs'])) - foreach ((array) $definition['constructorArgs'] as $_var) { + if (isset($definition['constructor-arg'])) + foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) From ee70a116100a77827d533f2d0cce15a7c071ae61 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:35:15 +0000 Subject: [PATCH 0377/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0=20windLogger=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2447 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 8a324ea8..60f3f05f 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -137,7 +137,7 @@ public function processRequest() { * @param WindActionException actionException * @return */ - protected function sendErrorMessage($exception) { + protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException($exception->getMessage()); @@ -248,13 +248,6 @@ public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } - /** - * @return WindLogger - */ - public function getLogger() { - return $this->windFactory->getInstance('windLogger'); - } - /** * @return WindHttpRequest $request */ From c9a7e1e40860159cf8d289b1e3a3bc97a5fbd1e2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:35:41 +0000 Subject: [PATCH 0378/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0log=E6=97=A5=E5=BF=97=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2448 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindHelper.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php index 003ba2a2..c01cf07b 100644 --- a/wind/core/WindHelper.php +++ b/wind/core/WindHelper.php @@ -69,7 +69,7 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { break; } } - $msg = ''; + $msg = $msghtml = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); @@ -84,8 +84,9 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { $call); $errtrace .= "$traceLine\n"; } - $errsample = ''; - if ($_errhtml && is_file($file)) { + $msg = "$file\n"; + $msghtml = "$file\n"; + if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; @@ -97,17 +98,15 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); + $msg .= implode("\n", $fileLines) . "\n"; $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; - $errsample = implode("\n", $fileLines) . "\n"; + $msghtml .= implode("\n", $fileLines) . "\n"; } } - if ($_errhtml) - $errfile = "$file"; - else - $errfile = "$file"; - $msg = "$errfile\n$errsample\n$errtrace\n"; + $msg .= "$errtrace\n"; + $msghtml .= "$errtrace\n"; } - $msg .= self::errorInfo(); + $msghtml .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; @@ -115,13 +114,14 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; - if ($_errhtml) { - $msg = "$topic

$topic

$errmessage\n$msg
"; - } else - $msg = "$topic\n$errmessage\n$msg"; + + $msghtml = "$topic

$topic

$errmessage\n$msghtml
"; + $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); - die($msg); + $msghtml = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msghtml); + Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', true); + die($_errhtml ? $msghtml : $msg); } /** From 2f1b9317472d5acf9c4b54fe8d6be1dcee55fa5f Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:36:54 +0000 Subject: [PATCH 0379/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0log=E6=97=A5=E5=BF=97=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2449 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php index c01cf07b..620575f4 100644 --- a/wind/core/WindHelper.php +++ b/wind/core/WindHelper.php @@ -135,7 +135,7 @@ private static function getCallLine($call) { if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { - $call_signature .= $call['function'] . '('; + $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) From eb57e0715ff6acffd09de82e58c9d2d1116b631c Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:46:40 +0000 Subject: [PATCH 0380/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0log=E6=97=A5=E5=BF=97=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2450 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/config/components_config.xml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index 632e69cb..13106c86 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -16,10 +16,8 @@
- - - - + + From 32f3e5842f2c38a9179cd1761c2f17255bd71c29 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:47:57 +0000 Subject: [PATCH 0381/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=EF=BC=9AwindLogger=20=E7=BB=84=E4=BB=B6=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2451 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/components_config.php | 10 +++++++++- _compile/wind_basic.php | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/_compile/components_config.php b/_compile/components_config.php index 8dd52bd3..97cfd8b3 100644 --- a/_compile/components_config.php +++ b/_compile/components_config.php @@ -11,9 +11,17 @@ ), ), ), - 'windLog' => array( + 'windLogger' => array( 'path' => 'COM:log.WindLogger', 'scope' => 'application', + 'constructor-arg' => array( + '0' => array( + 'value' => '', + ), + '1' => array( + 'value' => '0', + ), + ), ), 'dispatcher' => array( 'path' => 'WIND:core.web.WindDispatcher', diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php index b6bd2685..342d68a1 100644 --- a/_compile/wind_basic.php +++ b/_compile/wind_basic.php @@ -1 +1 @@ -$_setter($value); else Wind::log( '[core.WindModule.__set] both of property and setter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); else Wind::log( '[core.WindModule.__set] both of property and getter are not exist. ' . $propertyName, WindLogger::LEVEL_DEBUG, 'wind.core'); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) { Wind::log( "[core.WindModule.__clone] unexcepted value type or the property is not setted.(" . $value . ") need an object type in here. ", WindLogger::LEVEL_DEBUG, 'wind.core'); continue; } $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } protected function validatePropertyName($propertyName, $value = null) { if (isset($this->delayAttributes[$propertyName])) { Wind::log( '[core.WindModule.validatePropertyName] is a delay property (' . $propertyName . ')', WindLogger::LEVEL_DEBUG, 'wind.core'); return true; } if (!($_writeTableProperties = $this->writeTableForProperty())) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if (!array_key_exists($propertyName, $_writeTableProperties)) { Wind::log( "[core.WindModule.validatePropertyName] writeTableForProperty is empty or your input is not exists. (" . $propertyName . ")", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } if ($this->_typeValidation && $_writeTableProperties[$propertyName]) { if ($value instanceof $_writeTableProperties[$propertyName]) return true; Wind::log( "[core.WindModule.validatePropertyName] type of the property " . $propertyName . " is not defined. ", WindLogger::LEVEL_DEBUG, 'wind.core'); return false; } return true; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); public function __construct($logDir = '', $writeType = 0) { $this->_logDir = $logDir; $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_INFO, $type); } public function trace($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_TRACE, $type); } public function debug($msg, $type = 'wind.system') { $this->log($msg, self::LEVEL_DEBUG, $type); } public function error($msg, $type = 'wind.core') { $this->log($msg, self::LEVEL_ERROR, $type); } public function profileBegin($msg, $type = 'wind.core') { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type); } public function profileEnd($msg, $type = 'wind.core') { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system') { if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { $this->_types[] = $type; } } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { switch ($key) { case self::LEVEL_INFO: $key = 'info'; break; case self::LEVEL_ERROR: $key = 'error'; break; case self::LEVEL_DEBUG: $key = 'debug'; break; case self::LEVEL_TRACE: $key = 'trace'; break; case self::LEVEL_PROFILE: $key = 'profile'; break; default: $key = 'all'; break; } if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . " timer: " . sprintf('%0.5f', ($timer - DEBUG_TIME)) . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); if (isset($definition['constructorArgs'])) foreach ((array) $definition['constructorArgs'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (IS_DEBUG && IS_DEBUG <= WindLogger::LEVEL_DEBUG) { Wind::log('[core.factory.WindFactory.createInstance] create instance:' . $className, WindLogger::LEVEL_DEBUG, 'core.factory'); } if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (!is_string($alias) || empty($alias)) { throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException( '[core.web.WindWebApplication.sendErrorMessage] ' . $exception->getMessage()); if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { echo $errno,$errfile,'.....',$errline,'
'; if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $errsample = ''; if ($_errhtml && is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $errsample = implode("\n", $fileLines) . "\n"; } } if ($_errhtml) $errfile = "$file"; else $errfile = "$file"; $msg = "$errfile\n$errsample\n$errtrace\n"; } $msg .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; if ($_errhtml) { $msg = "$topic

$topic

$errmessage\n$msg
"; } else $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . '('; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { $this->getRequest()->setAttribute($value, $key); if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } }?> \ No newline at end of file +$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { $key = isset($_map[$key]) ? $_map[$key] : 'all'; if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (!is_string($alias) || empty($alias)) { throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = $msghtml = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $msg = "$file\n"; $msghtml = "$file\n"; if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $msg .= implode("\n", $fileLines) . "\n"; $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $msghtml .= implode("\n", $fileLines) . "\n"; } } $msg .= "$errtrace\n"; $msghtml .= "$errtrace\n"; } $msghtml .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; $msghtml = "$topic

$topic

$errmessage\n$msghtml
"; $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); $msghtml = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msghtml); Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', true); die($_errhtml ? $msghtml : $msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } }?> \ No newline at end of file From bb3fc36cc2217d24f37e8539a70d882a024d9ff3 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:48:09 +0000 Subject: [PATCH 0382/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=EF=BC=9AwindLogger=20=E7=BB=84=E4=BB=B6=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2452 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/components_config.php b/wind/components_config.php index bb0a1aa2..97cfd8b3 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -16,7 +16,7 @@ 'scope' => 'application', 'constructor-arg' => array( '0' => array( - 'value' => 'data.log', + 'value' => '', ), '1' => array( 'value' => '0', From 2da1913ed2b687c01d25c968af2ec17d918927a4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:48:19 +0000 Subject: [PATCH 0383/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0log=E6=97=A5=E5=BF=97=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2453 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 50 ++++++++++++++++++---------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index adea53d4..46cb654c 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -1,6 +1,7 @@ @@ -51,7 +52,6 @@ public function __construct($dsn = '', $username = '', $password = '') { * @return WindSqlStatement */ public function createStatement($sql = null) { - Wind::import("WIND:component.db.WindSqlStatement"); return new WindSqlStatement($this, $sql); } @@ -69,7 +69,8 @@ public function getDbHandle() { * @return string * */ public function getAttribute($attribute = '') { - if (!$attribute) return; + if (!$attribute) + return; if ($this->_dbHandle !== null) { return $this->_dbHandle->getAttribute($attribute); } else @@ -83,7 +84,8 @@ public function getAttribute($attribute = '') { * @return * */ public function setAttribute($attribute, $value = null) { - if (!$attribute) return; + if (!$attribute) + return; if ($this->_dbHandle !== null && $this->_dbHandle instanceof PDO) { $this->_dbHandle->setAttribute($attribute, $value); } else @@ -95,7 +97,8 @@ public function setAttribute($attribute, $value = null) { * @return string */ public function getDriverName() { - if ($this->_driverName) return $this->_driverName; + if ($this->_driverName) + return $this->_driverName; if ($this->_dbHandle !== null) { $this->_driverName = $this->_dbHandle->getAttribute(PDO::ATTR_DRIVER_NAME); } elseif (($pos = strpos($this->_dsn, ':')) !== false) { @@ -146,7 +149,6 @@ public function execute($sql) { return $this->getDbHandle()->exec($sql); } catch (PDOException $e) { $this->close(); - Wind::log('component.db.WindConnection.excute.', WindLogger::LEVEL_TRACE, 'component.db'); throw new WindDbException($e->getMessage()); } } @@ -210,7 +212,8 @@ public function sqlSingle($array) { * @param array $fileds */ public function createTable($tableName, $values, $engine = '', $autoIncrement = '') { - return $this->getDbHandle()->createTable($tableName, $values, $engine, $this->_charset, $autoIncrement); + return $this->getDbHandle()->createTable($tableName, $values, $engine, $this->_charset, + $autoIncrement); } /** @@ -240,9 +243,11 @@ public function close() { * @return */ public function init() { - if ($this->_dbHandle !== null) return; + if ($this->_dbHandle !== null) + return; try { - Wind::log("component.db.WindConnection._init() Initialize DB handle, set default attributes and charset.", + Wind::log( + "component.db.WindConnection._init() Initialize DB handle, set default attributes and charset.", WindLogger::LEVEL_INFO); $driverName = $this->getDriverName(); if ($driverName) { @@ -251,9 +256,11 @@ public function init() { } else $dbHandleClass = 'PDO'; if (!$dbHandleClass) { - throw new WindDbException('The db handle class path \'' . $dbHandleClass . '\' is not exist.'); + throw new WindDbException( + 'The db handle class path \'' . $dbHandleClass . '\' is not exist.'); } - $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); + $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, + (array) $this->_attributes); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->_dbHandle->setCharset($this->_charset); Wind::log( @@ -261,7 +268,8 @@ public function init() { WindLogger::LEVEL_DEBUG); } catch (PDOException $e) { $this->close(); - Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", WindLogger::LEVEL_TRACE); + Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", + WindLogger::LEVEL_TRACE); throw new WindDbException($e->getMessage()); } } @@ -272,12 +280,18 @@ public function init() { */ public function setConfig($config) { parent::setConfig($config); - if (!$this->_dsn) $this->_dsn = $this->getConfig(self::DSN, '', $this->_dsn); - if (!$this->_user) $this->_user = $this->getConfig(self::USER, '', $this->_user); - if (!$this->_pwd) $this->_pwd = $this->getConfig(self::PWD, '', $this->_pwd); - if (!$this->_enableLog) $this->_enableLog = $this->getConfig(self::ENABLELOG, '', $this->_enableLog); - if (!$this->_charset) $this->_charset = $this->getConfig(self::CHARSET, '', $this->_charset); - if (!$this->_tablePrefix) $this->_tablePrefix = $this->getConfig(self::TABLEPREFIX, '', $this->_tablePrefix); + if (!$this->_dsn) + $this->_dsn = $this->getConfig(self::DSN, '', $this->_dsn); + if (!$this->_user) + $this->_user = $this->getConfig(self::USER, '', $this->_user); + if (!$this->_pwd) + $this->_pwd = $this->getConfig(self::PWD, '', $this->_pwd); + if (!$this->_enableLog) + $this->_enableLog = $this->getConfig(self::ENABLELOG, '', $this->_enableLog); + if (!$this->_charset) + $this->_charset = $this->getConfig(self::CHARSET, '', $this->_charset); + if (!$this->_tablePrefix) + $this->_tablePrefix = $this->getConfig(self::TABLEPREFIX, '', $this->_tablePrefix); } } ?> \ No newline at end of file From 00aa2c3d4ed54f06f99a550508dd68618a55f9f3 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 09:48:38 +0000 Subject: [PATCH 0384/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0log=E6=97=A5=E5=BF=97=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BD=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2454 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index 6d6c4613..9eb2be0d 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -100,6 +100,7 @@ public function profileEnd($msg, $type = 'wind.core', $flush = false) { * @param const $logType 日志类别 */ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { + if (!$this->_logDir) return; if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else @@ -113,9 +114,8 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flu $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; - if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) { + if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; - } if ($flush) $this->flush(); } From f54da164248913fc907e82d8c804b6a73fe1612e Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 11:36:20 +0000 Subject: [PATCH 0385/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E4=BC=98=E5=8C=96=E6=97=A5=E5=BF=97=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2455 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 28 +++------- wind/component/db/WindResultSet.php | 38 ++++++++----- wind/component/db/WindSqlStatement.php | 77 ++++++++++++-------------- 3 files changed, 68 insertions(+), 75 deletions(-) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 46cb654c..48c389a0 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -243,33 +243,23 @@ public function close() { * @return */ public function init() { - if ($this->_dbHandle !== null) - return; try { - Wind::log( - "component.db.WindConnection._init() Initialize DB handle, set default attributes and charset.", - WindLogger::LEVEL_INFO); $driverName = $this->getDriverName(); - if ($driverName) { - $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; - $dbHandleClass = Wind::import($dbHandleClass); - } else - $dbHandleClass = 'PDO'; - if (!$dbHandleClass) { - throw new WindDbException( - 'The db handle class path \'' . $dbHandleClass . '\' is not exist.'); - } + $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; + $dbHandleClass = Wind::import($dbHandleClass); $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->_dbHandle->setCharset($this->_charset); - Wind::log( - "component.db.WindConnection.init() \r\n dsn: " . $this->_dsn . " \r\n username: " . $this->_user . " \r\n password: " . $this->_pwd . " \r\n tablePrefix: " . $this->_tablePrefix, - WindLogger::LEVEL_DEBUG); + if (IS_DEBUG) { + $reflection = new ReflectionClass(get_class($this)); + $properties = $reflection->getProperties(); + Wind::getApp()->getComponent('windLogger')->info( + "component.db.WindConnection.init() Initialize db connection success." . WindString::varToString( + $properties), 'component.db'); + } } catch (PDOException $e) { $this->close(); - Wind::log("component.db.WindConnection._init() Initalize DB handle failed.", - WindLogger::LEVEL_TRACE); throw new WindDbException($e->getMessage()); } } diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index c31c5485..4551a646 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -34,8 +34,10 @@ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { $this->_columns = $sqlStatement->getColumns(); } else $this->_statement = $sqlStatement; - if ($fetchMode != 0) $this->_fetchMode = $fetchMode; - if ($fetchMode != 0) $this->_fetchType = $fetchType; + if ($fetchMode != 0) + $this->_fetchMode = $fetchMode; + if ($fetchMode != 0) + $this->_fetchType = $fetchType; } /** @@ -77,8 +79,10 @@ public function columnCount() { * @return array */ public function fetch($fetchMode = 0, $fetchType = 0) { - if ($fetchMode === 0) $fetchMode = $this->_fetchMode; - if ($fetchType === 0) $fetchMode = $this->_fetchType; + if ($fetchMode === 0) + $fetchMode = $this->_fetchMode; + if ($fetchType === 0) + $fetchMode = $this->_fetchType; return $this->_fetch($fetchMode, $fetchType); } @@ -87,16 +91,22 @@ public function fetch($fetchMode = 0, $fetchType = 0) { * @see WindResult::fetch() */ private function _fetch($fetchMode, $fetchType) { - if (!empty($this->_columns)) $fetchMode = PDO::FETCH_BOUND; + if (!empty($this->_columns)) + $fetchMode = PDO::FETCH_BOUND; $result = array(); if ($row = $this->_statement->fetch($fetchMode, $fetchType)) { - if (empty($this->_columns)) return $row; - foreach ($this->_columns as $key => $value) { - $result[$key] = $value; - } - return $result; + if (empty($this->_columns)) + $result = $row; + else + foreach ($this->_columns as $key => $value) { + $result[$key] = $value; + } } - return array(); + if (IS_DEBUG) + Wind::getApp()->getComponent('windLogger')->info( + '[component.db.WindResultSet._fetch]' . WindString::varToString($result)); + + return $result; } /** @@ -107,14 +117,16 @@ private function _fetch($fetchMode, $fetchType) { * @return array */ public function fetchAll($index = '', $fetchMode = 0) { - if ($fetchMode === 0) $fetchMode = $this->_fetchMode; + if ($fetchMode === 0) + $fetchMode = $this->_fetchMode; $result = array(); if (!$index) while ($row = $this->fetch($fetchMode)) $result[] = $row; else while ($row = $this->fetch($fetchMode)) { - if (!isset($row[$index])) continue; + if (!isset($row[$index])) + continue; $result[$row[$index]] = $row; } return $result; diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index 91437b89..d06eb84b 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -27,7 +27,8 @@ class WindSqlStatement { * * @var array */ - private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); + private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, + 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); private $_columns = array(); /** @@ -54,8 +55,6 @@ public function __construct($connection, $query) { */ public function bindParam($parameter, &$variable, $dataType = null, $length = null, $driverOptions = null) { try { - Wind::log("component.db.WindSqlStatement.bindParam. parameter:" . $parameter . " variable:" . $variable, - WindLogger::LEVEL_INFO, "component.db"); $this->init(); if ($dataType === null) { $dataType = $this->_getPdoDataType($variable); @@ -63,11 +62,10 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu if ($length === null) $this->getStatement()->bindParam($parameter, $variable, $dataType); else - $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, $driverOptions); + $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, + $driverOptions); return $this; } catch (PDOException $e) { - Wind::log("component.db.WindSqlStatement.bindParam. exception message:" . $e->getMessage(), - WindLogger::LEVEL_TRACE, "component.db"); throw new WindDbException($e->getMessage()); } } @@ -83,10 +81,11 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu * @return WindSqlStatement */ public function bindParams(&$parameters) { - if (!is_array($parameters)) { + if (!is_array($parameters)) throw new WindDbException( - '[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters)); - } + '[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype( + $parameters)); + $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1)); foreach ($parameters as $key => $value) { $_key = $keied ? $key : $key + 1; @@ -112,17 +111,12 @@ public function bindParams(&$parameters) { */ public function bindValue($parameter, $value, $data_type = null) { try { - Wind::log("component.db.WindSqlStatement.bindValue. parameter:" . $parameter . " variable:" . $value, - WindLogger::LEVEL_INFO, "component.db"); $this->init(); - if ($data_type === null) { + if ($data_type === null) $data_type = $this->_getPdoDataType($value); - } $this->getStatement()->bindValue($parameter, $value, $data_type); return $this; } catch (PDOException $e) { - Wind::log("component.db.WindSqlStatement.bindValue. exception message:" . $e->getMessage(), - WindLogger::LEVEL_TRACE, "component.db"); throw new WindDbException($e->getMessage()); } } @@ -135,13 +129,15 @@ public function bindValue($parameter, $value, $data_type = null) { * @return WindSqlStatement */ public function bindValues($values) { - if (!is_array($values)) { + if (!is_array($values)) throw new WindDbException( - '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type ' . gettype($values)); - } + '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type \'' . gettype( + $values) . '\''); + $keied = (array_keys($values) !== range(0, sizeof($values) - 1)); foreach ($values as $key => $value) { - if (!$keied) $key = $key + 1; + if (!$keied) + $key = $key + 1; $this->bindValue($key, $value, $this->_getPdoDataType($value)); } return $this; @@ -160,9 +156,9 @@ public function bindValues($values) { */ public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $driverdata = null) { try { - Wind::log("component.db.WindSqlStatement.bindColumn.", WindLogger::LEVEL_INFO, "component.db"); $this->init(); - if ($type == null) $type = $this->_getPdoDataType($param); + if ($type == null) + $type = $this->_getPdoDataType($param); if ($type == null) $this->getStatement()->bindColumn($column, $param); elseif ($maxlen == null) @@ -172,8 +168,6 @@ public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $this->_columns[$column] = & $param; return $this; } catch (PDOException $e) { - Wind::log("component.db.WindSqlStatement.bindColumn. exception message" . $e->getMessage(), - WindLogger::LEVEL_TRACE, "component.db"); throw new WindDbException($e->getMessage()); } } @@ -275,19 +269,17 @@ public function lastInsertId($name = '') { */ public function execute($params = array(), $rowCount = true) { try { - Wind::log("component.db.WindSqlStatement.execute.", WindLogger::LEVEL_INFO, "component.db"); $this->init(); $this->bindValues($params); $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; - Wind::log("component.db.WindSqlStatement.execute return value:" . $_result, WindLogger::LEVEL_DEBUG, - "component.db"); - Wind::profileEnd('component.db.WindSqlStatement._init'); + if (IS_DEBUG) + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindSqlStatement.execute] sql:", + $this->getStatement()->queryString, 'component.db'); return $_result; } catch (PDOException $e) { - Wind::log("component.db.WindSqlStatement.execute throw exception,exception message: " . $e->getMessage(), - WindLogger::LEVEL_TRACE, "component.db"); - throw new WindDbException($e->getMessage()); + throw new WindDbException('[component.db.WindSqlStatement.execute]' . $e->getMessage()); } } @@ -298,9 +290,11 @@ public function execute($params = array(), $rowCount = true) { * @return WindSqlStatement */ public function setQueryString($queryString) { - if (!$queryString) return $this; + if (!$queryString) + return $this; if ($_prefix = $this->getConnection()->getTablePrefix()) { - list($new, $old) = strpos($_prefix, '|') !== false ? explode('|', $_prefix) : array($_prefix, ''); + list($new, $old) = strpos($_prefix, '|') !== false ? explode('|', $_prefix) : array( + $_prefix, ''); $queryString = preg_replace('/{(' . $old . ')?(.*?)}/', $new . '\2', $queryString); } $this->_queryString = $queryString; @@ -349,18 +343,15 @@ public function getColumns() { public function init() { if ($this->_statement === null) { try { - Wind::log("component.db.WindSqlStatement._init Initialize DBStatement. ", WindLogger::LEVEL_INFO, - "component.db"); - Wind::profileBegin("component.db.WindSqlStatement._init", " SQL: " . $this->getQueryString(), - "component.db"); - $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString()); - Wind::log( - "component.db.WindSqlStatement._init Initialize DBStatement. This statement is " . get_class( - $this->_statement), WindLogger::LEVEL_DEBUG, "component.db"); + $this->_statement = $this->getConnection()->getDbHandle()->prepare( + $this->getQueryString()); + if (IS_DEBUG) + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindSqlStatement.init] Initialize DBStatement", + 'component.db'); } catch (PDOException $e) { - Wind::log("Component.db.WindSqlStatement._init Initialize DBStatement - failed.", WindLogger::LEVEL_TRACE, "component.db"); - throw new WindDbException("Initialization WindSqlStatement failed."); + throw new WindDbException( + "Initialization WindSqlStatement failed." . $e->getMessage()); } } } From 8de035dc74b87eff2e80a02e049fefb41a7ab8d3 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 11:36:37 +0000 Subject: [PATCH 0386/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E4=BC=98=E5=8C=96=E6=97=A5=E5=BF=97=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2456 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 7e59e818..d51e19cf 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -195,10 +195,8 @@ public static function getRootPath($namespace) { public static function autoLoad($className, $path = '') { if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; - if ($path === '') - throw new Exception('auto load ' . $className . ' failed.'); $path .= '.' . self::$_extensions; - if ((include $path) === false) + if (!(@include $path)) throw new Exception( '[wind.Wind.autoLoad] Your requested \'' . $path . '\' was not found on this server.'); } @@ -385,7 +383,15 @@ private static function _loadBaseLib() { 'AbstractWindHttp' => 'http/transfer/AbstractWindHttp', 'WindHttpCurl' => 'http/transfer/WindHttpCurl', 'WindHttpSocket' => 'http/transfer/WindHttpSocket', - 'WindHttpStream' => 'http/transfer/WindHttpStream'); + 'WindHttpStream' => 'http/transfer/WindHttpStream', + 'WindDate' => 'utility/date/WindDate', + 'WindGeneralDate' => 'utility/date/WindGeneralDate', + 'WindDecoder' => 'utility/json/WindDecoder', 'WindEncoder' => 'utility/json/WindEncoder', + 'WindArray' => 'utility/WindArray', 'WindFile' => 'utility/WindFile', + 'WindHtmlHelper' => 'utility/WindHtmlHelper', 'WindImage' => 'utility/WindImage', + 'WindPack' => 'utility/WindPack', 'WindSecurity' => 'utility/WindSecurity', + 'WindString' => 'utility/WindString', 'WindUtility' => 'utility/WindUtility', + 'WindValidator' => 'utility/WindValidator'); } } Wind::init(); From 4f20362229dda88480220af7a47cb1c8c5bad92d Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 23 Aug 2011 11:40:10 +0000 Subject: [PATCH 0387/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9AWind::autoLoad=20=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2457 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index d51e19cf..3a14096f 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -195,10 +195,7 @@ public static function getRootPath($namespace) { public static function autoLoad($className, $path = '') { if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; - $path .= '.' . self::$_extensions; - if (!(@include $path)) - throw new Exception( - '[wind.Wind.autoLoad] Your requested \'' . $path . '\' was not found on this server.'); + include $path . '.' . self::$_extensions; } /** From 6d9a179153b45b337129fbebc8080ff6025da1a2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 24 Aug 2011 03:58:55 +0000 Subject: [PATCH 0388/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0db=E7=BB=84=E4=BB=B6=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2460 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 1 + _compile/components_config.php | 11 +++++++---- _compile/config/components_config.xml | 5 +++-- _compile/wind_basic.php | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/_compile/compile.php b/_compile/compile.php index 80375043..1651e571 100644 --- a/_compile/compile.php +++ b/_compile/compile.php @@ -12,6 +12,7 @@ Wind::import('COM:parser.*', true); Wind::import('COM:router.*', true); Wind::import('COM:http.*', true); +Wind::import('COM:utility.*', true); $imports = Wind::getImports(); /* 载入需要的文件信息 */ diff --git a/_compile/components_config.php b/_compile/components_config.php index 97cfd8b3..448e6fe6 100644 --- a/_compile/components_config.php +++ b/_compile/components_config.php @@ -40,10 +40,6 @@ 'path' => 'COM:router.WindRouter', 'scope' => 'application', ), - 'urlRewriteRouter' => array( - 'path' => 'COM:router.WindUrlRewriteRouter', - 'scope' => 'singleton', - ), 'urlHelper' => array( 'path' => 'WIND:core.web.WindUrlHelper', 'scope' => 'application', @@ -75,6 +71,13 @@ 'path' => 'COM:viewer.compiler.WindViewTemplate', 'scope' => 'prototype', ), + 'db' => array( + 'path' => 'COM:db.WindConnection', + 'scope' => 'singleton', + 'config' => array( + 'resource' => 'db_config.xml', + ), + ), 'errorMessage' => array( 'path' => 'WIND:core.web.WindErrorMessage', 'scope' => 'prototype', diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index 13106c86..18b137e9 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -30,8 +30,6 @@
- @@ -54,6 +52,9 @@ + + + diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php index 342d68a1..8aebd722 100644 --- a/_compile/wind_basic.php +++ b/_compile/wind_basic.php @@ -1 +1 @@ -$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { $key = isset($_map[$key]) ? $_map[$key] : 'all'; if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) return null; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (!is_string($alias) || empty($alias)) { throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } if (isset($this->classDefinitions[$alias])) return; $this->classDefinitions[$alias] = $classDefinition; } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = $msghtml = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $msg = "$file\n"; $msghtml = "$file\n"; if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $msg .= implode("\n", $fileLines) . "\n"; $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $msghtml .= implode("\n", $fileLines) . "\n"; } } $msg .= "$errtrace\n"; $msghtml .= "$errtrace\n"; } $msghtml .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; $msghtml = "$topic

$topic

$errmessage\n$msghtml
"; $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); $msghtml = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msghtml); Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', true); die($_errhtml ? $msghtml : $msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } }?> \ No newline at end of file +$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { $key = isset($_map[$key]) ? $_map[$key] : 'all'; if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias])) throw new WindException( '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); $definition = $this->classDefinitions[$alias]; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (!$className) throw new WindException('class name is required.'); if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (is_string($alias) && !empty($alias)) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = $msghtml = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $msg = "$file\n"; $msghtml = "$file\n"; if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $msg .= implode("\n", $fileLines) . "\n"; $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $msghtml .= implode("\n", $fileLines) . "\n"; } } $msg .= "$errtrace\n"; $msghtml .= "$errtrace\n"; } $msghtml .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; $msghtml = "$topic

$topic

$errmessage\n$msghtml
"; $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); $msghtml = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msghtml); Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', true); die($_errhtml ? $msghtml : $msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } class WindDate { public static function getTimeZone() { return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); } public static function setTimezone($timezone) { function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); } public static function format($format = null, $dateTime = null) { return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); } public static function datePart($interval, $dateTime = null) { return date($interval, self::getTimeStamp($dateTime)); } public static function dateDiff($interval, $startDateTime, $endDateTime) { $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); $retval = 0; switch ($interval) { case "y": $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; case "m": $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; case "w": $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; case "d": $retval = bcdiv($diff, (60 * 60 * 24));break; case "h": $retval = bcdiv($diff, (60 * 60));break; case "n": $retval = bcdiv($diff, 60);break; case "s": default:$retval = $diff;break; } return $retval; } public static function dateAdd($interval, $value, $dateTime, $format = null) { $date = getdate(self::getTimeStamp($dateTime)); switch ($interval) { case "y": $date["year"] += $value;break; case "q": $date["mon"] += ($value * 3);break; case "m": $date["mon"] += $value;break; case "w": $date["mday"] += ($value * 7);break; case "d": $date["mday"] += $value;break; case "h": $date["hours"] += $value;break; case "n": $date["minutes"] += $value;break; case "s": default:$date["seconds"] += $value;break; } return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); } public static function getRealDaysInMonthsOfYear($year) { $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if (self::isLeapYear($year)) { $months[1] = 29; } return $months; } public static function getDaysInMonth($month, $year) { if (1 > $month || 12 < $month) { return 0; } if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { return 0; } return $daysInmonths[$month - 1]; } public static function getDaysInYear($year) { return self::isLeapYear($year) ? 366 : 365; } public static function getRFCDate($date = null) { $time = $date ? is_int($date) ? $date : strtotime($date) : time(); $tz = date('Z', $time); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); } public static function getChinaDate($time = null) { list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); } public static function getChinaWeek($week = null) { $week = $week ? $week : (int) date('w', time()); $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); return $weekMap[$week]; } public static function getPeriodOfTime($hour = null) { $hour = $hour ? $hour : (int) date('G', time()); $period = ''; if (0 <= $hour && 6 > $hour) { $period = '凌晨'; } elseif (6 <= $hour && 8 > $hour) { $period = '早上'; } elseif (8 <= $hour && 11 > $hour) { $period = '上午'; } elseif (11 <= $hour && 13 > $hour) { $period = '中午'; } elseif (13 <= $hour && 15 > $hour) { $period = '响午'; } elseif (15 <= $hour && 18 > $hour) { $period = '下午'; } elseif (18 <= $hour && 20 > $hour) { $period = '傍晚'; } elseif (20 <= $hour && 22 > $hour) { $period = '晚上'; } elseif (22 <= $hour && 23 >= $hour) { $period = '深夜'; } return $period; } public static function getUTCDate($dateTime = null) { $oldTimezone = self::getTimezone(); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone('UTC'); } $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone($oldTimezone); } return $date; } public static function getMicroTime($get_as_float = null,$mircrotime = null) { return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); } public static function isLeapYear($year) { if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { return true; } return false; } public static function getTimeStamp($dateTime = null){ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); } public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); $timestamp = $timestamp ? $timestamp : time(); $compareTime = strtotime(self::format('Y-m-d',$timestamp)); $currentTime = strtotime(self::format('Y-m-d',$time)); $decrease = $timestamp - $time; $result = self::format($format,$time); if (0 >= $decrease) { return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } if ($currentTime == $compareTime) { if (1 == $type) { if (60 >= $decrease) { return array($decrease . $timelang['second'], $result); } return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); } return array(self::format('H:i',$time), $result); } elseif ($currentTime == $compareTime - 86400) { return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); } elseif ($currentTime == $compareTime - 172800) { return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); } return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } } class WindGeneralDate { const FILL = 0; const DIGIT = 1; const TEXT = 2; const DEFAULT_FORMAT = 'Y-m-d H:i:s'; private $time = 0; public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { $time = time(); !$month && ((!$year) ? $month = date('m', $time) : $month = 1); !$day && ((!$year) ? $day = date('d', $time) : $day = 1); !$hours && !$year && $hours = date('H', $time); !$minutes && !$year && $minutes = date('i', $time); !$second && !$year && $second = date('s', $time); !$year && $year = date('Y', $time); $this->time = mktime($hours, $minutes, $second, $month, $day, $year); } public function getDaysInMonth() { return date('t', $this->time); } public function getDaysInYear() { return $this->isLeapYear() ? 366 : 365; } public function getDayOfYear() { return date('z', $this->time) + 1; } public function getDayOfMonth() { return date('j', $this->time); } public function getDayOfWeek() { return date('w', $this->time) + 1; } public function getWeekOfYear() { return date('W', $this->time); } public function getYear($format = true) { return date($format ? 'Y' : 'y', $this->time); } public function getMonth($display = self::FILL) { if(self::FILL == $display){ return date('m', $this->time); }elseif(self::DIGIT == $display){ return date('n', $this->time); }elseif(self::TEXT == $display){ return date('M', $this->time); } return date('n', $this->time); } public function getDay($display = self::FILL) { if(self::FILL == $display){ return date('d', $this->time); }elseif(self::DIGIT == $display){ return date('j', $this->time); }elseif(self::TEXT == $display){ return date('jS', $this->time); } return date('j', $this->time); } public function getWeek($display = self::FILL) { if(self::FILL == $display || self::DIGIT == $display){ return date('w', $this->time); }elseif(self::TEXT == $display){ return date('D', $this->time); } return date('N', $this->time); } public function get12Hours($display = self::FILL){ if(self::FILL == $display){ return date('h', $this->time); }elseif(self::DIGIT == $display){ return date('g', $this->time);; } return date('h', $this->time); } public function get24Hours($display = self::FILL){ if(self::FILL == $display){ return date('H', $this->time); }elseif(self::DIGIT == $display){ return date('G', $this->time);; } return date('H', $this->time); } public function getMinutes() { return date('i', $this->time); } public function getSeconds() { return date('s', $this->time); } public function getLocalTimeZone() { return date('T', $this->time); } public function setTime($time) { if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { $this->time = $time; } } public function getNow() { $date = getdate($this->time); return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); } public function __toString() { return $this->toString(); } public function toString($format = null) { return date($format ? $format : self::DEFAULT_FORMAT, $this->time); } public function isLeapYear() { return date('L', $this->time); } } class WindDecoder { const JSON_SLICE = 1; const JSON_IN_STR = 2; const JSON_IN_ARR = 4; const JSON_IN_OBJ = 8; const JSON_IN_CMT = 16; public static function decode($str, $useArray = true) { $str = strtolower(self::reduceString($str)); if ('true' == $str) { return true; } elseif ('false' == $str) { return false; } elseif ('null' == $str) { return null; } elseif (is_numeric($str)) { return (float)$str == (integer)$str ? (integer) $str : (float) $str; }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ return self::jsonToString($str); }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); } return false; } protected static function jsonToString($string) { $delim = substr($string, 0, 1); $chrs = substr($string, 1, -1); $decodeStr = ''; for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { $compare = substr($chrs, $c, 2); $ordCode = ord($chrs{$c}); if('\b' == $compare){ $decodeStr .= chr(0x08); ++$c; }elseif('\t' == $compare){ $decodeStr .= chr(0x09); ++$c; }elseif('\n' == $compare){ $decodeStr .= chr(0x0A); ++$c; }elseif('\f' == $compare){ $decodeStr .= chr(0x0C); ++$c; }elseif('\r' == $compare){ $decodeStr .= chr(0x0D); ++$c; }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { $decodeStr .= $chrs{++$c}; } }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $decodeStr .= self::utf16beToUTF8($utf16); $c += 5; }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ $decodeStr .= $chrs{$c}; }elseif(0xC0 == ($ordCode & 0xE0)){ $decodeStr .= substr($chrs, $c, 2); ++$c; }elseif(0xE0 == ($ordCode & 0xF0)){ $decodeStr .= substr($chrs, $c, 3); $c += 2; }elseif(0xF0 == ($ordCode & 0xF8)){ $decodeStr .= substr($chrs, $c, 4); $c += 3; }elseif(0xF8 == ($ordCode & 0xFC)){ $decodeStr .= substr($chrs, $c, 5); $c += 4; }elseif(0xFC == ($ordCode & 0xFE)){ $decodeStr .= substr($chrs, $c, 6); $c += 5; } } return $decodeStr; } protected static function jsonToArray($str) { return self::complexConvert($str,true); } protected static function jsonToObject($str) { return self::complexConvert($str,false); } protected static function complexConvert($str,$useArray = true){ if ('[' == $str{0}) { $stk = array(self::JSON_IN_ARR); $arr = array(); } else { $obj = $useArray ? array() : new stdClass(); $stk = array(self::JSON_IN_OBJ); } array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = self::reduceString($chrs); if ('' == $chrs) { return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; } for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); if (reset($stk) == self::JSON_IN_ARR) { array_push($arr, self::decode($slice, $useArray)); } elseif (reset($stk) == self::JSON_IN_OBJ) { if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $key = self::decode($parts[1], $useArray); $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { array_pop($stk); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { array_pop($stk); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { array_pop($stk); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { array_pop($stk); for ($i = $top['where']; $i <= ++$c; ++$i){ $chrs = substr_replace($chrs, ' ', $i, 1); } } } if (self::JSON_IN_ARR == reset($stk)) { return $arr; } elseif (self::JSON_IN_OBJ == reset($stk)) { return $obj; } return false; } protected static function unicodeToUTF8(&$str) { $utf8 = ''; foreach ($str as $unicode) { if ($unicode < 128) { $utf8 .= chr($unicode); } elseif ($unicode < 2048) { $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } else { $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } } return $utf8; } protected static function reduceString($str) { return trim(preg_replace(array( '#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str)); } protected static function utf16beToUTF8(&$str) { return self::unicodeToUTF8(unpack('n*', $str)); } } class WindEncoder { public static $charset = 'utf-8'; public static function encode($value) { switch (gettype($value)) { case 'boolean': return $value ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $value; case 'double': case 'float': return (float) $value; case 'string': return self::stringToJson($value); case 'array': return self::arrayToJson($value); case 'object': return self::objectToJson($value); default: return ''; } return ''; } protected static function stringToJson($string) { if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { $string = iconv($enc, 'UTF-8', $string); } $ascii = ''; $strlen = strlen($string); for ($c = 0; $c < $strlen; ++$c) { $ordVar = ord($string{$c}); if (0x08 == $ordVar) { $ascii .= '\b'; } elseif (0x09 == $ordVar) { $ascii .= '\t'; } elseif (0x0A == $ordVar) { $ascii .= '\n'; } elseif (0x0C == $ordVar) { $ascii .= '\f'; } elseif (0x0D == $ordVar) { $ascii .= '\r'; } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { $ascii .= '\\' . $string{$c}; } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { $ascii .= $string{$c}; } elseif (0xC0 == ($ordVar & 0xE0)) { $char = pack('C*', $ordVar, ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xE0 == ($ordVar & 0xF0)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF0 == ($ordVar & 0xF8)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF8 == ($ordVar & 0xFC)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xFC == ($ordVar & 0xFE)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } } return '"' . $ascii . '"'; } protected static function arrayToJson(array $array) { if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; } return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; } protected static function objectToJson($object) { if ($object instanceof Traversable) { $vars = array(); foreach ($object as $k => $v) { $vars[$k] = $v; } } else { $vars = get_object_vars($object); } return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; } protected static function nameValue($name, $value) { return self::encode(strval($name)) . ':' . self::encode($value); } protected static function utf8ToUTF16BE(&$string, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if (function_exists('mb_convert_encoding')) { return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); } $uni = self::utf8ToUnicode($string); foreach ($uni as $cp) { $out .= pack('n', $cp); } return $out; } protected static function utf8ToUnicode(&$string) { $unicode = $values = array(); $lookingFor = 1; for ($i = 0, $length = strlen($string); $i < $length; $i++) { $thisValue = ord($string[$i]); if ($thisValue < 128) { $unicode[] = $thisValue; } else { if (count($values) == 0) { $lookingFor = ($thisValue < 224) ? 2 : 3; } $values[] = $thisValue; if (count($values) == $lookingFor) { $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; $values = array(); $lookingFor = 1; } } } return $unicode; } } class WindArray { public static function mergeArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); unset($array2[$key]); } else { $tmp[$key] = $array; } } return array_merge($tmp, (array) $array2); } public static function filterArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); } } return $tmp; } public static function rebuildArrayWithKey($key, array $array) { if (!$key || !$array) { return array(); } $tmp = array(); foreach ($array as $_array) { if (isset($_array[$key])) { $tmp[$_array[$key]] = $_array; } } return $tmp; } } Wind::import("COM:utility.WindSecurity"); Wind::import("COM:utility.WindString"); class WindFile { const READ = 'rb'; const READWRITE = 'rb+'; const WRITE = 'wb'; const WRITEREAD = 'wb+'; const APPEND_WRITE = 'ab'; const APPEND_WRITEREAD = 'ab+'; public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { $temp = "\r\n "; if (!$isBuildReturn && is_array($data)) { foreach ($data as $key => $value) { if (!preg_match('/^\w+$/', $key)) continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n"; } else { ($isBuildReturn) && $temp .= " return "; $temp .= WindString::varToString($data) . ";\r\n"; } return self::write($fileName, $temp, $method, $ifLock); } public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); fclose($handle); $ifChmod && chmod($fileName, 0777); return $writeCheck; } public static function read($fileName, $method = self::READ) { $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { flock($handle, LOCK_SH); $data = fread($handle, filesize($fileName)); fclose($handle); } return $data; } public static function clearDir($dir, $ifexpiled = false) { if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { self::delFile($fullPath); } } closedir($handle); false === $ifexpiled && rmdir($dir); return true; } public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); if (!$handler = opendir($path)) { return false; } while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { if (substr($filename, 0, 1) != '.') { self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); } } else { self::delFile($path . DIRECTORY_SEPARATOR . $filename); } } } closedir($handler); true == $delDir && $level > 0 && rmdir($path); return true; } public static function getMimeType($fileName) { $suffix = self::getFileSuffix($fileName); $mimes = require rtrim(WIND_PATH, D_S) . D_S . 'component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { throw new WindException('Sorry, can not find the corresponding mime type of the file'); } return false; } public static function getDirectoryIterator($dir) { return new DirectoryIterator($dir); } public static function getFileInfo($fileName) { if (false === is_file($fileName)) { return array(); } $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); $fileInfo['ctime'] = filectime($fileName); $fileInfo['atime'] = fileatime($fileName); $fileInfo['mtime'] = filemtime($fileName); $fileInfo['readable'] = is_readable($fileName); $fileInfo['writable'] = is_writable($fileName); $fileInfo['executable'] = is_executable($fileName); $fileInfo['right'] = fileperms($fileName); $fileInfo['group'] = filegroup($fileName); $fileInfo['owner'] = fileowner($fileName); $fileInfo['mime'] = self::getMimeType($fileName); return $fileInfo; } public static function getDirectoryInfo($dir) { if (false !== is_dir($dir)) { return array(); } return stat($dir); } public static function delFile($filename) { return @unlink($filename); } public static function getFileSuffix($filename) { $filename = explode($filename, '.'); return $filename[count($filename) - 1]; } public static function appendSlashesToDir($path) { return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; } } class WindHtmlHelper { public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function encodeArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; } return $_tmp; } } class WindImage { public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); if (!$imagecreate) return false; $imgwidth = $minitemp['width']; $imgheight = $minitemp['height']; $srcX = $srcY = $dstX = $dstY =0; if (!$isProportion) { $dsDivision = $imgheight / $imgwidth; $fixDivision = $dstH / $dstW; if ($dsDivision > $fixDivision) { $tmp = $imgwidth * $fixDivision; $srcY = round(($imgheight - $tmp) / 2); $imgheight = $tmp; } else { $tmp = $imgheight / $fixDivision; $srcX = round(($imgwidth - $tmp) / 2); $imgwidth = $tmp; } } $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { $black = imagecolorallocate($thumb, 0, 0, 0); imagecolortransparent($thumb, $black); } $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); self::makeImg($minitemp['type'], $thumb, $dstFile); imagedestroy($thumb); return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); } public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { $sourcedb = $waterdb = array(); if (false === ($sourcedb = self::getImgInfo($source))) return false; if (!$waterImg && !$waterText) return false; imagealphablending($sourcedb['source'], true); if ($waterImg) { $waterdb = self::getImgInfo($waterImg); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); if ($waterdb['type'] == 'png') { $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); $sourcedb['source'] = $tmp; } else { imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); } } elseif ($waterText) { list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); empty($waterFont) && $waterFont = 12; $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); $waterdb['width'] = $temp[2] - $temp[6]; $waterdb['height'] = $temp[3] - $temp[7]; unset($temp); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); if (strlen($color) != 7) return false; $R = hexdec(substr($color, 1, 2)); $G = hexdec(substr($color, 3, 2)); $B = hexdec(substr($color, 5)); self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); } $dstsrc && $source = $dstsrc; self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); isset($waterdb['source']) && imagedestroy($waterdb['source']); imagedestroy($sourcedb['source']); return true; } private static function checkAttribute($attribute) { $attribute = is_string($attribute) ? array($attribute) : $attribute; if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; return $attribute; } private static function changeCharset($charset) { $charset = strtolower($charset); return !in_array($charset, array('utf8', 'utf-8')); } private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { if (is_array($waterPos)) return $waterPos; $wX = $wY = 0; switch (intval($waterPos)) { case 0 : $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); break; case 1 : $wX = 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 2: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 3: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 4: $wX = 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 5: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 6: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; default: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; break; } return array($wX, $wY); } private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { if (false === ($imgdata = self::getImgInfo($srcFile))) return false; if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; $imgdata['dstW'] = $dstW; $imgdata['dstH'] = $dstH; if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); } elseif ($dstW > 0 && $dstH > 0) { if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); } if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); } } else { $imgdata = false; } return $imgdata; } public static function getImgInfo($srcFile) { if (false === ($imgdata = self::getImgSize($srcFile))) return false; $imgdata['type'] = self::getTypes($imgdata['type']); if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; $imgdata['source'] = $imagecreatefromtype($srcFile); !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); return $imgdata; } private static function getImgSize($srcFile, $srcExt = null) { empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); $srcdata = array(); $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); in_array($srcExt, $exts) && $srcdata['type'] = 2; if (false === ($info = getimagesize($srcFile))) return false; list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; return $srcdata; } private static function getImgcreate($imagetype) { if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { return array('imagecreatetruecolor', 'imagecopyresampled'); } if (function_exists('imagecreate') && function_exists('imagecopyresized')) { return array('imagecreate', 'imagecopyresized'); } return array('', ''); } private static function makeImg($type, $image, $filename, $quality = '75') { $makeimage = 'image' . $type; if (!function_exists($makeimage)) return false; if ($type == 'jpeg') { $makeimage($image, $filename, $quality); } else { $makeimage($image, $filename); } return true; } private static function getTypes($id) { $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; } } Wind::import('WIND:component.utility.WindFile'); class WindPack { const STRIP_SELF = 'stripWhiteSpaceBySelf'; const STRIP_PHP = 'stripWhiteSpaceByPhp'; const STRIP_TOKEN = 'stripWhiteSpaceByToken'; private $packList = array(); private $contentInjectionPosition; private $contentInjectionCallBack = ''; public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { if (empty($dst) || empty($dir)) { return false; } $suffix = is_array($suffix) ? $suffix : array( $suffix); if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { return false; } $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->stripImport($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { if (empty($dst) || empty($fileList)) { return false; } $content = array(); $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function stripWhiteSpaceByPhp($filename) { return php_strip_whitespace($filename); } public function stripWhiteSpaceBySelf($filename, $compress = true) { $content = $this->getContentFromFile($filename); $content = $this->stripComment($content, ''); return $this->stripSpace($content, ' '); } public function stripWhiteSpaceByToken($filename) { $content = $this->getContentFromFile($filename); $compressContent = ''; $lastToken = 0; foreach (token_get_all($content) as $key => $token) { if (is_array($token)) { if (in_array($token[0], array( T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) { continue; } $compressContent .= ' ' . $token[1]; } else { $compressContent .= $token; } $lastToken = $token[0]; } return $compressContent; } public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { static $content = array(); if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { return false; } $dir = is_array($dir) ? $dir : array( $dir); foreach ($dir as $_dir) { $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; if (is_dir($_dir)) { $handle = dir($_dir); while (false != ($tmp = $handle->read())) { $name = WindFile::appendSlashesToDir($_dir) . $tmp; if (is_dir($name) && !in_array($tmp, $ndir)) { $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); } if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { $content[] = $this->$packMethod($name); $this->setPackList($file, $name); } } $handle->close(); } } return $content; } public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { return array(); } $fileList = is_array($fileList) ? $fileList : array( $fileList); foreach ($fileList as $key => $value) { if (is_array($value) && isset($value[1])) { $parents = class_parents($value[1]); $_fileList = $this->buildFileList($parents, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); $implements = class_implements($value[1]); $_fileList = $this->buildFileList($implements, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); if (key_exists($key, $this->getPackList())) continue; $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; if (is_file($file)) { $content[] = $this->$packMethod($file); $this->setPackList($key, $value); } } } } public function stripComment($content, $replace = '') { return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); } public function stripNR($content, $replace = array('\n','\r\n','\r')) { return preg_replace('/[\n\r]+/', $replace, $content); } public function stripSpace($content, $replace = ' ') { return preg_replace('/[ ]+/', $replace, $content); } public function stripPhpIdentify($content, $replace = '') { return preg_replace('/(?:<\?(?:php)*)|(\)/i', $replace, $content); } public function stripStrByRule($content, $rule, $replace = '') { return preg_replace("/$rule/", $replace, $content); } public function stripImport($content, $replace = '') { $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); if ($matchs[1]) { foreach ($matchs[1] as $key => $value) { $name = substr($value, strrpos($value, '.') + 1); if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { $strip = str_replace(array( '(', ')'), array( '\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; $content = $this->stripStrByRule($content, $strip, $replace); } } } return $content; } public function getPackList() { return $this->packList; } public function getContentFromFile($filename) { if (is_file($filename)) { $content = ''; $fp = fopen($filename, "r"); while (!feof($fp)) { $line = fgets($fp); if (in_array(strlen($line), array( 2, 3)) && in_array(ord($line), array( 9, 10, 13))) continue; $content .= $line; } fclose($fp); return $content; } return false; } public function getContentBySuffix($content, $suffix, $replace = ' ') { switch ($suffix) { case 'php': $content = '' . $replace . $content . ''; break; default: $content = '' . $replace . $content . ''; break; } return $content; } private function buildFileList($list, $fileList) { $_temp = array(); foreach ($list as $fileName) { foreach ($fileList as $key => $value) { if ($value[1] == $fileName) { $_temp[$key] = $value; break; } } } return $_temp; } public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { if (!in_array($position, array( 'before', 'after'))) $position = 'before'; $this->contentInjectionPosition = $position; $this->contentInjectionCallBack = $contentInjectionCallBack; } public function callBack($content, $replace = '') { if ($this->contentInjectionCallBack !== '') { $_content = call_user_func_array($this->contentInjectionCallBack, array( $this->getPackList())); if ($this->contentInjectionPosition == 'before') { $content = $replace . $_content . $content; } elseif ($this->contentInjectionPosition == 'after') { $content .= $replace . $_content . $replace; } } return $content; } private function isValidatePackMethod($packMethod) { return method_exists($this, $packMethod) && in_array($packMethod, array( WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN)); } private function setPackList($key, $value) { if (isset($this->packList[$key])) { if (is_array($this->packList[$key])) { array_push($this->packList[$key], $value); } else { $tmp_name = $this->packList[$key]; $this->packList[$key] = array( $tmp_name, $value); } } else { $this->packList[$key] = $value; } } } class WindSecurity { public static function escapeHTML($str) { return htmlspecialchars($str, ENT_QUOTES); } public static function stripTags($str, $allowTags = "") { return strip_tags($str, $allowTags); } public static function escapePath($fileName, $ifCheck = true) { if (!self::_escapePath($fileName, $ifCheck)) { throw new WindException('file name is illegal'); } return $fileName; } public static function escapeDir($dir) { $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } public static function escapeChar($value) { if (is_array($value)) { foreach ($value as $key => $sub) { $value[$key] = self::escapeChar($sub); } } elseif (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = self::escapeString($value); } return $value; } public static function escapeString($string) { $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } public static function quotemeta($string) { return quotemeta($string); } public function checkInputValue($value, $key = '') { if (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = "'" . addslashes($value) . "'"; } elseif (is_float($value)) { $value = (float) $value; } elseif (is_object($value) || is_array($value)) { $value = "'" . addslashes(serialize($value)). "'"; } return $value; } public static function addSlashesForInput($str) { if (!get_magic_quotes_gpc()) { $str = addslashes($str); } return $str; } public static function addSlashesForOutput($str) { if (!get_magic_quotes_runtime()) { $str = addslashes($str); } return $str; } public static function addSlashes($value, $gpc = false, $df = false) { if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable) )) { return $value; } if(is_string($value)){ if (false === $gpc && true === $df) { return self::addSlashesForOutput($value); } if (false === $df && true === $gpc) { return self::addSlashesForInput($value); } return addslashes($value); } foreach($value as $key=>$_value){ $value[$key] = self::addSlashes($_value,$gpc,$df); } return $value; } public static function stripSlashes($value) { if (!$value) return $value; if (is_string($value)) return stripslashes($value); if (!is_array($value) && !($value instanceof Traversable)) return $value; foreach ($value as $key => $_value) { $value[$key] = self::stripSlashes($_value); } return $value; } public static function sqlEscape($var, $strip = true, $isArray = false) { if (is_array($var)) { if (!$isArray) return " '' "; foreach ($var as $key => $value) { $var[$key] = trim(self::sqlEscape($value, $strip)); } return $var; } elseif (is_numeric($var)) { return " '" . $var . "' "; } else { return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; } } public static function sqlImplode($array, $strip = true) { return implode(',', self::sqlEscape($array, $strip, true)); } public static function sqlSingle($array, $strip = true) { if (!is_array($array)) return ''; $array = self::sqlEscape($array, $strip, true); $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; } return $str; } public static function sqlMulti($array, $strip = true) { if (!is_array($array)) { return ''; } $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; } } return $str; } public static function sqlMetadata($data ,$tlists=array()) { if (empty($tlists) || !in_array($data , $tlists)) { $data = str_replace(array('`', ' '), '',$data); } return ' `'.$data.'` '; } private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; if (strtr($tmpname, $tmparray) != $tmpname) { return false; } return true; } } class WindString { const UTF8 = 'utf8'; const GBK = 'gbk'; public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( $string, $start, $length, $dot); } public static function strlen($string, $charset = self::UTF8) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; $count++; } return $count; } public static function varToString($input, $indent = '') { switch (gettype($input)) { case 'string': return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; case 'array': $output = "array(\r\n"; foreach ($input as $key => $value) { $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( $value, $indent . "\t"); $output .= ",\r\n"; } $output .= $indent . ')'; return $output; case 'boolean': return $input ? 'true' : 'false'; case 'NULL': return 'NULL'; case 'integer': case 'double': case 'float': return "'" . (string) $input . "'"; } return 'NULL'; } public static function jsonEncode($value) { if (!function_exists('json_encode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); } public static function jsonDecode($value) { if (!function_exists('json_decode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); } public static function jsonSimpleEncode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': return '"' . addslashes( str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; case 'array': if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array(); foreach ($var as $name => $value) { $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( $value); } return '{' . join(',', $properties) . '}'; } $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); return '[' . join(',', $elements) . ']'; } return false; } public static function utf8_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j += 2; } else { $word++; } $j++; } $start = $word + 3 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 3); $j += 2; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function utf8_strlen($str) { $i = $count = 0; $len = strlen($str); while ($i < $len) { $chr = ord($str[$i]); $count++; $i++; if ($i >= $len) break; if ($chr & 0x80) { $chr <<= 1; while ($chr & 0x80) { $i++; $chr <<= 1; } } } return $count; } public static function gbk_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j++; } else { $word++; } $j++; } $start = $word + 2 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 2); $j++; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function gbk_strlen($string) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? $i += 2 : $i++; $count++; } return $count; } } class WindUtility { public static function mergeArray($array1, $array2) { foreach ($array2 as $key => $value) { if (!isset($array1[$key]) || !is_array($array1[$key])) { $array1[$key] = $value; continue; } $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); } return $array1; } public static function lcfirst($str) { if (function_exists('lcfirst')) return lcfirst($str); $str[0] = strtolower($str[0]); return $str; } public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { $randnum = rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { $randstr .= chr($randnum + 55); } else { $randstr .= chr($randnum + 61); } } return $randstr; } public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } class WindValidator { public static function isTelPhone($phone) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); } public static function isTelNumber($number) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); } public static function isQQ($qq) { return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); } public static function isZipcode($zipcode) { return 0 < preg_match('/^\d{4,8}$/', $zipcode); } public static function hasEmail($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); } public static function isEmail($string) { return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); } public static function hasIdCard($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); } public static function isIdCard($string) { return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); } public static function hasUrl($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); } public static function isUrl($string) { return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); } public static function hasChinese($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); } public static function isChinese($string) { return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); } public static function hasHtml($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); } public static function isHtml($string) { return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); } public static function hasIpv4($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); } public static function isIpv4($string) { return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); } public static function hasIpv6($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| ::([a-f0-9]{1,4}:){5}| ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )([a-f0-9]{1,4}:[a-f0-9]{1,4}| (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string, $matches, $ifAll); } public static function isIpv6($string) { return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| ::(?:[a-f0-9]{1,4}:){5}| (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string); } public static function hasScript($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); } public static function isScript($string) { return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); } public static function isEmpty($value) { return empty($value); } public static function isNonNegative($number) { return 0 <= (int) $number; } public static function isPositive($number) { return 0 < (int) $number; } public static function isNegative($number) { return 0 > (int) $number; } public static function isArray($array) { return is_array($array); } public static function isRequired($value) { return !self::isEmpty($value); } public static function inArray($needle, array $array, $strict = true) { return in_array($needle, $array, $strict); } public static function isLegalLength($string, $length, $charset = 'utf8') { Wind::import('WIND:component.utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { if (true === $ifAll) { return preg_match_all($regExp, $string, $matches); } return preg_match($regExp, $string, $matches); } }?> \ No newline at end of file From ee4b01c76b95bc6fdbf67343ce94978cc94c69eb Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 24 Aug 2011 04:49:41 +0000 Subject: [PATCH 0389/1065] =?UTF-8?q?bug=20fixted:=20dbHandler=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2461 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/db/WindConnection.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 48c389a0..9db72f41 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -60,6 +60,8 @@ public function createStatement($sql = null) { * @return WindMysqlPdoAdapter */ public function getDbHandle() { + if ($this->_dbHandle === null) + $this->init(); return $this->_dbHandle; } From b20f4107e0901a25a58f41e272de100969a721af Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 24 Aug 2011 04:56:28 +0000 Subject: [PATCH 0390/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2462 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/dao/WindDao.php | 74 ++----------------------- wind/component/dao/WindDaoFactory.php | 77 +++------------------------ 2 files changed, 11 insertions(+), 140 deletions(-) diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php index abae1e17..567e87ab 100644 --- a/wind/component/dao/WindDao.php +++ b/wind/component/dao/WindDao.php @@ -8,77 +8,21 @@ * @package */ class WindDao extends WindModule { - /** - * 链接配置文件或是配置数组 - * @var string|array - */ - protected $dbName = ''; - /** - * cache类型定义 - * - * @var string - */ - protected $cacheClass = ''; - /** - * cache配置信息 - * - * @var string - */ - protected $cacheConfig = ''; - /** * @var object */ protected $connection = null; - protected $cacheHandler = null; - - /** - * 获得需要缓存的处理的方法名称数组 - * array('methodName1'=>'WIND:component') - * @return multitype: - */ - public function getCacheMethods() { - return array(); - } /** * 根据用户配置决定配置是采用配置链接管理 * @return WindConnection */ public function getConnection($name = '') { - $this->_getConnection(); - if ($this->connection instanceof WindConnectionManager) { - return $this->connection->getConnection($name); - } - return $this->connection; - } - - /** - * @return WindCacheDb - */ - public function getCacheHandler() { - return $this->_getCacheHandler(); - } - - /** - * @return the $configName - */ - public function getDBName() { - return $this->dbName; - } - - /** - * @return the $cacheClass - */ - public function getCacheClass() { - return $this->cacheClass; - } - - /** - * @return the $cacheConfig - */ - public function getCacheConfig() { - return $this->cacheConfig; + $this->_getConnection(); + if ($this->connection instanceof WindConnectionManager) { + return $this->connection->getConnection($name); + } + return $this->connection; } /** @@ -87,13 +31,5 @@ public function getCacheConfig() { public function setConnection($connection) { $this->connection = $connection; } - - /** - * @param field_type $cacheHandler - */ - public function setCacheHandler($cacheHandler) { - $this->cacheHandler = $cacheHandler; - } - } ?> \ No newline at end of file diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php index 0bf4d1f5..009e610d 100644 --- a/wind/component/dao/WindDaoFactory.php +++ b/wind/component/dao/WindDaoFactory.php @@ -14,15 +14,8 @@ * @package */ class WindDaoFactory extends WindModule { - /** - * dao 实例数组 - * - * @var array - */ - private $daos = array(); /** * dao路径信息 - * * @var string */ protected $daoResource = ''; @@ -38,19 +31,16 @@ class WindDaoFactory extends WindModule { */ public function getDao($className) { try { - if (strpos($className, ":") === false && strpos($className, ".") === false) { + if (strpos($className, ":") === false) $className = $this->getDaoResource() . '.' . $className; - } - if (isset($this->daos[$className])) return $this->daos[$className]; - - $className = Wind::import($className); - $daoInstance = WindFactory::createInstance($className); - $this->createDbConnection($daoInstance); - $this->createCacheHandler($daoInstance); + Wind::getApp()->getWindFactory()->addClassDefinitions($className, + array('path' => $className, 'scope' => 'application')); + $daoInstance = Wind::getApp()->getWindFactory()->getInstance($className); + $daoInstance->setDelayAttributes(array('connection' => array('ref' => 'db'))); return $daoInstance; } catch (Exception $exception) { throw new WindDaoException( - '[component.dao.WindDaoFactory] create dao ' . $className . ' fail. Error message:' . $exception->getMessage()); + '[component.dao.WindDaoFactory] create dao ' . $className . ' fail.' . $exception->getMessage()); } } @@ -69,60 +59,5 @@ public function getDaoResource() { public function setDaoResource($daoResource) { $this->daoResource = $daoResource; } - - /** - * 注册Dao缓存监听 - * @param WindDao daoInstance - */ - private function registerCacheListener($daoInstance) { - $caches = (array) $daoInstance->getCacheMethods(); - foreach ($caches as $classMethod => $classPath) { - if (!$classMethod) continue; - if ($classPath === 'default') - $_className = Wind::import('COM:dao.listener.WindDaoCacheListener'); - else - $_className = Wind::import($classPath); - if (!$_className) continue; - $daoInstance->registerEventListener($classMethod, new $_className($daoInstance)); - } - } - - /** - * 创建db链接句柄 - * - * @param WindDao $daoObject - */ - protected function createDbConnection($daoObject) { - $configName = $daoObject->getDBName(); - $config = $this->getSystemConfig()->getDbConfig($configName); - if (!$config) throw new WindDbException( - '[component.dao.WindDaoFactory.createDbConnection] (' . $configName . ')', - WindDbException::DB_CONN_NOT_EXIST); - - $path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); - $alias = $configName ? $path . $configName : $path . get_class($this); - $definition = array('path' => $path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', 'scope' => 'application'); - $this->getSystemFactory()->addClassDefinitions($alias, $definition); - $daoObject->setDelayAttributes(array('connection' => array('ref' => $alias))); - } - - /** - * 创建cache句柄 - * - * @param WindDao $daoObject - */ - protected function createCacheHandler($daoObject) { - if (!($_className = $daoObject->getCacheClass())) return; - $_classConfig = $daoObject->getCacheConfig(); - $_alias = $_className . '_' . md5((is_string($_classConfig) ? $_classConfig : serialize($_classConfig))); - if (!$this->getSystemFactory()->checkAlias($_alias)) { - $definition = array('path' => $_className, 'alias' => $_alias, 'initMethod' => 'init', 'scope' => 'singleton'); - $definition['config'] = is_array($_classConfig) ? $_classConfig : array('resource' => $_classConfig); - $this->getSystemFactory()->addClassDefinitions($_alias, $definition); - } - $daoObject->setDelayAttributes(array('cacheHandler' => array('ref' => $_alias))); - $daoObject = new WindClassProxy($daoObject); - $this->registerCacheListener($daoObject); - } } ?> \ No newline at end of file From e2a5e60d35bc7569ce294b059e5d7fdc8be32399 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 24 Aug 2011 05:09:47 +0000 Subject: [PATCH 0391/1065] =?UTF-8?q?xml=E6=A0=BC=E5=BC=8F=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2463 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/parser/WindXmlParser.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wind/component/parser/WindXmlParser.php b/wind/component/parser/WindXmlParser.php index 1df04590..cee4d7a6 100644 --- a/wind/component/parser/WindXmlParser.php +++ b/wind/component/parser/WindXmlParser.php @@ -62,7 +62,10 @@ public function getChilds($node) { foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); - (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; + if (3 == $node->nodeType) { + $value = trim($node->nodeValue); + (is_numeric($value) || $value) && $childs[0] = $value;//值为0的情况 + } if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; @@ -103,4 +106,4 @@ public function getAttributes($node) { return $attributes; } } -?> \ No newline at end of file +?> From be46d1917ff32177fda4990dc88c369deb8a76fc Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 01:55:33 +0000 Subject: [PATCH 0392/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2464 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/wind/components_config.php b/wind/components_config.php index 97cfd8b3..a023197a 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -13,10 +13,10 @@ ), 'windLogger' => array( 'path' => 'COM:log.WindLogger', - 'scope' => 'application', + 'scope' => 'singleton', 'constructor-arg' => array( '0' => array( - 'value' => '', + 'value' => 'data.log', ), '1' => array( 'value' => '0', @@ -40,10 +40,6 @@ 'path' => 'COM:router.WindRouter', 'scope' => 'application', ), - 'urlRewriteRouter' => array( - 'path' => 'COM:router.WindUrlRewriteRouter', - 'scope' => 'singleton', - ), 'urlHelper' => array( 'path' => 'WIND:core.web.WindUrlHelper', 'scope' => 'application', @@ -75,6 +71,13 @@ 'path' => 'COM:viewer.compiler.WindViewTemplate', 'scope' => 'prototype', ), + 'db' => array( + 'path' => 'COM:db.WindConnection', + 'scope' => 'singleton', + 'config' => array( + 'resource' => 'db_config.xml', + ), + ), 'errorMessage' => array( 'path' => 'WIND:core.web.WindErrorMessage', 'scope' => 'prototype', @@ -86,18 +89,15 @@ 'windCache' => array( 'path' => 'COM:cache.strategy.WindFileCache', 'config' => array( - 'dir' => 'compile', - 'dbconfig-name' => 'default', - 'table-name' => 'cache', - 'field-key' => 'key', - 'field-value' => 'value', - 'field-expire' => 'expire', + 'dir' => 'data.config', + 'suffix' => 'php', + 'expires' => '', ), ), 'viewCache' => array( 'path' => 'COM:cache.strategy.WindFileCache', 'config' => array( - 'dir' => 'compile.cache', + 'dir' => 'data.view', 'suffix' => 'php', 'expires' => '10', ), From 1f517dd526a1f0e5dd023a1b6eace049f9c00996 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 08:32:07 +0000 Subject: [PATCH 0393/1065] =?UTF-8?q?bug=20fixted:=20log=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2465 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/log/WindLogger.php | 51 +++++++++++++------------------ 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php index 9eb2be0d..60dac919 100644 --- a/wind/component/log/WindLogger.php +++ b/wind/component/log/WindLogger.php @@ -12,9 +12,8 @@ class WindLogger extends WindModule { const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; - const WRITE_ALL = 0; - const WRITE_LEVEL = 1; const WRITE_TYPE = 2; + const WRITE_LEVEL = 1; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; /** @@ -33,7 +32,7 @@ class WindLogger extends WindModule { * 2: 按照type分文件存储日志记录 * @var int */ - private $_writeType = '0'; + private $_writeType = 0; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); @@ -100,8 +99,9 @@ public function profileEnd($msg, $type = 'wind.core', $flush = false) { * @param const $logType 日志类别 */ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { - if (!$this->_logDir) return; - if ($this->_writeType == self::WRITE_TYPE) + if (!$this->_logDir) + return; + if ($this->_writeType & self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); @@ -129,29 +129,25 @@ public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); - $_l = array(); + $_l = $_logTypes = $_logLevels = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); - if ($this->_writeType == self::WRITE_LEVEL) { - $_logs = array(); - foreach ($this->_logs as $key => $value) { - $_l[] = $value[2]; - $_logs[$value[0]][] = $value[2]; - } - foreach ($_logs as $key => $value) { - $key = isset($_map[$key]) ? $_map[$key] : 'all'; + + foreach ($this->_logs as $key => $value) { + $_l[] = $value[2]; + $_logTypes[$value[1]][] = $value[2]; + $_logLevels[$value[0]][] = $value[2]; + } + if ($this->_writeType & 1) { + foreach ($_logLevels as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } - } elseif ($this->_writeType == self::WRITE_TYPE) { - $_logs = array(); - foreach ($this->_logs as $key => $value) { - $_l[] = $value[2]; - $_logs[$value[1]][] = $value[2]; - } - foreach ($_logs as $key => $value) { + } + if ($this->_writeType & 2) { + foreach ($_logTypes as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); @@ -193,23 +189,18 @@ public function getMemoryUsage($peak = true) { * @return string */ private function _build($msg, $level, $type, $timer = 0, $mem = 0) { - $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: - $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: - $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: - $msg .= "\t(" . $type . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: - $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: @@ -235,17 +226,17 @@ private function _buildProfile($msg, $type, $timer, $mem) { $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { - $_msg = "PROFILE! Message: \r\n"; + $_msg = "PROFILE! Message:"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) - $_msg .= $profile[1] . "\r\n"; + $_msg .= "\r\n\t" . $profile[1]; else - $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; - $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; + $_msg .= "\r\n\t" . substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1); + $_msg .= "\r\n\tTime:" . ($timer - $profile[3]) . "\r\n\tMem:" . ($mem - $profile[4]) . "\r\n\tType:$profile[2]"; break; } unset($this->_profiles[$key]); From 33bfd3ddf7c15fb86545f37cefbb3f278e4722be Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 08:32:50 +0000 Subject: [PATCH 0394/1065] =?UTF-8?q?bug=20fixted:=20=E6=9C=89=E4=B8=AAbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2466 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/utility/WindFile.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/wind/component/utility/WindFile.php b/wind/component/utility/WindFile.php index 29156154..80e8b9c3 100644 --- a/wind/component/utility/WindFile.php +++ b/wind/component/utility/WindFile.php @@ -52,7 +52,8 @@ public static function savePhpData($fileName, $data, $isBuildReturn = true, $met $temp = " $value) { - if (!preg_match('/^\w+$/', $key)) continue; + if (!preg_match('/^\w+$/', $key)) + continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n?>"; @@ -77,7 +78,8 @@ public static function savePhpData($fileName, $data, $isBuildReturn = true, $met public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); - if (!$handle = fopen($fileName, $method)) return false; + if (!$handle = fopen($fileName, $method)) + return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); @@ -113,9 +115,11 @@ public static function read($fileName, $method = self::READ) { */ public static function clearDir($dir, $ifexpiled = false) { //TODO 删除掉是否过期相关处理,不要将外部业务需求,耦合进工具库方法 - if (!$handle = @opendir($dir)) return false; + if (!$handle = @opendir($dir)) + return false; while (false !== ($file = readdir($handle))) { - if ('.' === $file[0] || '..' === $file[0]) continue; + if ('.' === $file[0] || '..' === $file[0]) + continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); @@ -162,8 +166,9 @@ public static function delFiles($path, $delDir = false, $level = 0) { * @return string */ public static function getMimeType($fileName) { + //TODO WindMimeTypes.php 被删掉了,有bug $suffix = self::getFileSuffix($fileName); - $mimes = require rtrim(WIND_PATH, D_S) . D_S . 'component/utility/WindMimeTypes.php'; + $mimes = require WIND_PATH . '/component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { From f11ddd2b3f6dc42f561caa06371326248bf22755 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 08:33:49 +0000 Subject: [PATCH 0395/1065] =?UTF-8?q?bug=20fixted:=20=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=8C=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=98=AF=E6=8E=92=E9=99=A4=20=E9=9D=99=E6=80=81?= =?UTF-8?q?=E7=B1=BB=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2467 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/compiler/WindTemplateCompilerEcho.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index 93477c47..35d1d114 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -21,7 +21,7 @@ class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { public function compile($key, $content) { $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content); list($_output, $type) = explode('|', $_output . '|'); - if (strpos($_output, ':') !== false) { + if (strpos($_output, '::') === false && strpos($_output, ':') !== false) { list($_namespace, $_var) = explode(':', $_output); $_output = 'Wind::getApp()->getResponse()->getData(\'' . $_namespace . '\', \'' . $_var . '\')'; } From 81e091739e723e724126e19040b1d14c0d571a14 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 08:36:46 +0000 Subject: [PATCH 0396/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E6=B7=BB=E5=8A=A0=E6=A8=A1=E6=9D=BF=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E8=A7=84=E5=88=99=EF=BC=8Cdebug=E6=A8=A1=E5=BC=8F=E4=B8=8B?= =?UTF-8?q?=EF=BC=8Ciscompile=E4=B8=BA=E9=9D=9E=E2=80=980=E2=80=99=20?= =?UTF-8?q?=E6=97=B6=20=E9=83=BD=E4=BC=9A=E5=8E=BB=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2468 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindViewerResolver.php | 28 +++++++------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index c63c6948..6aa1c438 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -71,17 +71,18 @@ public function compile($template, $suffix = '', $output = false) { if (!is_file($templateFile)) throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, WindViewException::VIEW_NOT_EXIST); - - /* @var $_windTemplate WindViewTemplate */ + + $compileFile = $this->windView->getCompileFile($template); + if (!$this->checkReCompile($templateFile, $compileFile)) + return array($compileFile, ''); + /* @var $_windTemplate WindViewTemplate */ $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); $_output = $_windTemplate->compile($templateFile, $this); - if ($output === true) - return array('', $_output); - else { + if ($output === false) { $compileFile = $this->windView->getCompileFile($template); WindFile::write($compileFile, $_output); - return array($compileFile, $_output); } + return array($compileFile, $_output); } /** @@ -102,22 +103,13 @@ protected function render($template) { } /** - * 检查是否需要重新编译 + * 检查是否需要重新编译,需要编译返回false,不需要编译返回true * @param string $templateFile * @param string $compileFile + * @return boolean */ private function checkReCompile($templateFile, $compileFile) { - $_reCompile = false; - if (IS_DEBUG) { - $_reCompile = true; - } elseif (false === ($compileFileModifyTime = @filemtime($compileFile))) { - $_reCompile = true; - } else { - $templateFileModifyTime = @filemtime($templateFile); - if ((int) $templateFileModifyTime >= $compileFileModifyTime) - $_reCompile = true; - } - return $_reCompile; + return WIND_DEBUG || $this->getWindView()->isCompile || !is_file($compileFile); } /** From e052415aac1d581c9232f94e652d800d2b99e2dc Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 08:37:51 +0000 Subject: [PATCH 0397/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=88=A0=E9=99=A4=E7=BC=96=E8=AF=91=E6=98=AF=E5=AF=B9?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=96=87=E4=BB=B6=E8=BF=9B=E8=A1=8C=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E7=9A=84=E8=BF=87=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2469 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindViewerResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index 6aa1c438..74ccd9fb 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -109,7 +109,7 @@ protected function render($template) { * @return boolean */ private function checkReCompile($templateFile, $compileFile) { - return WIND_DEBUG || $this->getWindView()->isCompile || !is_file($compileFile); + return WIND_DEBUG || $this->getWindView()->isCompile; } /** From 6ac2c0ca6ba670116f9d3e77aea5742abd0a54f9 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 08:41:24 +0000 Subject: [PATCH 0398/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=88=A0=E9=99=A4=E7=BC=96=E8=AF=91=E6=98=AF=E5=AF=B9?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=96=87=E4=BB=B6=E8=BF=9B=E8=A1=8C=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E7=9A=84=E8=BF=87=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2470 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindView.php | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 3f630c98..2854f9e1 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -38,45 +38,40 @@ class WindView extends WindModule implements IWindView { public $templateName; /** * 是否对模板变量进行html字符过滤 - * * @var boolean */ public $htmlspecialchars = true; /** * 是否开启模板编译 - * + * 00: 0 关闭,不进行模板编译 + * 01: 1 进行模板编译 * @var boolean */ - public $isCompile = false; + public $isCompile = 0; /** * 编译目录 - * * @var string */ public $compileDir; /** * 编译脚本后缀 - * * @var string */ public $compileExt = 'tpl'; /** * 视图解析引擎 - * * @var WindViewerResolver */ protected $viewResolver = null; /** * 布局文件 - * * @var string */ protected $layout; /** * 视图渲染 - * * @param WindForward $forward * @param WindUrlBasedRouter $router */ @@ -126,8 +121,9 @@ public function setConfig($config) { public function getViewTemplate($template = '', $ext = '') { if (!$template) { $template = $this->templateName; - } elseif (is_file($template)) - return $template; + } + /* elseif (is_file($template)) + return $template; */ !$ext && $ext = $this->templateExt; return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); } @@ -145,10 +141,11 @@ public function getCompileFile($template = '') { return; if (!$template) { $template = $this->templateName; - } elseif (is_file($template)) { + } + /*elseif (is_file($template)) { $_info = pathinfo($template); $template = $_info['filename']; - } + }*/ $dir = Wind::getRealDir($this->compileDir); if (!is_dir($dir)) throw new WindViewException( @@ -156,7 +153,7 @@ public function getCompileFile($template = '') { $_tmp = explode('.', $template); foreach ($_tmp as $_dir) { !is_dir($dir) && @mkdir($dir); - $dir .= D_S . $_dir; + $dir .= DIRECTORY_SEPARATOR . $_dir; } return $this->compileExt ? $dir . '.' . $this->compileExt : $dir; } From f527ecade317938413da89d46ea363b03e276a98 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 08:41:43 +0000 Subject: [PATCH 0399/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=88=A0=E9=99=A4=E7=BC=96=E8=AF=91=E6=98=AF=E5=AF=B9?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=96=87=E4=BB=B6=E8=BF=9B=E8=A1=8C=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E7=9A=84=E8=BF=87=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2471 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 2 +- _compile/components_config.php | 15 ++++++--------- _compile/config/components_config.xml | 21 ++++++++------------- _compile/wind_basic.php | 2 +- 4 files changed, 16 insertions(+), 24 deletions(-) diff --git a/_compile/compile.php b/_compile/compile.php index 1651e571..1c839c3f 100644 --- a/_compile/compile.php +++ b/_compile/compile.php @@ -42,7 +42,7 @@ if (is_file(_COMPILE_PATH . 'config/' . $file) && $file !== '.' && $file !== '..') { $result = $windConfigParser->parse(_COMPILE_PATH . 'config/' . $file); $file = preg_replace('/\.(\w)*$/i', '', $file); - WindFile::write(_COMPILE_PATH . $file . '.php', + WindFile::write(WIND_PATH . $file . '.php', ' array( 'path' => 'COM:log.WindLogger', - 'scope' => 'application', + 'scope' => 'singleton', 'constructor-arg' => array( '0' => array( - 'value' => '', + 'value' => 'data.log', ), '1' => array( 'value' => '0', @@ -89,18 +89,15 @@ 'windCache' => array( 'path' => 'COM:cache.strategy.WindFileCache', 'config' => array( - 'dir' => 'compile', - 'dbconfig-name' => 'default', - 'table-name' => 'cache', - 'field-key' => 'key', - 'field-value' => 'value', - 'field-expire' => 'expire', + 'dir' => 'data.config', + 'suffix' => 'php', + 'expires' => '', ), ), 'viewCache' => array( 'path' => 'COM:cache.strategy.WindFileCache', 'config' => array( - 'dir' => 'compile.cache', + 'dir' => 'data.view', 'suffix' => 'php', 'expires' => '10', ), diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index 18b137e9..443bb38e 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -15,8 +15,8 @@
- - + + + - compile - default - - cache - - key - - value - - expire + data.config + php + 0 + - compile.cache + data.view php 10 diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php index 8aebd722..69543277 100644 --- a/_compile/wind_basic.php +++ b/_compile/wind_basic.php @@ -1 +1 @@ -$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { $key = isset($_map[$key]) ? $_map[$key] : 'all'; if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias])) throw new WindException( '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); $definition = $this->classDefinitions[$alias]; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (!$className) throw new WindException('class name is required.'); if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (is_string($alias) && !empty($alias)) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, $this->getInstance('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { return $this->windFactory->getInstance($componentName); } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = $msghtml = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $msg = "$file\n"; $msghtml = "$file\n"; if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $msg .= implode("\n", $fileLines) . "\n"; $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $msghtml .= implode("\n", $fileLines) . "\n"; } } $msg .= "$errtrace\n"; $msghtml .= "$errtrace\n"; } $msghtml .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; $msghtml = "$topic

$topic

$errmessage\n$msghtml
"; $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); $msghtml = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msghtml); Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', true); die($_errhtml ? $msghtml : $msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } class WindDate { public static function getTimeZone() { return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); } public static function setTimezone($timezone) { function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); } public static function format($format = null, $dateTime = null) { return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); } public static function datePart($interval, $dateTime = null) { return date($interval, self::getTimeStamp($dateTime)); } public static function dateDiff($interval, $startDateTime, $endDateTime) { $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); $retval = 0; switch ($interval) { case "y": $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; case "m": $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; case "w": $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; case "d": $retval = bcdiv($diff, (60 * 60 * 24));break; case "h": $retval = bcdiv($diff, (60 * 60));break; case "n": $retval = bcdiv($diff, 60);break; case "s": default:$retval = $diff;break; } return $retval; } public static function dateAdd($interval, $value, $dateTime, $format = null) { $date = getdate(self::getTimeStamp($dateTime)); switch ($interval) { case "y": $date["year"] += $value;break; case "q": $date["mon"] += ($value * 3);break; case "m": $date["mon"] += $value;break; case "w": $date["mday"] += ($value * 7);break; case "d": $date["mday"] += $value;break; case "h": $date["hours"] += $value;break; case "n": $date["minutes"] += $value;break; case "s": default:$date["seconds"] += $value;break; } return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); } public static function getRealDaysInMonthsOfYear($year) { $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if (self::isLeapYear($year)) { $months[1] = 29; } return $months; } public static function getDaysInMonth($month, $year) { if (1 > $month || 12 < $month) { return 0; } if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { return 0; } return $daysInmonths[$month - 1]; } public static function getDaysInYear($year) { return self::isLeapYear($year) ? 366 : 365; } public static function getRFCDate($date = null) { $time = $date ? is_int($date) ? $date : strtotime($date) : time(); $tz = date('Z', $time); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); } public static function getChinaDate($time = null) { list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); } public static function getChinaWeek($week = null) { $week = $week ? $week : (int) date('w', time()); $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); return $weekMap[$week]; } public static function getPeriodOfTime($hour = null) { $hour = $hour ? $hour : (int) date('G', time()); $period = ''; if (0 <= $hour && 6 > $hour) { $period = '凌晨'; } elseif (6 <= $hour && 8 > $hour) { $period = '早上'; } elseif (8 <= $hour && 11 > $hour) { $period = '上午'; } elseif (11 <= $hour && 13 > $hour) { $period = '中午'; } elseif (13 <= $hour && 15 > $hour) { $period = '响午'; } elseif (15 <= $hour && 18 > $hour) { $period = '下午'; } elseif (18 <= $hour && 20 > $hour) { $period = '傍晚'; } elseif (20 <= $hour && 22 > $hour) { $period = '晚上'; } elseif (22 <= $hour && 23 >= $hour) { $period = '深夜'; } return $period; } public static function getUTCDate($dateTime = null) { $oldTimezone = self::getTimezone(); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone('UTC'); } $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone($oldTimezone); } return $date; } public static function getMicroTime($get_as_float = null,$mircrotime = null) { return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); } public static function isLeapYear($year) { if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { return true; } return false; } public static function getTimeStamp($dateTime = null){ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); } public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); $timestamp = $timestamp ? $timestamp : time(); $compareTime = strtotime(self::format('Y-m-d',$timestamp)); $currentTime = strtotime(self::format('Y-m-d',$time)); $decrease = $timestamp - $time; $result = self::format($format,$time); if (0 >= $decrease) { return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } if ($currentTime == $compareTime) { if (1 == $type) { if (60 >= $decrease) { return array($decrease . $timelang['second'], $result); } return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); } return array(self::format('H:i',$time), $result); } elseif ($currentTime == $compareTime - 86400) { return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); } elseif ($currentTime == $compareTime - 172800) { return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); } return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } } class WindGeneralDate { const FILL = 0; const DIGIT = 1; const TEXT = 2; const DEFAULT_FORMAT = 'Y-m-d H:i:s'; private $time = 0; public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { $time = time(); !$month && ((!$year) ? $month = date('m', $time) : $month = 1); !$day && ((!$year) ? $day = date('d', $time) : $day = 1); !$hours && !$year && $hours = date('H', $time); !$minutes && !$year && $minutes = date('i', $time); !$second && !$year && $second = date('s', $time); !$year && $year = date('Y', $time); $this->time = mktime($hours, $minutes, $second, $month, $day, $year); } public function getDaysInMonth() { return date('t', $this->time); } public function getDaysInYear() { return $this->isLeapYear() ? 366 : 365; } public function getDayOfYear() { return date('z', $this->time) + 1; } public function getDayOfMonth() { return date('j', $this->time); } public function getDayOfWeek() { return date('w', $this->time) + 1; } public function getWeekOfYear() { return date('W', $this->time); } public function getYear($format = true) { return date($format ? 'Y' : 'y', $this->time); } public function getMonth($display = self::FILL) { if(self::FILL == $display){ return date('m', $this->time); }elseif(self::DIGIT == $display){ return date('n', $this->time); }elseif(self::TEXT == $display){ return date('M', $this->time); } return date('n', $this->time); } public function getDay($display = self::FILL) { if(self::FILL == $display){ return date('d', $this->time); }elseif(self::DIGIT == $display){ return date('j', $this->time); }elseif(self::TEXT == $display){ return date('jS', $this->time); } return date('j', $this->time); } public function getWeek($display = self::FILL) { if(self::FILL == $display || self::DIGIT == $display){ return date('w', $this->time); }elseif(self::TEXT == $display){ return date('D', $this->time); } return date('N', $this->time); } public function get12Hours($display = self::FILL){ if(self::FILL == $display){ return date('h', $this->time); }elseif(self::DIGIT == $display){ return date('g', $this->time);; } return date('h', $this->time); } public function get24Hours($display = self::FILL){ if(self::FILL == $display){ return date('H', $this->time); }elseif(self::DIGIT == $display){ return date('G', $this->time);; } return date('H', $this->time); } public function getMinutes() { return date('i', $this->time); } public function getSeconds() { return date('s', $this->time); } public function getLocalTimeZone() { return date('T', $this->time); } public function setTime($time) { if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { $this->time = $time; } } public function getNow() { $date = getdate($this->time); return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); } public function __toString() { return $this->toString(); } public function toString($format = null) { return date($format ? $format : self::DEFAULT_FORMAT, $this->time); } public function isLeapYear() { return date('L', $this->time); } } class WindDecoder { const JSON_SLICE = 1; const JSON_IN_STR = 2; const JSON_IN_ARR = 4; const JSON_IN_OBJ = 8; const JSON_IN_CMT = 16; public static function decode($str, $useArray = true) { $str = strtolower(self::reduceString($str)); if ('true' == $str) { return true; } elseif ('false' == $str) { return false; } elseif ('null' == $str) { return null; } elseif (is_numeric($str)) { return (float)$str == (integer)$str ? (integer) $str : (float) $str; }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ return self::jsonToString($str); }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); } return false; } protected static function jsonToString($string) { $delim = substr($string, 0, 1); $chrs = substr($string, 1, -1); $decodeStr = ''; for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { $compare = substr($chrs, $c, 2); $ordCode = ord($chrs{$c}); if('\b' == $compare){ $decodeStr .= chr(0x08); ++$c; }elseif('\t' == $compare){ $decodeStr .= chr(0x09); ++$c; }elseif('\n' == $compare){ $decodeStr .= chr(0x0A); ++$c; }elseif('\f' == $compare){ $decodeStr .= chr(0x0C); ++$c; }elseif('\r' == $compare){ $decodeStr .= chr(0x0D); ++$c; }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { $decodeStr .= $chrs{++$c}; } }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $decodeStr .= self::utf16beToUTF8($utf16); $c += 5; }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ $decodeStr .= $chrs{$c}; }elseif(0xC0 == ($ordCode & 0xE0)){ $decodeStr .= substr($chrs, $c, 2); ++$c; }elseif(0xE0 == ($ordCode & 0xF0)){ $decodeStr .= substr($chrs, $c, 3); $c += 2; }elseif(0xF0 == ($ordCode & 0xF8)){ $decodeStr .= substr($chrs, $c, 4); $c += 3; }elseif(0xF8 == ($ordCode & 0xFC)){ $decodeStr .= substr($chrs, $c, 5); $c += 4; }elseif(0xFC == ($ordCode & 0xFE)){ $decodeStr .= substr($chrs, $c, 6); $c += 5; } } return $decodeStr; } protected static function jsonToArray($str) { return self::complexConvert($str,true); } protected static function jsonToObject($str) { return self::complexConvert($str,false); } protected static function complexConvert($str,$useArray = true){ if ('[' == $str{0}) { $stk = array(self::JSON_IN_ARR); $arr = array(); } else { $obj = $useArray ? array() : new stdClass(); $stk = array(self::JSON_IN_OBJ); } array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = self::reduceString($chrs); if ('' == $chrs) { return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; } for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); if (reset($stk) == self::JSON_IN_ARR) { array_push($arr, self::decode($slice, $useArray)); } elseif (reset($stk) == self::JSON_IN_OBJ) { if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $key = self::decode($parts[1], $useArray); $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { array_pop($stk); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { array_pop($stk); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { array_pop($stk); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { array_pop($stk); for ($i = $top['where']; $i <= ++$c; ++$i){ $chrs = substr_replace($chrs, ' ', $i, 1); } } } if (self::JSON_IN_ARR == reset($stk)) { return $arr; } elseif (self::JSON_IN_OBJ == reset($stk)) { return $obj; } return false; } protected static function unicodeToUTF8(&$str) { $utf8 = ''; foreach ($str as $unicode) { if ($unicode < 128) { $utf8 .= chr($unicode); } elseif ($unicode < 2048) { $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } else { $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } } return $utf8; } protected static function reduceString($str) { return trim(preg_replace(array( '#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str)); } protected static function utf16beToUTF8(&$str) { return self::unicodeToUTF8(unpack('n*', $str)); } } class WindEncoder { public static $charset = 'utf-8'; public static function encode($value) { switch (gettype($value)) { case 'boolean': return $value ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $value; case 'double': case 'float': return (float) $value; case 'string': return self::stringToJson($value); case 'array': return self::arrayToJson($value); case 'object': return self::objectToJson($value); default: return ''; } return ''; } protected static function stringToJson($string) { if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { $string = iconv($enc, 'UTF-8', $string); } $ascii = ''; $strlen = strlen($string); for ($c = 0; $c < $strlen; ++$c) { $ordVar = ord($string{$c}); if (0x08 == $ordVar) { $ascii .= '\b'; } elseif (0x09 == $ordVar) { $ascii .= '\t'; } elseif (0x0A == $ordVar) { $ascii .= '\n'; } elseif (0x0C == $ordVar) { $ascii .= '\f'; } elseif (0x0D == $ordVar) { $ascii .= '\r'; } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { $ascii .= '\\' . $string{$c}; } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { $ascii .= $string{$c}; } elseif (0xC0 == ($ordVar & 0xE0)) { $char = pack('C*', $ordVar, ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xE0 == ($ordVar & 0xF0)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF0 == ($ordVar & 0xF8)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF8 == ($ordVar & 0xFC)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xFC == ($ordVar & 0xFE)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } } return '"' . $ascii . '"'; } protected static function arrayToJson(array $array) { if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; } return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; } protected static function objectToJson($object) { if ($object instanceof Traversable) { $vars = array(); foreach ($object as $k => $v) { $vars[$k] = $v; } } else { $vars = get_object_vars($object); } return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; } protected static function nameValue($name, $value) { return self::encode(strval($name)) . ':' . self::encode($value); } protected static function utf8ToUTF16BE(&$string, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if (function_exists('mb_convert_encoding')) { return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); } $uni = self::utf8ToUnicode($string); foreach ($uni as $cp) { $out .= pack('n', $cp); } return $out; } protected static function utf8ToUnicode(&$string) { $unicode = $values = array(); $lookingFor = 1; for ($i = 0, $length = strlen($string); $i < $length; $i++) { $thisValue = ord($string[$i]); if ($thisValue < 128) { $unicode[] = $thisValue; } else { if (count($values) == 0) { $lookingFor = ($thisValue < 224) ? 2 : 3; } $values[] = $thisValue; if (count($values) == $lookingFor) { $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; $values = array(); $lookingFor = 1; } } } return $unicode; } } class WindArray { public static function mergeArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); unset($array2[$key]); } else { $tmp[$key] = $array; } } return array_merge($tmp, (array) $array2); } public static function filterArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); } } return $tmp; } public static function rebuildArrayWithKey($key, array $array) { if (!$key || !$array) { return array(); } $tmp = array(); foreach ($array as $_array) { if (isset($_array[$key])) { $tmp[$_array[$key]] = $_array; } } return $tmp; } } Wind::import("COM:utility.WindSecurity"); Wind::import("COM:utility.WindString"); class WindFile { const READ = 'rb'; const READWRITE = 'rb+'; const WRITE = 'wb'; const WRITEREAD = 'wb+'; const APPEND_WRITE = 'ab'; const APPEND_WRITEREAD = 'ab+'; public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { $temp = "\r\n "; if (!$isBuildReturn && is_array($data)) { foreach ($data as $key => $value) { if (!preg_match('/^\w+$/', $key)) continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n"; } else { ($isBuildReturn) && $temp .= " return "; $temp .= WindString::varToString($data) . ";\r\n"; } return self::write($fileName, $temp, $method, $ifLock); } public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); fclose($handle); $ifChmod && chmod($fileName, 0777); return $writeCheck; } public static function read($fileName, $method = self::READ) { $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { flock($handle, LOCK_SH); $data = fread($handle, filesize($fileName)); fclose($handle); } return $data; } public static function clearDir($dir, $ifexpiled = false) { if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { self::delFile($fullPath); } } closedir($handle); false === $ifexpiled && rmdir($dir); return true; } public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); if (!$handler = opendir($path)) { return false; } while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { if (substr($filename, 0, 1) != '.') { self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); } } else { self::delFile($path . DIRECTORY_SEPARATOR . $filename); } } } closedir($handler); true == $delDir && $level > 0 && rmdir($path); return true; } public static function getMimeType($fileName) { $suffix = self::getFileSuffix($fileName); $mimes = require rtrim(WIND_PATH, D_S) . D_S . 'component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { throw new WindException('Sorry, can not find the corresponding mime type of the file'); } return false; } public static function getDirectoryIterator($dir) { return new DirectoryIterator($dir); } public static function getFileInfo($fileName) { if (false === is_file($fileName)) { return array(); } $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); $fileInfo['ctime'] = filectime($fileName); $fileInfo['atime'] = fileatime($fileName); $fileInfo['mtime'] = filemtime($fileName); $fileInfo['readable'] = is_readable($fileName); $fileInfo['writable'] = is_writable($fileName); $fileInfo['executable'] = is_executable($fileName); $fileInfo['right'] = fileperms($fileName); $fileInfo['group'] = filegroup($fileName); $fileInfo['owner'] = fileowner($fileName); $fileInfo['mime'] = self::getMimeType($fileName); return $fileInfo; } public static function getDirectoryInfo($dir) { if (false !== is_dir($dir)) { return array(); } return stat($dir); } public static function delFile($filename) { return @unlink($filename); } public static function getFileSuffix($filename) { $filename = explode($filename, '.'); return $filename[count($filename) - 1]; } public static function appendSlashesToDir($path) { return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; } } class WindHtmlHelper { public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function encodeArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; } return $_tmp; } } class WindImage { public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); if (!$imagecreate) return false; $imgwidth = $minitemp['width']; $imgheight = $minitemp['height']; $srcX = $srcY = $dstX = $dstY =0; if (!$isProportion) { $dsDivision = $imgheight / $imgwidth; $fixDivision = $dstH / $dstW; if ($dsDivision > $fixDivision) { $tmp = $imgwidth * $fixDivision; $srcY = round(($imgheight - $tmp) / 2); $imgheight = $tmp; } else { $tmp = $imgheight / $fixDivision; $srcX = round(($imgwidth - $tmp) / 2); $imgwidth = $tmp; } } $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { $black = imagecolorallocate($thumb, 0, 0, 0); imagecolortransparent($thumb, $black); } $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); self::makeImg($minitemp['type'], $thumb, $dstFile); imagedestroy($thumb); return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); } public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { $sourcedb = $waterdb = array(); if (false === ($sourcedb = self::getImgInfo($source))) return false; if (!$waterImg && !$waterText) return false; imagealphablending($sourcedb['source'], true); if ($waterImg) { $waterdb = self::getImgInfo($waterImg); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); if ($waterdb['type'] == 'png') { $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); $sourcedb['source'] = $tmp; } else { imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); } } elseif ($waterText) { list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); empty($waterFont) && $waterFont = 12; $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); $waterdb['width'] = $temp[2] - $temp[6]; $waterdb['height'] = $temp[3] - $temp[7]; unset($temp); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); if (strlen($color) != 7) return false; $R = hexdec(substr($color, 1, 2)); $G = hexdec(substr($color, 3, 2)); $B = hexdec(substr($color, 5)); self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); } $dstsrc && $source = $dstsrc; self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); isset($waterdb['source']) && imagedestroy($waterdb['source']); imagedestroy($sourcedb['source']); return true; } private static function checkAttribute($attribute) { $attribute = is_string($attribute) ? array($attribute) : $attribute; if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; return $attribute; } private static function changeCharset($charset) { $charset = strtolower($charset); return !in_array($charset, array('utf8', 'utf-8')); } private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { if (is_array($waterPos)) return $waterPos; $wX = $wY = 0; switch (intval($waterPos)) { case 0 : $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); break; case 1 : $wX = 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 2: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 3: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 4: $wX = 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 5: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 6: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; default: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; break; } return array($wX, $wY); } private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { if (false === ($imgdata = self::getImgInfo($srcFile))) return false; if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; $imgdata['dstW'] = $dstW; $imgdata['dstH'] = $dstH; if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); } elseif ($dstW > 0 && $dstH > 0) { if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); } if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); } } else { $imgdata = false; } return $imgdata; } public static function getImgInfo($srcFile) { if (false === ($imgdata = self::getImgSize($srcFile))) return false; $imgdata['type'] = self::getTypes($imgdata['type']); if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; $imgdata['source'] = $imagecreatefromtype($srcFile); !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); return $imgdata; } private static function getImgSize($srcFile, $srcExt = null) { empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); $srcdata = array(); $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); in_array($srcExt, $exts) && $srcdata['type'] = 2; if (false === ($info = getimagesize($srcFile))) return false; list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; return $srcdata; } private static function getImgcreate($imagetype) { if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { return array('imagecreatetruecolor', 'imagecopyresampled'); } if (function_exists('imagecreate') && function_exists('imagecopyresized')) { return array('imagecreate', 'imagecopyresized'); } return array('', ''); } private static function makeImg($type, $image, $filename, $quality = '75') { $makeimage = 'image' . $type; if (!function_exists($makeimage)) return false; if ($type == 'jpeg') { $makeimage($image, $filename, $quality); } else { $makeimage($image, $filename); } return true; } private static function getTypes($id) { $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; } } Wind::import('WIND:component.utility.WindFile'); class WindPack { const STRIP_SELF = 'stripWhiteSpaceBySelf'; const STRIP_PHP = 'stripWhiteSpaceByPhp'; const STRIP_TOKEN = 'stripWhiteSpaceByToken'; private $packList = array(); private $contentInjectionPosition; private $contentInjectionCallBack = ''; public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { if (empty($dst) || empty($dir)) { return false; } $suffix = is_array($suffix) ? $suffix : array( $suffix); if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { return false; } $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->stripImport($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { if (empty($dst) || empty($fileList)) { return false; } $content = array(); $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function stripWhiteSpaceByPhp($filename) { return php_strip_whitespace($filename); } public function stripWhiteSpaceBySelf($filename, $compress = true) { $content = $this->getContentFromFile($filename); $content = $this->stripComment($content, ''); return $this->stripSpace($content, ' '); } public function stripWhiteSpaceByToken($filename) { $content = $this->getContentFromFile($filename); $compressContent = ''; $lastToken = 0; foreach (token_get_all($content) as $key => $token) { if (is_array($token)) { if (in_array($token[0], array( T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) { continue; } $compressContent .= ' ' . $token[1]; } else { $compressContent .= $token; } $lastToken = $token[0]; } return $compressContent; } public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { static $content = array(); if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { return false; } $dir = is_array($dir) ? $dir : array( $dir); foreach ($dir as $_dir) { $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; if (is_dir($_dir)) { $handle = dir($_dir); while (false != ($tmp = $handle->read())) { $name = WindFile::appendSlashesToDir($_dir) . $tmp; if (is_dir($name) && !in_array($tmp, $ndir)) { $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); } if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { $content[] = $this->$packMethod($name); $this->setPackList($file, $name); } } $handle->close(); } } return $content; } public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { return array(); } $fileList = is_array($fileList) ? $fileList : array( $fileList); foreach ($fileList as $key => $value) { if (is_array($value) && isset($value[1])) { $parents = class_parents($value[1]); $_fileList = $this->buildFileList($parents, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); $implements = class_implements($value[1]); $_fileList = $this->buildFileList($implements, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); if (key_exists($key, $this->getPackList())) continue; $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; if (is_file($file)) { $content[] = $this->$packMethod($file); $this->setPackList($key, $value); } } } } public function stripComment($content, $replace = '') { return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); } public function stripNR($content, $replace = array('\n','\r\n','\r')) { return preg_replace('/[\n\r]+/', $replace, $content); } public function stripSpace($content, $replace = ' ') { return preg_replace('/[ ]+/', $replace, $content); } public function stripPhpIdentify($content, $replace = '') { return preg_replace('/(?:<\?(?:php)*)|(\)/i', $replace, $content); } public function stripStrByRule($content, $rule, $replace = '') { return preg_replace("/$rule/", $replace, $content); } public function stripImport($content, $replace = '') { $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); if ($matchs[1]) { foreach ($matchs[1] as $key => $value) { $name = substr($value, strrpos($value, '.') + 1); if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { $strip = str_replace(array( '(', ')'), array( '\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; $content = $this->stripStrByRule($content, $strip, $replace); } } } return $content; } public function getPackList() { return $this->packList; } public function getContentFromFile($filename) { if (is_file($filename)) { $content = ''; $fp = fopen($filename, "r"); while (!feof($fp)) { $line = fgets($fp); if (in_array(strlen($line), array( 2, 3)) && in_array(ord($line), array( 9, 10, 13))) continue; $content .= $line; } fclose($fp); return $content; } return false; } public function getContentBySuffix($content, $suffix, $replace = ' ') { switch ($suffix) { case 'php': $content = '' . $replace . $content . ''; break; default: $content = '' . $replace . $content . ''; break; } return $content; } private function buildFileList($list, $fileList) { $_temp = array(); foreach ($list as $fileName) { foreach ($fileList as $key => $value) { if ($value[1] == $fileName) { $_temp[$key] = $value; break; } } } return $_temp; } public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { if (!in_array($position, array( 'before', 'after'))) $position = 'before'; $this->contentInjectionPosition = $position; $this->contentInjectionCallBack = $contentInjectionCallBack; } public function callBack($content, $replace = '') { if ($this->contentInjectionCallBack !== '') { $_content = call_user_func_array($this->contentInjectionCallBack, array( $this->getPackList())); if ($this->contentInjectionPosition == 'before') { $content = $replace . $_content . $content; } elseif ($this->contentInjectionPosition == 'after') { $content .= $replace . $_content . $replace; } } return $content; } private function isValidatePackMethod($packMethod) { return method_exists($this, $packMethod) && in_array($packMethod, array( WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN)); } private function setPackList($key, $value) { if (isset($this->packList[$key])) { if (is_array($this->packList[$key])) { array_push($this->packList[$key], $value); } else { $tmp_name = $this->packList[$key]; $this->packList[$key] = array( $tmp_name, $value); } } else { $this->packList[$key] = $value; } } } class WindSecurity { public static function escapeHTML($str) { return htmlspecialchars($str, ENT_QUOTES); } public static function stripTags($str, $allowTags = "") { return strip_tags($str, $allowTags); } public static function escapePath($fileName, $ifCheck = true) { if (!self::_escapePath($fileName, $ifCheck)) { throw new WindException('file name is illegal'); } return $fileName; } public static function escapeDir($dir) { $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } public static function escapeChar($value) { if (is_array($value)) { foreach ($value as $key => $sub) { $value[$key] = self::escapeChar($sub); } } elseif (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = self::escapeString($value); } return $value; } public static function escapeString($string) { $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } public static function quotemeta($string) { return quotemeta($string); } public function checkInputValue($value, $key = '') { if (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = "'" . addslashes($value) . "'"; } elseif (is_float($value)) { $value = (float) $value; } elseif (is_object($value) || is_array($value)) { $value = "'" . addslashes(serialize($value)). "'"; } return $value; } public static function addSlashesForInput($str) { if (!get_magic_quotes_gpc()) { $str = addslashes($str); } return $str; } public static function addSlashesForOutput($str) { if (!get_magic_quotes_runtime()) { $str = addslashes($str); } return $str; } public static function addSlashes($value, $gpc = false, $df = false) { if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable) )) { return $value; } if(is_string($value)){ if (false === $gpc && true === $df) { return self::addSlashesForOutput($value); } if (false === $df && true === $gpc) { return self::addSlashesForInput($value); } return addslashes($value); } foreach($value as $key=>$_value){ $value[$key] = self::addSlashes($_value,$gpc,$df); } return $value; } public static function stripSlashes($value) { if (!$value) return $value; if (is_string($value)) return stripslashes($value); if (!is_array($value) && !($value instanceof Traversable)) return $value; foreach ($value as $key => $_value) { $value[$key] = self::stripSlashes($_value); } return $value; } public static function sqlEscape($var, $strip = true, $isArray = false) { if (is_array($var)) { if (!$isArray) return " '' "; foreach ($var as $key => $value) { $var[$key] = trim(self::sqlEscape($value, $strip)); } return $var; } elseif (is_numeric($var)) { return " '" . $var . "' "; } else { return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; } } public static function sqlImplode($array, $strip = true) { return implode(',', self::sqlEscape($array, $strip, true)); } public static function sqlSingle($array, $strip = true) { if (!is_array($array)) return ''; $array = self::sqlEscape($array, $strip, true); $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; } return $str; } public static function sqlMulti($array, $strip = true) { if (!is_array($array)) { return ''; } $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; } } return $str; } public static function sqlMetadata($data ,$tlists=array()) { if (empty($tlists) || !in_array($data , $tlists)) { $data = str_replace(array('`', ' '), '',$data); } return ' `'.$data.'` '; } private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; if (strtr($tmpname, $tmparray) != $tmpname) { return false; } return true; } } class WindString { const UTF8 = 'utf8'; const GBK = 'gbk'; public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( $string, $start, $length, $dot); } public static function strlen($string, $charset = self::UTF8) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; $count++; } return $count; } public static function varToString($input, $indent = '') { switch (gettype($input)) { case 'string': return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; case 'array': $output = "array(\r\n"; foreach ($input as $key => $value) { $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( $value, $indent . "\t"); $output .= ",\r\n"; } $output .= $indent . ')'; return $output; case 'boolean': return $input ? 'true' : 'false'; case 'NULL': return 'NULL'; case 'integer': case 'double': case 'float': return "'" . (string) $input . "'"; } return 'NULL'; } public static function jsonEncode($value) { if (!function_exists('json_encode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); } public static function jsonDecode($value) { if (!function_exists('json_decode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); } public static function jsonSimpleEncode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': return '"' . addslashes( str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; case 'array': if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array(); foreach ($var as $name => $value) { $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( $value); } return '{' . join(',', $properties) . '}'; } $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); return '[' . join(',', $elements) . ']'; } return false; } public static function utf8_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j += 2; } else { $word++; } $j++; } $start = $word + 3 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 3); $j += 2; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function utf8_strlen($str) { $i = $count = 0; $len = strlen($str); while ($i < $len) { $chr = ord($str[$i]); $count++; $i++; if ($i >= $len) break; if ($chr & 0x80) { $chr <<= 1; while ($chr & 0x80) { $i++; $chr <<= 1; } } } return $count; } public static function gbk_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j++; } else { $word++; } $j++; } $start = $word + 2 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 2); $j++; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function gbk_strlen($string) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? $i += 2 : $i++; $count++; } return $count; } } class WindUtility { public static function mergeArray($array1, $array2) { foreach ($array2 as $key => $value) { if (!isset($array1[$key]) || !is_array($array1[$key])) { $array1[$key] = $value; continue; } $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); } return $array1; } public static function lcfirst($str) { if (function_exists('lcfirst')) return lcfirst($str); $str[0] = strtolower($str[0]); return $str; } public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { $randnum = rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { $randstr .= chr($randnum + 55); } else { $randstr .= chr($randnum + 61); } } return $randstr; } public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } class WindValidator { public static function isTelPhone($phone) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); } public static function isTelNumber($number) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); } public static function isQQ($qq) { return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); } public static function isZipcode($zipcode) { return 0 < preg_match('/^\d{4,8}$/', $zipcode); } public static function hasEmail($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); } public static function isEmail($string) { return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); } public static function hasIdCard($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); } public static function isIdCard($string) { return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); } public static function hasUrl($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); } public static function isUrl($string) { return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); } public static function hasChinese($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); } public static function isChinese($string) { return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); } public static function hasHtml($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); } public static function isHtml($string) { return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); } public static function hasIpv4($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); } public static function isIpv4($string) { return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); } public static function hasIpv6($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| ::([a-f0-9]{1,4}:){5}| ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )([a-f0-9]{1,4}:[a-f0-9]{1,4}| (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string, $matches, $ifAll); } public static function isIpv6($string) { return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| ::(?:[a-f0-9]{1,4}:){5}| (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string); } public static function hasScript($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); } public static function isScript($string) { return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); } public static function isEmpty($value) { return empty($value); } public static function isNonNegative($number) { return 0 <= (int) $number; } public static function isPositive($number) { return 0 < (int) $number; } public static function isNegative($number) { return 0 > (int) $number; } public static function isArray($array) { return is_array($array); } public static function isRequired($value) { return !self::isEmpty($value); } public static function inArray($needle, array $array, $strict = true) { return in_array($needle, $array, $strict); } public static function isLegalLength($string, $length, $charset = 'utf8') { Wind::import('WIND:component.utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { if (true === $ifAll) { return preg_match_all($regExp, $string, $matches); } return preg_match($regExp, $string, $matches); } }?> \ No newline at end of file +$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { $key = isset($_map[$key]) ? $_map[$key] : 'all'; if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias])) throw new WindException( '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); $definition = $this->classDefinitions[$alias]; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (!$className) throw new WindException('class name is required.'); if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (is_string($alias) && !empty($alias)) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, Wind::getApp()->getComponent('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); if (IS_DEBUG) $this->getComponent('windLogger')->flush(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { $component = null; switch ($componentName) { case 'windCache': if ($this->getConfig('iscache') !== '0') $component = $this->windFactory->getInstance($componentName); break; default: $component = $this->windFactory->getInstance($componentName); break; } return $component; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = $msghtml = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $msg = "$file\n"; $msghtml = "$file\n"; if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $msg .= implode("\n", $fileLines) . "\n"; $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $msghtml .= implode("\n", $fileLines) . "\n"; } } $msg .= "$errtrace\n"; $msghtml .= "$errtrace\n"; } $msghtml .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; $msghtml = "$topic

$topic

$errmessage\n$msghtml
"; $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); $msghtml = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msghtml); Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', true); die($_errhtml ? $msghtml : $msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } class WindDate { public static function getTimeZone() { return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); } public static function setTimezone($timezone) { function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); } public static function format($format = null, $dateTime = null) { return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); } public static function datePart($interval, $dateTime = null) { return date($interval, self::getTimeStamp($dateTime)); } public static function dateDiff($interval, $startDateTime, $endDateTime) { $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); $retval = 0; switch ($interval) { case "y": $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; case "m": $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; case "w": $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; case "d": $retval = bcdiv($diff, (60 * 60 * 24));break; case "h": $retval = bcdiv($diff, (60 * 60));break; case "n": $retval = bcdiv($diff, 60);break; case "s": default:$retval = $diff;break; } return $retval; } public static function dateAdd($interval, $value, $dateTime, $format = null) { $date = getdate(self::getTimeStamp($dateTime)); switch ($interval) { case "y": $date["year"] += $value;break; case "q": $date["mon"] += ($value * 3);break; case "m": $date["mon"] += $value;break; case "w": $date["mday"] += ($value * 7);break; case "d": $date["mday"] += $value;break; case "h": $date["hours"] += $value;break; case "n": $date["minutes"] += $value;break; case "s": default:$date["seconds"] += $value;break; } return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); } public static function getRealDaysInMonthsOfYear($year) { $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if (self::isLeapYear($year)) { $months[1] = 29; } return $months; } public static function getDaysInMonth($month, $year) { if (1 > $month || 12 < $month) { return 0; } if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { return 0; } return $daysInmonths[$month - 1]; } public static function getDaysInYear($year) { return self::isLeapYear($year) ? 366 : 365; } public static function getRFCDate($date = null) { $time = $date ? is_int($date) ? $date : strtotime($date) : time(); $tz = date('Z', $time); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); } public static function getChinaDate($time = null) { list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); } public static function getChinaWeek($week = null) { $week = $week ? $week : (int) date('w', time()); $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); return $weekMap[$week]; } public static function getPeriodOfTime($hour = null) { $hour = $hour ? $hour : (int) date('G', time()); $period = ''; if (0 <= $hour && 6 > $hour) { $period = '凌晨'; } elseif (6 <= $hour && 8 > $hour) { $period = '早上'; } elseif (8 <= $hour && 11 > $hour) { $period = '上午'; } elseif (11 <= $hour && 13 > $hour) { $period = '中午'; } elseif (13 <= $hour && 15 > $hour) { $period = '响午'; } elseif (15 <= $hour && 18 > $hour) { $period = '下午'; } elseif (18 <= $hour && 20 > $hour) { $period = '傍晚'; } elseif (20 <= $hour && 22 > $hour) { $period = '晚上'; } elseif (22 <= $hour && 23 >= $hour) { $period = '深夜'; } return $period; } public static function getUTCDate($dateTime = null) { $oldTimezone = self::getTimezone(); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone('UTC'); } $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone($oldTimezone); } return $date; } public static function getMicroTime($get_as_float = null,$mircrotime = null) { return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); } public static function isLeapYear($year) { if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { return true; } return false; } public static function getTimeStamp($dateTime = null){ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); } public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); $timestamp = $timestamp ? $timestamp : time(); $compareTime = strtotime(self::format('Y-m-d',$timestamp)); $currentTime = strtotime(self::format('Y-m-d',$time)); $decrease = $timestamp - $time; $result = self::format($format,$time); if (0 >= $decrease) { return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } if ($currentTime == $compareTime) { if (1 == $type) { if (60 >= $decrease) { return array($decrease . $timelang['second'], $result); } return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); } return array(self::format('H:i',$time), $result); } elseif ($currentTime == $compareTime - 86400) { return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); } elseif ($currentTime == $compareTime - 172800) { return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); } return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } } class WindGeneralDate { const FILL = 0; const DIGIT = 1; const TEXT = 2; const DEFAULT_FORMAT = 'Y-m-d H:i:s'; private $time = 0; public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { $time = time(); !$month && ((!$year) ? $month = date('m', $time) : $month = 1); !$day && ((!$year) ? $day = date('d', $time) : $day = 1); !$hours && !$year && $hours = date('H', $time); !$minutes && !$year && $minutes = date('i', $time); !$second && !$year && $second = date('s', $time); !$year && $year = date('Y', $time); $this->time = mktime($hours, $minutes, $second, $month, $day, $year); } public function getDaysInMonth() { return date('t', $this->time); } public function getDaysInYear() { return $this->isLeapYear() ? 366 : 365; } public function getDayOfYear() { return date('z', $this->time) + 1; } public function getDayOfMonth() { return date('j', $this->time); } public function getDayOfWeek() { return date('w', $this->time) + 1; } public function getWeekOfYear() { return date('W', $this->time); } public function getYear($format = true) { return date($format ? 'Y' : 'y', $this->time); } public function getMonth($display = self::FILL) { if(self::FILL == $display){ return date('m', $this->time); }elseif(self::DIGIT == $display){ return date('n', $this->time); }elseif(self::TEXT == $display){ return date('M', $this->time); } return date('n', $this->time); } public function getDay($display = self::FILL) { if(self::FILL == $display){ return date('d', $this->time); }elseif(self::DIGIT == $display){ return date('j', $this->time); }elseif(self::TEXT == $display){ return date('jS', $this->time); } return date('j', $this->time); } public function getWeek($display = self::FILL) { if(self::FILL == $display || self::DIGIT == $display){ return date('w', $this->time); }elseif(self::TEXT == $display){ return date('D', $this->time); } return date('N', $this->time); } public function get12Hours($display = self::FILL){ if(self::FILL == $display){ return date('h', $this->time); }elseif(self::DIGIT == $display){ return date('g', $this->time);; } return date('h', $this->time); } public function get24Hours($display = self::FILL){ if(self::FILL == $display){ return date('H', $this->time); }elseif(self::DIGIT == $display){ return date('G', $this->time);; } return date('H', $this->time); } public function getMinutes() { return date('i', $this->time); } public function getSeconds() { return date('s', $this->time); } public function getLocalTimeZone() { return date('T', $this->time); } public function setTime($time) { if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { $this->time = $time; } } public function getNow() { $date = getdate($this->time); return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); } public function __toString() { return $this->toString(); } public function toString($format = null) { return date($format ? $format : self::DEFAULT_FORMAT, $this->time); } public function isLeapYear() { return date('L', $this->time); } } class WindDecoder { const JSON_SLICE = 1; const JSON_IN_STR = 2; const JSON_IN_ARR = 4; const JSON_IN_OBJ = 8; const JSON_IN_CMT = 16; public static function decode($str, $useArray = true) { $str = strtolower(self::reduceString($str)); if ('true' == $str) { return true; } elseif ('false' == $str) { return false; } elseif ('null' == $str) { return null; } elseif (is_numeric($str)) { return (float)$str == (integer)$str ? (integer) $str : (float) $str; }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ return self::jsonToString($str); }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); } return false; } protected static function jsonToString($string) { $delim = substr($string, 0, 1); $chrs = substr($string, 1, -1); $decodeStr = ''; for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { $compare = substr($chrs, $c, 2); $ordCode = ord($chrs{$c}); if('\b' == $compare){ $decodeStr .= chr(0x08); ++$c; }elseif('\t' == $compare){ $decodeStr .= chr(0x09); ++$c; }elseif('\n' == $compare){ $decodeStr .= chr(0x0A); ++$c; }elseif('\f' == $compare){ $decodeStr .= chr(0x0C); ++$c; }elseif('\r' == $compare){ $decodeStr .= chr(0x0D); ++$c; }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { $decodeStr .= $chrs{++$c}; } }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $decodeStr .= self::utf16beToUTF8($utf16); $c += 5; }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ $decodeStr .= $chrs{$c}; }elseif(0xC0 == ($ordCode & 0xE0)){ $decodeStr .= substr($chrs, $c, 2); ++$c; }elseif(0xE0 == ($ordCode & 0xF0)){ $decodeStr .= substr($chrs, $c, 3); $c += 2; }elseif(0xF0 == ($ordCode & 0xF8)){ $decodeStr .= substr($chrs, $c, 4); $c += 3; }elseif(0xF8 == ($ordCode & 0xFC)){ $decodeStr .= substr($chrs, $c, 5); $c += 4; }elseif(0xFC == ($ordCode & 0xFE)){ $decodeStr .= substr($chrs, $c, 6); $c += 5; } } return $decodeStr; } protected static function jsonToArray($str) { return self::complexConvert($str,true); } protected static function jsonToObject($str) { return self::complexConvert($str,false); } protected static function complexConvert($str,$useArray = true){ if ('[' == $str{0}) { $stk = array(self::JSON_IN_ARR); $arr = array(); } else { $obj = $useArray ? array() : new stdClass(); $stk = array(self::JSON_IN_OBJ); } array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = self::reduceString($chrs); if ('' == $chrs) { return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; } for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); if (reset($stk) == self::JSON_IN_ARR) { array_push($arr, self::decode($slice, $useArray)); } elseif (reset($stk) == self::JSON_IN_OBJ) { if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $key = self::decode($parts[1], $useArray); $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { array_pop($stk); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { array_pop($stk); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { array_pop($stk); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { array_pop($stk); for ($i = $top['where']; $i <= ++$c; ++$i){ $chrs = substr_replace($chrs, ' ', $i, 1); } } } if (self::JSON_IN_ARR == reset($stk)) { return $arr; } elseif (self::JSON_IN_OBJ == reset($stk)) { return $obj; } return false; } protected static function unicodeToUTF8(&$str) { $utf8 = ''; foreach ($str as $unicode) { if ($unicode < 128) { $utf8 .= chr($unicode); } elseif ($unicode < 2048) { $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } else { $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } } return $utf8; } protected static function reduceString($str) { return trim(preg_replace(array( '#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str)); } protected static function utf16beToUTF8(&$str) { return self::unicodeToUTF8(unpack('n*', $str)); } } class WindEncoder { public static $charset = 'utf-8'; public static function encode($value) { switch (gettype($value)) { case 'boolean': return $value ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $value; case 'double': case 'float': return (float) $value; case 'string': return self::stringToJson($value); case 'array': return self::arrayToJson($value); case 'object': return self::objectToJson($value); default: return ''; } return ''; } protected static function stringToJson($string) { if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { $string = iconv($enc, 'UTF-8', $string); } $ascii = ''; $strlen = strlen($string); for ($c = 0; $c < $strlen; ++$c) { $ordVar = ord($string{$c}); if (0x08 == $ordVar) { $ascii .= '\b'; } elseif (0x09 == $ordVar) { $ascii .= '\t'; } elseif (0x0A == $ordVar) { $ascii .= '\n'; } elseif (0x0C == $ordVar) { $ascii .= '\f'; } elseif (0x0D == $ordVar) { $ascii .= '\r'; } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { $ascii .= '\\' . $string{$c}; } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { $ascii .= $string{$c}; } elseif (0xC0 == ($ordVar & 0xE0)) { $char = pack('C*', $ordVar, ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xE0 == ($ordVar & 0xF0)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF0 == ($ordVar & 0xF8)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF8 == ($ordVar & 0xFC)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xFC == ($ordVar & 0xFE)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } } return '"' . $ascii . '"'; } protected static function arrayToJson(array $array) { if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; } return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; } protected static function objectToJson($object) { if ($object instanceof Traversable) { $vars = array(); foreach ($object as $k => $v) { $vars[$k] = $v; } } else { $vars = get_object_vars($object); } return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; } protected static function nameValue($name, $value) { return self::encode(strval($name)) . ':' . self::encode($value); } protected static function utf8ToUTF16BE(&$string, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if (function_exists('mb_convert_encoding')) { return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); } $uni = self::utf8ToUnicode($string); foreach ($uni as $cp) { $out .= pack('n', $cp); } return $out; } protected static function utf8ToUnicode(&$string) { $unicode = $values = array(); $lookingFor = 1; for ($i = 0, $length = strlen($string); $i < $length; $i++) { $thisValue = ord($string[$i]); if ($thisValue < 128) { $unicode[] = $thisValue; } else { if (count($values) == 0) { $lookingFor = ($thisValue < 224) ? 2 : 3; } $values[] = $thisValue; if (count($values) == $lookingFor) { $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; $values = array(); $lookingFor = 1; } } } return $unicode; } } class WindArray { public static function mergeArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); unset($array2[$key]); } else { $tmp[$key] = $array; } } return array_merge($tmp, (array) $array2); } public static function filterArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); } } return $tmp; } public static function rebuildArrayWithKey($key, array $array) { if (!$key || !$array) { return array(); } $tmp = array(); foreach ($array as $_array) { if (isset($_array[$key])) { $tmp[$_array[$key]] = $_array; } } return $tmp; } } Wind::import("COM:utility.WindSecurity"); Wind::import("COM:utility.WindString"); class WindFile { const READ = 'rb'; const READWRITE = 'rb+'; const WRITE = 'wb'; const WRITEREAD = 'wb+'; const APPEND_WRITE = 'ab'; const APPEND_WRITEREAD = 'ab+'; public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { $temp = "\r\n "; if (!$isBuildReturn && is_array($data)) { foreach ($data as $key => $value) { if (!preg_match('/^\w+$/', $key)) continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n"; } else { ($isBuildReturn) && $temp .= " return "; $temp .= WindString::varToString($data) . ";\r\n"; } return self::write($fileName, $temp, $method, $ifLock); } public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); fclose($handle); $ifChmod && chmod($fileName, 0777); return $writeCheck; } public static function read($fileName, $method = self::READ) { $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { flock($handle, LOCK_SH); $data = fread($handle, filesize($fileName)); fclose($handle); } return $data; } public static function clearDir($dir, $ifexpiled = false) { if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { self::delFile($fullPath); } } closedir($handle); false === $ifexpiled && rmdir($dir); return true; } public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); if (!$handler = opendir($path)) { return false; } while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { if (substr($filename, 0, 1) != '.') { self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); } } else { self::delFile($path . DIRECTORY_SEPARATOR . $filename); } } } closedir($handler); true == $delDir && $level > 0 && rmdir($path); return true; } public static function getMimeType($fileName) { $suffix = self::getFileSuffix($fileName); $mimes = require rtrim(WIND_PATH, D_S) . D_S . 'component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { throw new WindException('Sorry, can not find the corresponding mime type of the file'); } return false; } public static function getDirectoryIterator($dir) { return new DirectoryIterator($dir); } public static function getFileInfo($fileName) { if (false === is_file($fileName)) { return array(); } $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); $fileInfo['ctime'] = filectime($fileName); $fileInfo['atime'] = fileatime($fileName); $fileInfo['mtime'] = filemtime($fileName); $fileInfo['readable'] = is_readable($fileName); $fileInfo['writable'] = is_writable($fileName); $fileInfo['executable'] = is_executable($fileName); $fileInfo['right'] = fileperms($fileName); $fileInfo['group'] = filegroup($fileName); $fileInfo['owner'] = fileowner($fileName); $fileInfo['mime'] = self::getMimeType($fileName); return $fileInfo; } public static function getDirectoryInfo($dir) { if (false !== is_dir($dir)) { return array(); } return stat($dir); } public static function delFile($filename) { return @unlink($filename); } public static function getFileSuffix($filename) { $filename = explode($filename, '.'); return $filename[count($filename) - 1]; } public static function appendSlashesToDir($path) { return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; } } class WindHtmlHelper { public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function encodeArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; } return $_tmp; } } class WindImage { public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); if (!$imagecreate) return false; $imgwidth = $minitemp['width']; $imgheight = $minitemp['height']; $srcX = $srcY = $dstX = $dstY =0; if (!$isProportion) { $dsDivision = $imgheight / $imgwidth; $fixDivision = $dstH / $dstW; if ($dsDivision > $fixDivision) { $tmp = $imgwidth * $fixDivision; $srcY = round(($imgheight - $tmp) / 2); $imgheight = $tmp; } else { $tmp = $imgheight / $fixDivision; $srcX = round(($imgwidth - $tmp) / 2); $imgwidth = $tmp; } } $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { $black = imagecolorallocate($thumb, 0, 0, 0); imagecolortransparent($thumb, $black); } $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); self::makeImg($minitemp['type'], $thumb, $dstFile); imagedestroy($thumb); return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); } public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { $sourcedb = $waterdb = array(); if (false === ($sourcedb = self::getImgInfo($source))) return false; if (!$waterImg && !$waterText) return false; imagealphablending($sourcedb['source'], true); if ($waterImg) { $waterdb = self::getImgInfo($waterImg); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); if ($waterdb['type'] == 'png') { $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); $sourcedb['source'] = $tmp; } else { imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); } } elseif ($waterText) { list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); empty($waterFont) && $waterFont = 12; $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); $waterdb['width'] = $temp[2] - $temp[6]; $waterdb['height'] = $temp[3] - $temp[7]; unset($temp); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); if (strlen($color) != 7) return false; $R = hexdec(substr($color, 1, 2)); $G = hexdec(substr($color, 3, 2)); $B = hexdec(substr($color, 5)); self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); } $dstsrc && $source = $dstsrc; self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); isset($waterdb['source']) && imagedestroy($waterdb['source']); imagedestroy($sourcedb['source']); return true; } private static function checkAttribute($attribute) { $attribute = is_string($attribute) ? array($attribute) : $attribute; if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; return $attribute; } private static function changeCharset($charset) { $charset = strtolower($charset); return !in_array($charset, array('utf8', 'utf-8')); } private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { if (is_array($waterPos)) return $waterPos; $wX = $wY = 0; switch (intval($waterPos)) { case 0 : $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); break; case 1 : $wX = 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 2: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 3: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 4: $wX = 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 5: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 6: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; default: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; break; } return array($wX, $wY); } private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { if (false === ($imgdata = self::getImgInfo($srcFile))) return false; if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; $imgdata['dstW'] = $dstW; $imgdata['dstH'] = $dstH; if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); } elseif ($dstW > 0 && $dstH > 0) { if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); } if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); } } else { $imgdata = false; } return $imgdata; } public static function getImgInfo($srcFile) { if (false === ($imgdata = self::getImgSize($srcFile))) return false; $imgdata['type'] = self::getTypes($imgdata['type']); if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; $imgdata['source'] = $imagecreatefromtype($srcFile); !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); return $imgdata; } private static function getImgSize($srcFile, $srcExt = null) { empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); $srcdata = array(); $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); in_array($srcExt, $exts) && $srcdata['type'] = 2; if (false === ($info = getimagesize($srcFile))) return false; list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; return $srcdata; } private static function getImgcreate($imagetype) { if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { return array('imagecreatetruecolor', 'imagecopyresampled'); } if (function_exists('imagecreate') && function_exists('imagecopyresized')) { return array('imagecreate', 'imagecopyresized'); } return array('', ''); } private static function makeImg($type, $image, $filename, $quality = '75') { $makeimage = 'image' . $type; if (!function_exists($makeimage)) return false; if ($type == 'jpeg') { $makeimage($image, $filename, $quality); } else { $makeimage($image, $filename); } return true; } private static function getTypes($id) { $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; } } Wind::import('WIND:component.utility.WindFile'); class WindPack { const STRIP_SELF = 'stripWhiteSpaceBySelf'; const STRIP_PHP = 'stripWhiteSpaceByPhp'; const STRIP_TOKEN = 'stripWhiteSpaceByToken'; private $packList = array(); private $contentInjectionPosition; private $contentInjectionCallBack = ''; public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { if (empty($dst) || empty($dir)) { return false; } $suffix = is_array($suffix) ? $suffix : array( $suffix); if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { return false; } $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->stripImport($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { if (empty($dst) || empty($fileList)) { return false; } $content = array(); $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function stripWhiteSpaceByPhp($filename) { return php_strip_whitespace($filename); } public function stripWhiteSpaceBySelf($filename, $compress = true) { $content = $this->getContentFromFile($filename); $content = $this->stripComment($content, ''); return $this->stripSpace($content, ' '); } public function stripWhiteSpaceByToken($filename) { $content = $this->getContentFromFile($filename); $compressContent = ''; $lastToken = 0; foreach (token_get_all($content) as $key => $token) { if (is_array($token)) { if (in_array($token[0], array( T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) { continue; } $compressContent .= ' ' . $token[1]; } else { $compressContent .= $token; } $lastToken = $token[0]; } return $compressContent; } public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { static $content = array(); if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { return false; } $dir = is_array($dir) ? $dir : array( $dir); foreach ($dir as $_dir) { $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; if (is_dir($_dir)) { $handle = dir($_dir); while (false != ($tmp = $handle->read())) { $name = WindFile::appendSlashesToDir($_dir) . $tmp; if (is_dir($name) && !in_array($tmp, $ndir)) { $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); } if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { $content[] = $this->$packMethod($name); $this->setPackList($file, $name); } } $handle->close(); } } return $content; } public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { return array(); } $fileList = is_array($fileList) ? $fileList : array( $fileList); foreach ($fileList as $key => $value) { if (is_array($value) && isset($value[1])) { $parents = class_parents($value[1]); $_fileList = $this->buildFileList($parents, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); $implements = class_implements($value[1]); $_fileList = $this->buildFileList($implements, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); if (key_exists($key, $this->getPackList())) continue; $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; if (is_file($file)) { $content[] = $this->$packMethod($file); $this->setPackList($key, $value); } } } } public function stripComment($content, $replace = '') { return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); } public function stripNR($content, $replace = array('\n','\r\n','\r')) { return preg_replace('/[\n\r]+/', $replace, $content); } public function stripSpace($content, $replace = ' ') { return preg_replace('/[ ]+/', $replace, $content); } public function stripPhpIdentify($content, $replace = '') { return preg_replace('/(?:<\?(?:php)*)|(\)/i', $replace, $content); } public function stripStrByRule($content, $rule, $replace = '') { return preg_replace("/$rule/", $replace, $content); } public function stripImport($content, $replace = '') { $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); if ($matchs[1]) { foreach ($matchs[1] as $key => $value) { $name = substr($value, strrpos($value, '.') + 1); if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { $strip = str_replace(array( '(', ')'), array( '\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; $content = $this->stripStrByRule($content, $strip, $replace); } } } return $content; } public function getPackList() { return $this->packList; } public function getContentFromFile($filename) { if (is_file($filename)) { $content = ''; $fp = fopen($filename, "r"); while (!feof($fp)) { $line = fgets($fp); if (in_array(strlen($line), array( 2, 3)) && in_array(ord($line), array( 9, 10, 13))) continue; $content .= $line; } fclose($fp); return $content; } return false; } public function getContentBySuffix($content, $suffix, $replace = ' ') { switch ($suffix) { case 'php': $content = '' . $replace . $content . ''; break; default: $content = '' . $replace . $content . ''; break; } return $content; } private function buildFileList($list, $fileList) { $_temp = array(); foreach ($list as $fileName) { foreach ($fileList as $key => $value) { if ($value[1] == $fileName) { $_temp[$key] = $value; break; } } } return $_temp; } public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { if (!in_array($position, array( 'before', 'after'))) $position = 'before'; $this->contentInjectionPosition = $position; $this->contentInjectionCallBack = $contentInjectionCallBack; } public function callBack($content, $replace = '') { if ($this->contentInjectionCallBack !== '') { $_content = call_user_func_array($this->contentInjectionCallBack, array( $this->getPackList())); if ($this->contentInjectionPosition == 'before') { $content = $replace . $_content . $content; } elseif ($this->contentInjectionPosition == 'after') { $content .= $replace . $_content . $replace; } } return $content; } private function isValidatePackMethod($packMethod) { return method_exists($this, $packMethod) && in_array($packMethod, array( WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN)); } private function setPackList($key, $value) { if (isset($this->packList[$key])) { if (is_array($this->packList[$key])) { array_push($this->packList[$key], $value); } else { $tmp_name = $this->packList[$key]; $this->packList[$key] = array( $tmp_name, $value); } } else { $this->packList[$key] = $value; } } } class WindSecurity { public static function escapeHTML($str) { return htmlspecialchars($str, ENT_QUOTES); } public static function stripTags($str, $allowTags = "") { return strip_tags($str, $allowTags); } public static function escapePath($fileName, $ifCheck = true) { if (!self::_escapePath($fileName, $ifCheck)) { throw new WindException('file name is illegal'); } return $fileName; } public static function escapeDir($dir) { $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } public static function escapeChar($value) { if (is_array($value)) { foreach ($value as $key => $sub) { $value[$key] = self::escapeChar($sub); } } elseif (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = self::escapeString($value); } return $value; } public static function escapeString($string) { $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } public static function quotemeta($string) { return quotemeta($string); } public function checkInputValue($value, $key = '') { if (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = "'" . addslashes($value) . "'"; } elseif (is_float($value)) { $value = (float) $value; } elseif (is_object($value) || is_array($value)) { $value = "'" . addslashes(serialize($value)). "'"; } return $value; } public static function addSlashesForInput($str) { if (!get_magic_quotes_gpc()) { $str = addslashes($str); } return $str; } public static function addSlashesForOutput($str) { if (!get_magic_quotes_runtime()) { $str = addslashes($str); } return $str; } public static function addSlashes($value, $gpc = false, $df = false) { if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable) )) { return $value; } if(is_string($value)){ if (false === $gpc && true === $df) { return self::addSlashesForOutput($value); } if (false === $df && true === $gpc) { return self::addSlashesForInput($value); } return addslashes($value); } foreach($value as $key=>$_value){ $value[$key] = self::addSlashes($_value,$gpc,$df); } return $value; } public static function stripSlashes($value) { if (!$value) return $value; if (is_string($value)) return stripslashes($value); if (!is_array($value) && !($value instanceof Traversable)) return $value; foreach ($value as $key => $_value) { $value[$key] = self::stripSlashes($_value); } return $value; } public static function sqlEscape($var, $strip = true, $isArray = false) { if (is_array($var)) { if (!$isArray) return " '' "; foreach ($var as $key => $value) { $var[$key] = trim(self::sqlEscape($value, $strip)); } return $var; } elseif (is_numeric($var)) { return " '" . $var . "' "; } else { return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; } } public static function sqlImplode($array, $strip = true) { return implode(',', self::sqlEscape($array, $strip, true)); } public static function sqlSingle($array, $strip = true) { if (!is_array($array)) return ''; $array = self::sqlEscape($array, $strip, true); $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; } return $str; } public static function sqlMulti($array, $strip = true) { if (!is_array($array)) { return ''; } $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; } } return $str; } public static function sqlMetadata($data ,$tlists=array()) { if (empty($tlists) || !in_array($data , $tlists)) { $data = str_replace(array('`', ' '), '',$data); } return ' `'.$data.'` '; } private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; if (strtr($tmpname, $tmparray) != $tmpname) { return false; } return true; } } class WindString { const UTF8 = 'utf8'; const GBK = 'gbk'; public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( $string, $start, $length, $dot); } public static function strlen($string, $charset = self::UTF8) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; $count++; } return $count; } public static function varToString($input, $indent = '') { switch (gettype($input)) { case 'string': return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; case 'array': $output = "array(\r\n"; foreach ($input as $key => $value) { $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( $value, $indent . "\t"); $output .= ",\r\n"; } $output .= $indent . ')'; return $output; case 'boolean': return $input ? 'true' : 'false'; case 'NULL': return 'NULL'; case 'integer': case 'double': case 'float': return "'" . (string) $input . "'"; } return 'NULL'; } public static function jsonEncode($value) { if (!function_exists('json_encode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); } public static function jsonDecode($value) { if (!function_exists('json_decode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); } public static function jsonSimpleEncode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': return '"' . addslashes( str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; case 'array': if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array(); foreach ($var as $name => $value) { $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( $value); } return '{' . join(',', $properties) . '}'; } $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); return '[' . join(',', $elements) . ']'; } return false; } public static function utf8_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j += 2; } else { $word++; } $j++; } $start = $word + 3 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 3); $j += 2; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function utf8_strlen($str) { $i = $count = 0; $len = strlen($str); while ($i < $len) { $chr = ord($str[$i]); $count++; $i++; if ($i >= $len) break; if ($chr & 0x80) { $chr <<= 1; while ($chr & 0x80) { $i++; $chr <<= 1; } } } return $count; } public static function gbk_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j++; } else { $word++; } $j++; } $start = $word + 2 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 2); $j++; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function gbk_strlen($string) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? $i += 2 : $i++; $count++; } return $count; } } class WindUtility { public static function mergeArray($array1, $array2) { foreach ($array2 as $key => $value) { if (!isset($array1[$key]) || !is_array($array1[$key])) { $array1[$key] = $value; continue; } $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); } return $array1; } public static function lcfirst($str) { if (function_exists('lcfirst')) return lcfirst($str); $str[0] = strtolower($str[0]); return $str; } public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { $randnum = rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { $randstr .= chr($randnum + 55); } else { $randstr .= chr($randnum + 61); } } return $randstr; } public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } class WindValidator { public static function isTelPhone($phone) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); } public static function isTelNumber($number) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); } public static function isQQ($qq) { return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); } public static function isZipcode($zipcode) { return 0 < preg_match('/^\d{4,8}$/', $zipcode); } public static function hasEmail($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); } public static function isEmail($string) { return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); } public static function hasIdCard($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); } public static function isIdCard($string) { return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); } public static function hasUrl($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); } public static function isUrl($string) { return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); } public static function hasChinese($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); } public static function isChinese($string) { return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); } public static function hasHtml($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); } public static function isHtml($string) { return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); } public static function hasIpv4($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); } public static function isIpv4($string) { return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); } public static function hasIpv6($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| ::([a-f0-9]{1,4}:){5}| ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )([a-f0-9]{1,4}:[a-f0-9]{1,4}| (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string, $matches, $ifAll); } public static function isIpv6($string) { return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| ::(?:[a-f0-9]{1,4}:){5}| (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string); } public static function hasScript($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); } public static function isScript($string) { return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); } public static function isEmpty($value) { return empty($value); } public static function isNonNegative($number) { return 0 <= (int) $number; } public static function isPositive($number) { return 0 < (int) $number; } public static function isNegative($number) { return 0 > (int) $number; } public static function isArray($array) { return is_array($array); } public static function isRequired($value) { return !self::isEmpty($value); } public static function inArray($needle, array $array, $strict = true) { return in_array($needle, $array, $strict); } public static function isLegalLength($string, $length, $charset = 'utf8') { Wind::import('WIND:component.utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { if (true === $ifAll) { return preg_match_all($regExp, $string, $matches); } return preg_match($regExp, $string, $matches); } }?> \ No newline at end of file From 54bde1af0d881b25cf1cf779999e987baea43387 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 25 Aug 2011 08:42:08 +0000 Subject: [PATCH 0400/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=88=A0=E9=99=A4=E7=BC=96=E8=AF=91=E6=98=AF=E5=AF=B9?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E6=96=87=E4=BB=B6=E8=BF=9B=E8=A1=8C=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E7=9A=84=E8=BF=87=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2472 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 34 ++-- wind/component/db/WindConnection.php | 104 ++++++------ wind/component/db/WindConnectionManager.php | 110 ++++++------- wind/component/db/WindResultSet.php | 12 +- wind/component/db/WindSqlStatement.php | 16 +- wind/core/WindHelper.php | 75 +++++---- wind/core/WindModule.php | 16 +- wind/core/exception/WindActionException.php | 7 +- wind/core/exception/WindFinalException.php | 5 +- wind/core/factory/WindFactory.php | 31 ++-- wind/core/filter/WindHandlerInterceptor.php | 9 +- .../filter/WindHandlerInterceptorChain.php | 4 +- wind/core/web/WindController.php | 64 -------- wind/core/web/WindErrorHandler.php | 7 +- wind/core/web/WindSimpleController.php | 34 +--- wind/core/web/WindWebApplication.php | 80 +++++---- .../WindActionInterceptorListener.php | 46 ++++++ wind/core/web/listener/WindFormListener.php | 9 - wind/core/web/view/404.htm | 140 ++++++++++++++++ wind/core/web/view/error.htm | 155 ++++++++++++++++++ wind/core/web/view/erroraction.htm | 45 +++++ 21 files changed, 657 insertions(+), 346 deletions(-) create mode 100644 wind/core/web/listener/WindActionInterceptorListener.php create mode 100644 wind/core/web/view/404.htm create mode 100644 wind/core/web/view/error.htm create mode 100644 wind/core/web/view/erroraction.htm diff --git a/wind/Wind.php b/wind/Wind.php index 3a14096f..f10fe9f9 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -1,14 +1,15 @@ * @author Qiong Wu @@ -86,6 +87,8 @@ public static function getApp() { * @return */ public static function resetApp() { + if (WIND_DEBUG & 2) + self::getApp()->getComponent('windLogger')->flush(); array_pop(self::$_currentApp); self::$_currentAppName = end(self::$_currentApp); } @@ -124,7 +127,7 @@ public static function import($filePath, $recursivePackage = false) { if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); while (($file = readdir($dh)) !== false) { - if (is_dir($dirPath . D_S . $file)) { + if (is_dir($dirPath . '/' . $file)) { if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { $_filePath = $filePath . '.' . $file . '.' . '*'; self::import($_filePath, $recursivePackage); @@ -160,7 +163,7 @@ public static function register($path, $alias = '', $includePath = false, $reset $alias = strtolower($alias); if (!empty($alias)) { if (!isset(self::$_namespace[$alias]) || $reset) - self::$_namespace[$alias] = rtrim($path, D_S) . D_S; + self::$_namespace[$alias] = rtrim($path, '/') . '/'; } if ($includePath) { if (empty(self::$_includePaths)) { @@ -195,7 +198,7 @@ public static function getRootPath($namespace) { public static function autoLoad($className, $path = '') { if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; - include $path . '.' . self::$_extensions; + @include $path . '.' . self::$_extensions; } /** @@ -226,7 +229,7 @@ public static function getRealPath($filePath, $suffix = '') { $filePath = substr($filePath, 0, $pos); } } - $filePath = str_replace('.', D_S, $filePath); + $filePath = str_replace('.', '/', $filePath); $namespace && $filePath = $namespace . $filePath; return $suffix ? $filePath . '.' . $suffix : $filePath; } @@ -243,7 +246,7 @@ public static function getRealDir($dirPath) { $dirPath = substr($dirPath, $pos + 1); } else $namespace = self::getRootPath(self::getAppName()); - $namespace && $dirPath = $namespace . D_S . str_replace('.', D_S, $dirPath); + $namespace && $dirPath = $namespace . '/' . str_replace('.', '/', $dirPath); return $dirPath; } @@ -251,8 +254,7 @@ public static function getRealDir($dirPath) { * 初始化框架 */ public static function init() { - if (IS_DEBUG) - self::_checkEnvironment(); + function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); self::_setDefaultSystemNamespace(); self::_registerAutoloader(); self::_loadBaseLib(); @@ -283,7 +285,7 @@ protected static function beforRun($appName, $config, $rootPath) { */ private static function _setDefaultSystemNamespace() { self::register(WIND_PATH, 'WIND', true); - self::register(WIND_PATH . 'component' . D_S, 'COM', true); + self::register(WIND_PATH . 'component' . '/', 'COM', true); } /** diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php index 9db72f41..ffd2220a 100644 --- a/wind/component/db/WindConnection.php +++ b/wind/component/db/WindConnection.php @@ -9,12 +9,6 @@ * @package */ class WindConnection extends WindModule { - const DSN = 'dsn'; - const USER = 'user'; - const PWD = 'pwd'; - const CHARSET = 'charset'; - const ENABLELOG = 'enablelog'; - const TABLEPREFIX = 'tablePrefix'; /** * PDO 链接字符串 * @var string @@ -109,38 +103,6 @@ public function getDriverName() { return $this->_driverName; } - /** - * 获得是否启用日志记录功能 - * @return boolean $enableLog - */ - public function getEnableLog() { - return $this->_enableLog; - } - - /** - * 设置是否启用日志记录功能 - * @param boolean $enableLog - */ - public function setEnableLog($enableLog) { - $this->_enableLog = (boolean) $enableLog; - } - - /** - * 获得表前缀 - * @return string $tablePrefix - */ - public function getTablePrefix() { - return $this->_tablePrefix; - } - - /** - * 设置表前缀 - * @param string $tablePrefix - */ - public function setTablePrefix($tablePrefix) { - $this->_tablePrefix = $tablePrefix; - } - /** * 执行一条sql语句 同时返回影响行数 * @param string $sql | SQL statement @@ -148,7 +110,13 @@ public function setTablePrefix($tablePrefix) { */ public function execute($sql) { try { - return $this->getDbHandle()->exec($sql); + $result = $this->getDbHandle()->exec($sql); + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindConnection.execute] \r\n\tSQL: " . $sql . + " \r\n\tResult:" . WindString::varToString( + $result)); + return $result; } catch (PDOException $e) { $this->close(); throw new WindDbException($e->getMessage()); @@ -253,12 +221,10 @@ public function init() { (array) $this->_attributes); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->_dbHandle->setCharset($this->_charset); - if (IS_DEBUG) { - $reflection = new ReflectionClass(get_class($this)); - $properties = $reflection->getProperties(); + if (WIND_DEBUG & 2) { Wind::getApp()->getComponent('windLogger')->info( - "component.db.WindConnection.init() Initialize db connection success." . WindString::varToString( - $properties), 'component.db'); + "[component.db.WindConnection.init] Initialize db connection success. \r\n\tDSN:" . $this->_dsn . "\r\n\tUser:" . $this->_user . "\r\n\tCharset:" . $this->_charset . "\r\n\tTablePrefix:" . $this->_tablePrefix . "\r\n\tDriverName:" . $this->_driverName, + 'component.db'); } } catch (PDOException $e) { $this->close(); @@ -272,18 +238,44 @@ public function init() { */ public function setConfig($config) { parent::setConfig($config); - if (!$this->_dsn) - $this->_dsn = $this->getConfig(self::DSN, '', $this->_dsn); - if (!$this->_user) - $this->_user = $this->getConfig(self::USER, '', $this->_user); - if (!$this->_pwd) - $this->_pwd = $this->getConfig(self::PWD, '', $this->_pwd); - if (!$this->_enableLog) - $this->_enableLog = $this->getConfig(self::ENABLELOG, '', $this->_enableLog); - if (!$this->_charset) - $this->_charset = $this->getConfig(self::CHARSET, '', $this->_charset); - if (!$this->_tablePrefix) - $this->_tablePrefix = $this->getConfig(self::TABLEPREFIX, '', $this->_tablePrefix); + $this->_dsn = $this->getConfig('dsn', '', $this->_dsn); + $this->_user = $this->getConfig('user', '', $this->_user); + $this->_pwd = $this->getConfig('pwd', '', $this->_pwd); + $this->_enableLog = $this->getConfig('enablelog', '', $this->_enableLog); + $this->_charset = $this->getConfig('charset', '', $this->_charset); + $this->_tablePrefix = $this->getConfig('tableprefix', '', $this->_tablePrefix); + } + + /** + * 获得是否启用日志记录功能 + * @return boolean $enableLog + */ + public function getEnableLog() { + return $this->_enableLog; + } + + /** + * 设置是否启用日志记录功能 + * @param boolean $enableLog + */ + public function setEnableLog($enableLog) { + $this->_enableLog = (boolean) $enableLog; + } + + /** + * 获得表前缀 + * @return string $tablePrefix + */ + public function getTablePrefix() { + return $this->_tablePrefix; + } + + /** + * 设置表前缀 + * @param string $tablePrefix + */ + public function setTablePrefix($tablePrefix) { + $this->_tablePrefix = $tablePrefix; } } ?> \ No newline at end of file diff --git a/wind/component/db/WindConnectionManager.php b/wind/component/db/WindConnectionManager.php index abd2f013..7f79e1d5 100644 --- a/wind/component/db/WindConnectionManager.php +++ b/wind/component/db/WindConnectionManager.php @@ -1,79 +1,71 @@ 'COM:db.WindConnectionManager', - 'db1' => array( - 'user' => 'xxx', - 'pwd' => 'xxx', - 'dsn' => 'mysql:host=localhost;dbname=test', - 'charset' => 'UTF8', - 'tablePrefix' => 'xx_', //新旧表前缀替换,前一个替换|之后的前缀 - ), - 'db2' => array( - 'user' => 'xxx', - 'pwd' => 'xxx', - 'dsn' => 'mysql:host=localhost;dbname=test', - 'charset' => 'UTF8', - 'tablePrefix' => 'xx_', //新旧表前缀替换,前一个替换|之后的前缀 - ), - ), - */ -/** + * + * + * mysql:host=localhost;dbname=test + * root + * root + * utf8 + * pw_ + * + * + * mysql:host=localhost;dbname=test + * root + * root + * utf8 + * pw_ + * + * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ -class WindConnectionManager extends WindModule { - const CONNECTION_MODE_RAND = '0'; +class WindConnectionManager extends WindConnection { /** - * 链接句柄 - * + * 链接池 * @var array */ - private $connections = array(); - - /** - * 初始化操作,将配置中的class的配置项删除 + private $connPool = array(); + + /* (non-PHPdoc) + * @see WindConnection::init() */ public function init() { - unset($this->_config['class']); - } - - /** - * 根据链接名称返回链接句柄,name为空则返回随机返回一个俩接句柄 - * @param unknown_type $name - * @return WindConnection - */ - public function getConnection($name = '') { - if (isset($this->connections[$name])) return $this->connections[$name]; - $config = array(); - if ($name !== '') { - $config = $this->getConfig($name); - if (!is_array($config) || empty($config)) { - throw new WindDbException('[component.db.WindConnectionManager.getConnection] empty config.'); + try { + $driverName = $this->getDriverName(); + $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; + $dbHandleClass = Wind::import($dbHandleClass); + $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, + (array) $this->_attributes); + $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->_dbHandle->setCharset($this->_charset); + if (WIND_DEBUG & 2) { + $reflection = new ReflectionClass(get_class($this)); + $properties = $reflection->getProperties(); + Wind::getApp()->getComponent('windLogger')->info( + "component.db.WindConnection.init() Initialize db connection success." . WindString::varToString( + $properties), 'component.db'); } - } else { - $config = $this->getCurrentConnection(); - $name = $config['name']; + } catch (PDOException $e) { + $this->close(); + throw new WindDbException($e->getMessage()); } - $connection = new WindConnection(); - $connection->setConfig($config); - $connection->init(); - $this->connections[$name] = $connection; - return $this->connections[$name]; } - /** - * 随机返回当前连接句柄的配置信息 - * @return array + /* (non-PHPdoc) + * @see WindModule::setConfig() */ - private function getCurrentConnection() { - $configs = $this->getConfig(); - $keys = array_keys($configs); - $key = count($keys) > 1 ? $keys[rand(0, count($keys) - 1)] : $keys[0]; - return $configs[$key]; + public function setConfig($config) { + if ($config) { + if (is_string($config)) + $config = Wind::getApp()->getComponent('configParser')->parse($config); + if (!empty($this->_config)) { + $this->_config = array_merge($this->_config, (array) $config); + } else + $this->_config = $config; + } } } \ No newline at end of file diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php index 4551a646..10548c2f 100644 --- a/wind/component/db/WindResultSet.php +++ b/wind/component/db/WindResultSet.php @@ -102,9 +102,10 @@ private function _fetch($fetchMode, $fetchType) { $result[$key] = $value; } } - if (IS_DEBUG) + if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( - '[component.db.WindResultSet._fetch]' . WindString::varToString($result)); + "[component.db.WindResultSet._fetch] \r\n\tResult:" . WindString::varToString( + $result)); return $result; } @@ -139,7 +140,12 @@ public function fetchAll($index = '', $fetchMode = 0) { * @return string|bool */ public function fetchColumn($index = 0) { - return $this->_statement->fetchColumn($index); + $result = $this->_statement->fetchColumn($index); + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindResultSet.fetchColumn] \r\n\tResult:" . WindString::varToString( + $result)); + return $result; } /** diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php index d06eb84b..e3cfa7a2 100644 --- a/wind/component/db/WindSqlStatement.php +++ b/wind/component/db/WindSqlStatement.php @@ -269,14 +269,20 @@ public function lastInsertId($name = '') { */ public function execute($params = array(), $rowCount = true) { try { + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->profileBegin( + 'SQL:execute sql statement.', 'component.db'); $this->init(); $this->bindValues($params); $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; - if (IS_DEBUG) + if (WIND_DEBUG & 2) { + Wind::getApp()->getComponent('windLogger')->profileEnd( + 'SQL:execute sql statement.', 'component.db'); Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindSqlStatement.execute] sql:", - $this->getStatement()->queryString, 'component.db'); + "[component.db.WindSqlStatement.execute] \r\n\tSQL:" . $this->getQueryString(), + 'component.db'); + } return $_result; } catch (PDOException $e) { throw new WindDbException('[component.db.WindSqlStatement.execute]' . $e->getMessage()); @@ -345,9 +351,9 @@ public function init() { try { $this->_statement = $this->getConnection()->getDbHandle()->prepare( $this->getQueryString()); - if (IS_DEBUG) + if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindSqlStatement.init] Initialize DBStatement", + "[component.db.WindSqlStatement.init] Initialize statement success.", 'component.db'); } catch (PDOException $e) { throw new WindDbException( diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php index 620575f4..e8425bee 100644 --- a/wind/core/WindHelper.php +++ b/wind/core/WindHelper.php @@ -10,6 +10,8 @@ */ class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; + protected static $errorDir = 'WIND:core.web.view'; + protected static $errorPage = 'error.htm'; /** * 错误处理句柄 @@ -25,7 +27,6 @@ public static function errorHandle($errno, $errstr, $errfile, $errline) { $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); - exit(); } } @@ -44,13 +45,6 @@ public static function exceptionHandle($exception) { $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); - exit(); - } - - public static function errorInfo() { - $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; - $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; - return $info; } /** @@ -60,7 +54,7 @@ public static function errorInfo() { * @param array $trace */ protected static function crash($message, $file, $line, $trace, $status = 0) { - $errmessage = substr($message, 0, 8000) . "\n"; + $errmessage = substr($message, 0, 8000); $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { @@ -69,9 +63,10 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { break; } } - $msg = $msghtml = ''; - if (IS_DEBUG) { - $errtrace = "__Stack:\n"; + $msg = ''; + if (WIND_DEBUG) { + $_errorPage = 'error.htm'; + /* format error trace */ $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { @@ -79,13 +74,11 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } - $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); - $errtrace .= "$traceLine\n"; + $trace[$key] = $traceLine; } - $msg = "$file\n"; - $msghtml = "$file\n"; + /* format error code */ if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); @@ -97,31 +90,39 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); - - $msg .= implode("\n", $fileLines) . "\n"; - $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; - $msghtml .= implode("\n", $fileLines) . "\n"; } } - $msg .= "$errtrace\n"; - $msghtml .= "$errtrace\n"; - } - $msghtml .= self::errorInfo(); + $msg .= "$file\n" . implode("\n", $fileLines) . "\n" . implode("\n", $trace); + } else + $_errorPage = '404.htm'; + if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; - header('HTTP/1.x ' . $status . ' ' . $_statusMsg); - header('Status: ' . $status . ' ' . $_statusMsg); } else - $topic = "Wind Framework - Error Caught\n"; + $topic = "Wind Framework - Error Caught"; + + $msg = "$topic\n$errmessage\n" . $msg . "\n\n" . self::errorInfo(); - $msghtml = "$topic

$topic

$errmessage\n$msghtml
"; - $msg = "$topic\n$errmessage\n$msg"; - ob_end_clean(); - $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); - $msghtml = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msghtml); - Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', true); - die($_errhtml ? $msghtml : $msg); + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', + true); + + if ($_errhtml) { + ob_start(); + $errDir = Wind::getApp()->getConfig('errorpage'); + !$errDir && $errDir = self::$errorDir; + if (isset($_statusMsg)) { + header('HTTP/1.x ' . $status . ' ' . $_statusMsg); + header('Status: ' . $status . ' ' . $_statusMsg); + is_file(Wind::getRealPath($errDir) . '.' . $status . '.htm') && $_errorPage = $status . '.htm'; + } + require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, + true); + $msg = ob_get_clean(); + } + $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~/', $msg); + die($msg); } /** @@ -172,6 +173,12 @@ protected static function getErrorName($errorNumber) { return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } + public static function errorInfo() { + $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; + $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; + return $info; + } + /** * 解析ControllerPath * 返回解析后的controller信息,controller,module,app diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 4dd51521..ebed5e20 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -142,16 +142,14 @@ public function getConfig($configName = '', $subConfigName = '', $default = '', * @return */ public function setConfig($config) { - if (!$config) - return; - if (is_string($config)) { - $configParser = $this->getSystemFactory()->getInstance('configParser'); - $config = $configParser->parse($config); + if ($config) { + if (is_string($config)) + $config = Wind::getApp()->getComponent('configParser')->parse($config); + if (!empty($this->_config)) { + $this->_config = array_merge($this->_config, (array) $config); + } else + $this->_config = $config; } - if (!$this->_config) { - $this->_config = array_merge($this->_config, (array) $config); - } else - $this->_config = $config; } /** diff --git a/wind/core/exception/WindActionException.php b/wind/core/exception/WindActionException.php index eddd73e8..44ed6575 100644 --- a/wind/core/exception/WindActionException.php +++ b/wind/core/exception/WindActionException.php @@ -14,8 +14,11 @@ class WindActionException extends WindException { * @param WindErrorMessage $error */ public function __construct($error, $code = 0) { - $this->setError($error); - parent::__construct($error->getError(0), $code); + if ($error instanceof WindErrorMessage) { + $this->setError($error); + parent::__construct($error->getError(0), $code); + } else + parent::__construct($error, $code); } /** diff --git a/wind/core/exception/WindFinalException.php b/wind/core/exception/WindFinalException.php index 85202c25..74e2f050 100644 --- a/wind/core/exception/WindFinalException.php +++ b/wind/core/exception/WindFinalException.php @@ -7,6 +7,9 @@ * @version $Id$ * @package */ -class WindFinalException extends WindException {} +class WindFinalException extends Exception{ + + +} ?> \ No newline at end of file diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index a93a88ee..f1001e4e 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -37,9 +37,11 @@ public function getInstance($alias, $args = array()) { return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; - if (!isset($this->classDefinitions[$alias]) || !($definition = $this->classDefinitions[$alias])) - return null; + if (!isset($this->classDefinitions[$alias])) + throw new WindException( + '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); + $definition = $this->classDefinitions[$alias]; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { @@ -58,6 +60,7 @@ public function getInstance($alias, $args = array()) { $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); + !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); return $instance; } @@ -80,6 +83,8 @@ public function registInstance($instance, $alias, $scope = 'singleton') { */ static public function createInstance($className, $args = array()) { try { + if (!$className || !class_exists($className)) + throw new WindException('class is not exist.'); if (empty($args)) { return new $className(); } else { @@ -87,7 +92,9 @@ static public function createInstance($className, $args = array()) { return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { - throw new WindException($className, WindException::ERROR_CLASS_NOT_EXIST); + throw new WindException( + '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), + WindException::ERROR_CLASS_NOT_EXIST); } } @@ -100,25 +107,22 @@ public function getPrototype($alias) { /** * 动态添加类定义对象 - * * @param string $alias * @param array $classDefinition * @return */ public function addClassDefinitions($alias, $classDefinition) { - if (!is_string($alias) || empty($alias)) { + if (is_string($alias) && !empty($alias)) { + if (!isset($this->classDefinitions[$alias])) + $this->classDefinitions[$alias] = $classDefinition; + } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); - } - if (isset($this->classDefinitions[$alias])) - return; - $this->classDefinitions[$alias] = $classDefinition; } /** * 加载类定义,如果merge为true,则覆盖原有配置信息 - * * @param array $classDefinitions * @param boolean $merge * @return @@ -139,7 +143,6 @@ public function loadClassDefinitions($classDefinitions, $merge = true) { /** * 类定义检查,检查类型以是否已经存在 - * * @param array $definition * @return boolean */ @@ -174,7 +177,6 @@ protected function setScope($alias, $scope, $instance) { /** * 为类对象设置配置 - * * @param array|string $config * @param string $alias * @param WindModule $instance @@ -185,7 +187,7 @@ protected function resolveConfig($config, $alias, $instance) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, - $this->getInstance('windCache')); + Wind::getApp()->getComponent('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); @@ -193,7 +195,6 @@ protected function resolveConfig($config, $alias, $instance) { /** * 执行用户配置的初始化操作 - * * @param string $initMethod * @param object $instance * @return @@ -210,7 +211,6 @@ protected function executeInitMethod($initMethod, $instance) { /** * 为类设置代理 - * * @param string $definition * @param WindModule $instance * @return WindClassProxy @@ -227,7 +227,6 @@ protected function setProxyForClass($proxy, $instance) { /** * 将类实例的依赖注入到类实例中 - * * @param string $properties * @param WindModule $instance */ diff --git a/wind/core/filter/WindHandlerInterceptor.php b/wind/core/filter/WindHandlerInterceptor.php index c6ca0890..70d7a0b0 100644 --- a/wind/core/filter/WindHandlerInterceptor.php +++ b/wind/core/filter/WindHandlerInterceptor.php @@ -9,18 +9,11 @@ class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; - /** - * Enter description here ... - */ public function preHandle() {} - /** - * Enter description here ... - */ public function postHandle() {} /** - * Enter description here ... * @return mixed */ public function handle() { @@ -32,7 +25,7 @@ public function handle() { if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { - $this->result = $this->interceptorChain->execute(); + $this->result = $this->interceptorChain->handle(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; diff --git a/wind/core/filter/WindHandlerInterceptorChain.php b/wind/core/filter/WindHandlerInterceptorChain.php index 71a5f316..b7b53fb5 100644 --- a/wind/core/filter/WindHandlerInterceptorChain.php +++ b/wind/core/filter/WindHandlerInterceptorChain.php @@ -29,7 +29,7 @@ public function setCallBack($callBack, $args = array()) { * @throws WindException * @return void|mixed */ - public function execute() { + public function handle() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { @@ -47,7 +47,7 @@ public function execute() { */ public function getHandler() { if (count($this->_interceptors) <= 0) { - $this->addInterceptors(new WindHandlerInterceptor()); + return $this; } if ($this->_state >= count($this->_interceptors)) return null; diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php index 0700b908..08f3c655 100644 --- a/wind/core/web/WindController.php +++ b/wind/core/web/WindController.php @@ -6,45 +6,15 @@ * @package */ abstract class WindController extends WindSimpleController { - /** - * 验证类 - * - * @var string - */ - protected $validatorClass = 'WIND:component.utility.WindValidator'; - /** - * 表单类 - * - * @var string - */ - protected $formClass = ''; /* (non-PHPdoc) * @see WindSimpleController::preAction() */ final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); - if ($formClassPath = $this->getFormClass()) { - $this->registerEventListener('doAction', - new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); - } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { - if (!isset($rules['errorMessage'])) { - $rules['errorMessage'] = $this->getErrorMessage(); - } - $this->registerEventListener('doAction', - new WindValidateListener($this->request, $rules, $this->getValidatorClass())); - } return true; } - /* (non-PHPdoc) - * @see WindAction::setDefaultTemplateName() - */ - protected function setDefaultTemplateName($handlerAdapter) { - /*$_temp = $handlerAdapter->getController() . '_' . $handlerAdapter->getAction(); - $this->setTemplate($_temp);*/ - } - /* (non-PHPdoc) * @see WindAction::resolvedActionMethod() */ @@ -63,38 +33,4 @@ protected function resolvedActionMethod($handlerAdapter) { } return $action; } - - /** - * 根据请求的Action值返回Action的真正方法名 - * 可以通过覆盖该方法来改变Action的命名规则 - * @param string $action - * @return string - */ - protected function resolvedActionName($action) { - return $action . 'Action'; - } - - /** - * 实现表单验证规则 - * @param string $type - */ - protected function validatorFormRule($type) { - return array(); - } - - /** - * 返回form的类 - * @return string - */ - protected function getFormClass() { - return $this->formClass; - } - - /** - * 返回数据验证类 - * @return string - */ - protected function getValidatorClass() { - return $this->validatorClass; - } } \ No newline at end of file diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php index 0706df7a..e5a08652 100644 --- a/wind/core/web/WindErrorHandler.php +++ b/wind/core/web/WindErrorHandler.php @@ -9,6 +9,7 @@ class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; + protected $errorDir = 'WIND:core.web.view'; /* (non-PHPdoc) * @see WindAction::beforeAction() @@ -35,7 +36,9 @@ public function run() { $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); - $this->setTemplatePath('COM:viewer.errorPage'); - $this->setTemplate('default_error'); + $errDir = Wind::getApp()->getConfig('errorpage'); + !$errDir && $errDir = $this->errorDir; + $this->setTemplatePath($errDir); + $this->setTemplate('erroraction'); } } \ No newline at end of file diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index 08e72819..108740f2 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -24,29 +24,17 @@ abstract public function run(); /** * @param WindUrlBasedRouter $handlerAdapter - * @deprecated */ - protected function beforeAction($handlerAdapter) {} - - /** - * @param WindUrlBasedRouter $handlerAdapter - * @deprecated - */ - protected function afterAction($handlerAdapter) {} - - /* (non-PHPdoc) - * @see IWindController::preAction() - */ - public function preAction($handlerAdapter) { + protected function beforeAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } - /* (non-PHPdoc) - * @see IWindController::postAction() + /** + * @param WindUrlBasedRouter $handlerAdapter */ - public function postAction($handlerAdapter) {} + protected function afterAction($handlerAdapter) {} /* (non-PHPdoc) * @see IWindController::doAction() @@ -283,19 +271,5 @@ interface IWindController { * @return WindForward */ public function doAction($handlerAdapter); - - /** - * Action预处理方法 - * @param WindUrlBasedRouter $handlerAdapter - * @return - */ - public function preAction($handlerAdapter); - - /** - * Action后处理方法 - * @param WindUrlBasedRouter $handlerAdapter - * @return - */ - public function postAction($handlerAdapter); } ?> \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 60f3f05f..3793f6bd 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -52,12 +52,7 @@ public function run() { set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); - if (null == ($filterChain = $this->getFilterChain())) { - $this->processRequest(); - } else { - $filterChain->setCallBack(array($this, 'processRequest')); - $filterChain->getHandler()->handle($this->request, $this->response); - } + $this->processRequest(); restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); @@ -113,6 +108,7 @@ public function processRequest() { strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, + 'config' => $this->getConfig('actionmap'), 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); @@ -121,17 +117,42 @@ public function processRequest() { throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); - $handler->preAction($this->handlerAdapter); - $forward = $handler->doAction($this->handlerAdapter); - $handler->postAction($this->handlerAdapter); - $this->doDispatch($forward); + $this->resolveActionChain($handler); + $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { $this->sendErrorMessage($e); - } catch (WindViewException $e) { + } catch (WindException $e) { $this->sendErrorMessage($e); } } + /** + * @param WindClassProxy $handler + * @throws WindActionException + */ + protected function resolveActionChain($handler) { + $_alias = $handler->_getClassName() . '.' . $this->handlerAdapter->getAction(); + if ($formClassPath = $handler->getConfig($_alias, 'form')) { + $handler->registerEventListener('doAction', + new WindFormListener($this->getRequest(), $formClassPath, + $this->getComponent('errorMessage'))); + } + if ($_items = $handler->getConfig($_alias, 'item')) { + !isset($_items[0]) && $_items = array($_items); + foreach ((array) $_items as $item) { + if (@$item['type'] === 'interceptor' && @$item['item']) { + /*$className = @$item['class'] ? Wind::import($item['class']) : 'WindActionInterceptorListener'; + $handler->registerEventListener('doAction', + new $className($this->getRequest(), $this->getResponse(), $item['item']));*/ + } elseif (@$item['type'] === 'filter' && @$item['class']) { + $className = Wind::import($item['class']); + $handler->registerEventListener('doAction', + new $className($this->getRequest(), $this->getResponse())); + } + } + } + } + /** * 异常处理请求 * @param WindActionException actionException @@ -139,8 +160,8 @@ public function processRequest() { */ protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); - if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) - throw new WindException($exception->getMessage()); + if ($moduleName === 'error') + throw new WindFinalException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) @@ -150,6 +171,9 @@ protected function sendErrorMessage($exception) { $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { + $module = $this->getModules($moduleName); + if (empty($module)) + $module = $this->setModules('default'); preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; @@ -161,22 +185,7 @@ protected function sendErrorMessage($exception) { $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); - $this->doDispatch($forward); - } - - /** - * @return WindFilterChain - */ - protected function getFilterChain() { - if (!$filters = $this->getConfig('filters')) - return null; - $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; - unset($filters['class']); - if (empty($filters)) - return null; - $this->windFactory->addClassDefinitions($filterChainPath, - array('path' => $filterChainPath, 'scope' => 'singleton')); - return $this->windFactory->getInstance($filterChainPath, array($filters)); + $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); } /** @@ -243,9 +252,20 @@ public function registeComponent($componentName, $componentInstance, $scope) { /** * @param string $componentName + * @return object */ public function getComponent($componentName) { - return $this->windFactory->getInstance($componentName); + $component = null; + switch ($componentName) { + case 'windCache': + if ($this->getConfig('iscache', '', true)) + $component = $this->windFactory->getInstance($componentName); + break; + default: + $component = $this->windFactory->getInstance($componentName); + break; + } + return $component; } /** diff --git a/wind/core/web/listener/WindActionInterceptorListener.php b/wind/core/web/listener/WindActionInterceptorListener.php new file mode 100644 index 00000000..4031fb58 --- /dev/null +++ b/wind/core/web/listener/WindActionInterceptorListener.php @@ -0,0 +1,46 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindActionInterceptorListener extends WindHandlerInterceptor { + /** + * @var WindHttpResponse + */ + protected $response; + /** + * @var WindHttpRequest + */ + protected $request; + /** + * @var array + */ + protected $interceptors = array(); + + /** + * @param WindHttpRequest $request + * @param WindHttpResponse $response + * @param array $interceptors + */ + public function __construct($request, $response, $interceptors) { + $this->request = $request; + $this->response = $response; + $this->interceptors = $interceptors; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() {} +} + +?> \ No newline at end of file diff --git a/wind/core/web/listener/WindFormListener.php b/wind/core/web/listener/WindFormListener.php index 9ae635f9..ad18cda3 100644 --- a/wind/core/web/listener/WindFormListener.php +++ b/wind/core/web/listener/WindFormListener.php @@ -58,21 +58,12 @@ public function preHandle() { } private function sendError($errorController, $errorAction, $errors) { - if (!$this->errorMessage instanceof WindErrorMessage) - $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - - } - } ?> \ No newline at end of file diff --git a/wind/core/web/view/404.htm b/wind/core/web/view/404.htm new file mode 100644 index 00000000..e5626d85 --- /dev/null +++ b/wind/core/web/view/404.htm @@ -0,0 +1,140 @@ + + + + +404 Not Found + + + +
+
+

404 Not Found

+
+
+
+
+ + \ No newline at end of file diff --git a/wind/core/web/view/error.htm b/wind/core/web/view/error.htm new file mode 100644 index 00000000..ffa40483 --- /dev/null +++ b/wind/core/web/view/error.htm @@ -0,0 +1,155 @@ + + + + +<?php echo $topic; ?> + + + +
+

+
+

+

+
    + $value): + if($key == $currentLine):?> +
  • + +
  • + +
+ +

__Stack:

+
    + +
  • + +
+
+
+
+ + \ No newline at end of file diff --git a/wind/core/web/view/erroraction.htm b/wind/core/web/view/erroraction.htm new file mode 100644 index 00000000..97e2593f --- /dev/null +++ b/wind/core/web/view/erroraction.htm @@ -0,0 +1,45 @@ + + + + +{@G:title} + + + +
+ + + + +
+

{$errorHeader}:

+

+ {$key}. {$error}
+

+

You Can Get Help In:

+

{@WindHelper::errorInfo()}

+
+
+ + \ No newline at end of file From 9b28969939fa5a88f90dae4cd886e94290864e82 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 11:54:46 +0000 Subject: [PATCH 0401/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2473 18ba2127-5a84-46d4-baec-3457e417f034 --- .../compiler/WindTemplateCompilerAction.php | 16 +++++----------- .../compiler/WindTemplateCompilerTemplate.php | 18 +++++++++--------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/wind/component/viewer/compiler/WindTemplateCompilerAction.php b/wind/component/viewer/compiler/WindTemplateCompilerAction.php index cf734b8f..801eb5c8 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerAction.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerAction.php @@ -11,28 +11,22 @@ * @package */ class WindTemplateCompilerAction extends AbstractWindTemplateCompiler { - protected $action = ''; - - protected $controller = ''; /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() */ public function compile($key, $content) { - $_content = 'getScript() . ' ?>' . "\r\n"; - return $_content; + return 'getComponent(\'forward\'); + $_tpl_forward->forwardAction(' . $this->action . '); + Wind::getApp()->doDispatch($_tpl_forward, true); ?>'; } /** * @return string */ public function getScript() { - $_tmp = '$_tpl_forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD);' . - '$_tpl_forward->setDisplay(true);' . - '$_tpl_forward->forwardAnotherAction(\'' . $this->action . '\', \'' . $this->controller . '\');' . - '$_tpl_app = $this->getSystemFactory()->getInstance(COMPONENT_WEBAPP);'. - '$_tpl_app->doDispatch($_tpl_forward);'; + $_tmp = '$_tpl_forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD);' . '$_tpl_forward->setDisplay(true);' . '$_tpl_forward->forwardAnotherAction(\'' . $this->action . '\', \'' . $this->controller . '\');' . '$_tpl_app = $this->getSystemFactory()->getInstance(COMPONENT_WEBAPP);' . '$_tpl_app->doDispatch($_tpl_forward);'; return $_tmp; } @@ -40,7 +34,7 @@ public function getScript() { * @see AbstractWindTemplateCompiler::getProperties() */ public function getProperties() { - return array('action', 'controller'); + return array('action'); } } \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php index 08585248..21657455 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php @@ -18,24 +18,24 @@ class WindTemplateCompilerTemplate extends AbstractWindTemplateCompiler { protected $suffix = ''; protected $load = 'true'; - - protected $getVar = true; /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() */ public function compile($key, $content) { - if (!isset($this->source)) + if (!$this->source) return $content; - /*preg_match('/^{?\$(\w+)}?$/Ui', trim($this->source), $result); - if (!empty($result)) { + + preg_match('/^{?\$(\w+)}?$/Ui', $this->source, $_tmp); + if (!empty($_tmp)) { $_tpl = $this->windViewerResolver->getWindView()->templateName; - $this->source = Wind::getApp()->getResponse()->getData($_tpl, $result[1]); - }*/ - //TODO 暂时不支持 load 参数 默认全部以load模式加载子模板 + $this->source = Wind::getApp()->getResponse()->getData($_tpl, $_tmp[1]); + } if ($this->load === 'false') { list($compileFile) = $this->windViewerResolver->compile($this->source, $this->suffix); - $content = ''; + if (!empty($_tmp)) + $compileFile = str_replace($this->source, '{$' . $_tmp[1] . '}', $compileFile); + $content = ''; } else { list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, true); From addd6c2b3ec354b4537efb0a7c63425fb2cb9342 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 11:55:16 +0000 Subject: [PATCH 0402/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2474 18ba2127-5a84-46d4-baec-3457e417f034 --- .../viewer/AbstractWindTemplateCompiler.php | 21 +++-------- wind/component/viewer/IWindView.php | 2 +- wind/component/viewer/WindView.php | 35 ++++++++----------- wind/component/viewer/WindViewerResolver.php | 3 +- 4 files changed, 22 insertions(+), 39 deletions(-) diff --git a/wind/component/viewer/AbstractWindTemplateCompiler.php b/wind/component/viewer/AbstractWindTemplateCompiler.php index b64b1b3b..23e15608 100644 --- a/wind/component/viewer/AbstractWindTemplateCompiler.php +++ b/wind/component/viewer/AbstractWindTemplateCompiler.php @@ -24,8 +24,6 @@ abstract class AbstractWindTemplateCompiler extends WindHandlerInterceptor { protected $request = null; protected $response = null; - - protected $getVar = false; /** * 初始化标签解析器 @@ -75,21 +73,12 @@ protected function getProperties() { */ protected function compileProperty($content) { foreach ($this->getProperties() as $value) { - if (!$value) - continue; - preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', - $content, $result); - if (!$result) - continue; - $result = trim(str_replace($result[1], '', $result[0])); - if ($this->getVar) { - preg_match('/^{?\$(\w+)}?$/Ui', $result, $_tmp); - if (!empty($_tmp)) { - $_tpl = $this->windViewerResolver->getWindView()->templateName; - $result = Wind::getApp()->getResponse()->getData($_tpl, $_tmp[1]); - } + if ($value) { + preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', + $content, $result); + if ($result) + $this->$value = trim(str_replace($result[1], '', $result[0])); } - $this->$value = $result; } } diff --git a/wind/component/viewer/IWindView.php b/wind/component/viewer/IWindView.php index 3be5c86b..8f80ff23 100644 --- a/wind/component/viewer/IWindView.php +++ b/wind/component/viewer/IWindView.php @@ -13,7 +13,7 @@ interface IWindView { * @param WindForward $forward * @param WindUrlBasedRouter $router */ - public function render($forward, $router); + public function render(); } diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 2854f9e1..7ee64661 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -72,26 +72,19 @@ class WindView extends WindModule implements IWindView { /** * 视图渲染 - * @param WindForward $forward - * @param WindUrlBasedRouter $router + * @param boolean $display */ - public function render($forward, $router, $display = false) { - $this->templateName = $forward->getTemplateName(); + public function render($display = false) { if (!$this->templateName) return; - if (null !== ($_ext = $forward->getTemplateExt())) - $this->templateExt = $_ext; - if (null !== ($_path = $forward->getTemplatePath())) - $this->templateDir = $_path; - if (null !== ($_layout = $forward->getLayout())) - $this->layout = $_layout; + //TODO 其他输出类型 $viewResolver = $this->_getViewResolver($this); - $viewResolver->windAssign($forward->getVars(), $this->templateName); + $viewResolver->windAssign(Wind::getApp()->getResponse()->getData($this->templateName)); if ($display === false) { $this->getResponse()->setBody($viewResolver->windFetch(), $this->templateName); } else - $viewResolver->displayWindFetch(); + echo $viewResolver->windFetch(); } /* (non-PHPdoc) @@ -122,8 +115,6 @@ public function getViewTemplate($template = '', $ext = '') { if (!$template) { $template = $this->templateName; } - /* elseif (is_file($template)) - return $template; */ !$ext && $ext = $this->templateExt; return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); } @@ -141,12 +132,8 @@ public function getCompileFile($template = '') { return; if (!$template) { $template = $this->templateName; - } - /*elseif (is_file($template)) { - $_info = pathinfo($template); - $template = $_info['filename']; - }*/ - $dir = Wind::getRealDir($this->compileDir); + } + $dir = Wind::getRealDir($this->compileDir, true); if (!is_dir($dir)) throw new WindViewException( '[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); @@ -181,4 +168,12 @@ public function getLayout() { return $this->layout; } + /** + * @param string $layout + * @return string + */ + public function setLayout($layout) { + return $this->layout = $layout; + } + } \ No newline at end of file diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index 74ccd9fb..eeecb92e 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -29,7 +29,7 @@ class WindViewerResolver implements IWindViewerResolver { /** * @param WindView $windView */ - public function __construct($windView) { + public function __construct($windView = null) { $this->windView = $windView; } @@ -53,7 +53,6 @@ public function windAssign($vars, $key = '') { if ($key === '') $key = $this->windView->templateName; $this->vars[$key] = $vars; - Wind::getApp()->getResponse()->setData($vars, $key); } /** From 7603c8eec3f9ded987365adfe8487f2b8dc84d08 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 11:55:38 +0000 Subject: [PATCH 0403/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2475 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/factory/WindFactory.php | 56 +++++++++++++++++-------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php index f1001e4e..eca4656f 100644 --- a/wind/core/factory/WindFactory.php +++ b/wind/core/factory/WindFactory.php @@ -33,35 +33,39 @@ public function __construct($classDefinitions = array()) { * @see AbstractWindFactory::getInstance() */ public function getInstance($alias, $args = array()) { - if (isset($this->prototype[$alias])) - return clone $this->prototype[$alias]; - if (isset($this->instances[$alias])) - return $this->instances[$alias]; - if (!isset($this->classDefinitions[$alias])) - throw new WindException( - '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); + $instance = null; + $definition = isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : array(); + if (isset($this->prototype[$alias])) { + $instance = clone $this->prototype[$alias]; + } elseif (isset($this->instances[$alias])) { + $instance = $this->instances[$alias]; + } else { + if (!$definition) + throw new WindException( + '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); + + if (isset($definition['constructor-arg'])) + foreach ((array) $definition['constructor-arg'] as $_var) { + if (isset($_var['value'])) { + $args[] = $_var['value']; + } elseif (isset($_var['ref'])) + $args[] = $this->getInstance($_var['ref']); + } + if (!isset($definition['className'])) + $definition['className'] = Wind::import(@$definition['path']); + $instance = $this->createInstance($definition['className'], $args); + if (isset($definition['config'])) + $this->resolveConfig($definition['config'], $alias, $instance); + if (isset($definition['properties'])) + $this->buildProperties($definition['properties'], $instance); + if (isset($definition['initMethod'])) + $this->executeInitMethod($definition['initMethod'], $instance); + !isset($definition['scope']) && $definition['scope'] = 'application'; + $this->setScope($alias, $definition['scope'], $instance); + } - $definition = $this->classDefinitions[$alias]; - if (isset($definition['constructor-arg'])) - foreach ((array) $definition['constructor-arg'] as $_var) { - if (isset($_var['value'])) { - $args[] = $_var['value']; - } elseif (isset($_var['ref'])) - $args[] = $this->getInstance($_var['ref']); - } - if (!isset($definition['className'])) - $definition['className'] = Wind::import(@$definition['path']); - $instance = $this->createInstance($definition['className'], $args); - if (isset($definition['config'])) - $this->resolveConfig($definition['config'], $alias, $instance); - if (isset($definition['properties'])) - $this->buildProperties($definition['properties'], $instance); - if (isset($definition['initMethod'])) - $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); - !isset($definition['scope']) && $definition['scope'] = 'application'; - $this->setScope($alias, $definition['scope'], $instance); return $instance; } From 876a31f0087a199255ffbcbdc615b3331386b9dd Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 11:55:51 +0000 Subject: [PATCH 0404/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2476 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindController.php | 8 +++ wind/core/web/WindDispatcher.php | 59 ++++++---------- wind/core/web/WindForward.php | 98 +++----------------------- wind/core/web/WindSimpleController.php | 51 +++++--------- wind/core/web/WindWebApplication.php | 59 +++++++--------- 5 files changed, 81 insertions(+), 194 deletions(-) diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php index 08f3c655..552931e3 100644 --- a/wind/core/web/WindController.php +++ b/wind/core/web/WindController.php @@ -33,4 +33,12 @@ protected function resolvedActionMethod($handlerAdapter) { } return $action; } + + /** + * @param string $action + * @throws WindException + */ + protected function resolvedActionName($action) { + return $action . 'Action'; + } } \ No newline at end of file diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php index 74aa2e55..3c5926b6 100644 --- a/wind/core/web/WindDispatcher.php +++ b/wind/core/web/WindDispatcher.php @@ -14,7 +14,7 @@ class WindDispatcher extends WindModule { * 将上一次请求信息缓存在这个变量中 * @var array */ - protected $processCache = array(); + protected $token; /** * @var boolean */ @@ -24,18 +24,24 @@ class WindDispatcher extends WindModule { * 请求分发处理 * * @param WindForward $forward - * @param WindUrlBasedRouter $router + * @param WindRouter $router * @param boolean $display * @return */ public function dispatch($forward, $router, $display) { - $this->checkProcess($router, false); + $this->checkToken($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); - else - $this->render($forward, $router); + else { + $view = $forward->getWindView(); + if ($view->templateName) { + Wind::getApp()->getResponse()->setData($forward->getVars(), $view->templateName); + $view->render($forward, $router, $this->display); + } + $this->display = false; + } } /** @@ -49,12 +55,11 @@ protected function dispatchWithRedirect($forward, $router) { if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); - $router->reParse(); - if (!$this->checkProcess($router)) { + if ($this->checkToken($router)) throw new WindFinalException( - '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), + '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); - } + } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); @@ -72,7 +77,7 @@ protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); - + $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); @@ -85,44 +90,26 @@ protected function dispatchWithAction($forward, $router, $display) { $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); - if (!$this->checkProcess($router)) { + if ($this->checkToken($router)) throw new WindFinalException( - '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), + '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); - } + Wind::getApp()->processRequest(); } - /** - * 进行视图渲染 - * @param WindForward $forward - * @param WindUrlBasedRouter $router - * @return - */ - protected function render($forward, $router) { - if ($windViewClass = $forward->getWindView()) { - $_className = Wind::import($windViewClass); - $view = $this->getSystemFactory()->createInstance($windViewClass); - } else - $view = $this->getSystemFactory()->getInstance('windView'); - $view->render($forward, $router, $this->display); - $this->display = false; - } - /** * 检查请求是否是重复请求 * @param WindUrlBasedRouter $router * @param boolean $check * @return boolean */ - protected function checkProcess($router, $check = true) { + protected function checkToken($router, $check = true) { + $token = $router->getModule() . '/' . $router->getController() . '/' . $router->getAction(); if ($check === false) { - $this->processCache['action'] = $router->getAction(); - $this->processCache['controller'] = $router->getController(); - $this->processCache['module'] = $router->getModule(); - } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) - return false; - return true; + $this->token = $token; + } else + return !strcasecmp($token, $this->token); } } diff --git a/wind/core/web/WindForward.php b/wind/core/web/WindForward.php index f2f46fd9..55ffce15 100644 --- a/wind/core/web/WindForward.php +++ b/wind/core/web/WindForward.php @@ -9,55 +9,26 @@ class WindForward extends WindModule { /** * 定义视图处理器 - * - * @var string - */ - private $windView; - /** - * 模板名称 - * - * @var strig - */ - private $templateName; - /** - * 模板路径 - * - * @var string - */ - private $templatePath = null; - /** - * 模板扩展名 - * - * @var string - */ - private $templateExt = null; - /** - * 模板布局 - * - * @var string + * @var WindView */ - private $layout; + protected $windView = null; /** * 模板变量信息 - * * @var array */ private $vars = array(); /** * 是否为Action请求 - * * @var boolean */ private $isReAction = false; /** * 是否是重定向请求 - * * @var boolean */ private $isRedirect = false; /** * 跳转链接 - * * @var string */ private $url; @@ -208,70 +179,19 @@ public function setArgs($args) { } /** - * @return the $templateName - */ - public function getTemplateName() { - return $this->templateName; - } - - /** - * @return the $templatePath - */ - public function getTemplatePath() { - return $this->templatePath; - } - - /** - * @return the $templateExt - */ - public function getTemplateExt() { - return $this->templateExt; - } - - /** - * @return the $layout - */ - public function getLayout() { - return $this->layout; - } - - /** - * @param strig $templateName - */ - public function setTemplateName($templateName) { - $this->templateName = $templateName; - } - - /** - * @param string $templatePath - */ - public function setTemplatePath($templatePath) { - $this->templatePath = $templatePath; - } - - /** - * @param string $templateExt - */ - public function setTemplateExt($templateExt) { - $this->templateExt = $templateExt; - } - - /** - * @param string $layout - */ - public function setLayout($layout) { - $this->layout = $layout; - } - - /** - * @return string + * @return WindView */ public function getWindView() { + if ($this->windView === null) + $this->_getWindView(); + $module = Wind::getApp()->getModules(); + isset($module['template-dir']) && $this->windView->templateDir = $module['template-dir']; + isset($module['compile-dir']) && $this->windView->compileDir = $module['compile-dir']; return $this->windView; } /** - * @param string $windView + * @param WindView $windView */ public function setWindView($windView) { $this->windView = $windView; diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index 108740f2..b1c8b0ff 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -1,7 +1,6 @@ * @author Qiong Wu * @version $Id$ @@ -22,20 +21,6 @@ abstract class WindSimpleController extends WindModule implements IWindControlle */ abstract public function run(); - /** - * @param WindUrlBasedRouter $handlerAdapter - */ - protected function beforeAction($handlerAdapter) { - $this->urlHelper = null; - $this->errorMessage = null; - $this->forward = null; - } - - /** - * @param WindUrlBasedRouter $handlerAdapter - */ - protected function afterAction($handlerAdapter) {} - /* (non-PHPdoc) * @see IWindController::doAction() */ @@ -50,22 +35,30 @@ public function doAction($handlerAdapter) { return $this->forward; } + /** + * @param AbstractWindRouter $handlerAdapter + */ + protected function beforeAction($handlerAdapter) {} + + /** + * @param AbstractWindRouter $handlerAdapter + */ + protected function afterAction($handlerAdapter) {} + /** * 重定向一个请求到另外的Action - * * @param string $action - * @param string $controller * @param array $args * @param boolean $isRedirect * @return */ - protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { - $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); + protected function forwardAction($action = 'run', $args = array(), $isRedirect = false) { + //$this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); + $this->getForward()->forwardAction($action, $args, $isRedirect); } /** * 重定向一个请求到另外的URL - * * @param string $url * @return */ @@ -77,7 +70,6 @@ protected function forwardRedirect($url) { /* 数据处理 */ /** * 设置模板数据 - * * @param string|array|object $data * @param string $key * @return @@ -88,7 +80,6 @@ protected function setOutput($data, $key = '') { /** * 设置模板数据 - * * @param string|array|object $data * @param string $key * @return @@ -102,7 +93,6 @@ protected function setGlobal($data, $key = '') { * 如果输入了回调方法则返回数组: * 第一个值:value * 第二个值:验证结果 - * * @param string $name input name * @param string $type input type (GET POST COOKIE) * @param string $callback | validation for input @@ -118,49 +108,44 @@ protected function getInput($name, $type = '', $callback = null) { /* 模板处理 */ /** * 设置页面模板 - * * @param string $template * @return */ protected function setTemplate($template) { - $this->getForward()->setTemplateName($template); + $this->getForward()->getWindView()->templateName = $template; } /** * 设置模板路径 - * * @param string $templatePath * @return */ protected function setTemplatePath($templatePath) { - $this->getForward()->setTemplatePath($templatePath); + $this->getForward()->getWindView()->templateDir = $templatePath; } /** * 设置模板文件的扩展名 - * * @param string $templateExt * @return */ protected function setTemplateExt($templateExt) { - $this->getForward()->setTemplateExt($templateExt); + $this->getForward()->getWindView()->templateExt = $templateExt; } /** * 设置页面布局 * 可以是一个布局对象或者一个布局文件 - * * @param WindLayout|string $layout * @return */ protected function setLayout($layout) { - $this->getForward()->setLayout($layout); + $this->getForward()->getWindView()->setLayout($layout); } /* 错误处理 */ /** * 添加错误信息 - * * @param string $message * @param string $key * @return @@ -171,7 +156,6 @@ protected function addMessage($message, $key = '') { /** * 发送一个错误 - * * @param string $message * @param string $key * @param string $errorAction @@ -185,7 +169,6 @@ protected function showMessage($message = '', $key = '', $errorAction = '') { /** * 设置默认的模板名称 - * * @param WindUrlBasedRouter $handlerAdapter * @return */ diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 3793f6bd..02302200 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -29,6 +29,8 @@ class WindWebApplication extends WindModule implements IWindApplication { */ protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; + protected $defaultModule = array('controller-path' => 'controller', + 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); /** * 应用初始化操作 @@ -50,6 +52,7 @@ public function __construct($config, $factory) { public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); + $this->setModules('default', $this->defaultModule); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); $this->processRequest(); @@ -65,17 +68,6 @@ public function run() { public function doDispatch($forward, $display = false) { if ($forward === null) return; - $moduleName = $this->handlerAdapter->getModule(); - if (!($module = $this->getModules($moduleName))) - throw new WindActionException( - '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', - 404); - - /* @var $forward WindForward */ - if ($forward->getTemplateExt() === null && isset($module['template-ext'])) - $forward->setTemplateExt($module['template-ext']); - if ($forward->getTemplatePath() === null && isset($module['template-dir'])) - $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } @@ -85,34 +77,28 @@ public function doDispatch($forward, $display = false) { */ public function processRequest() { try { - $moduleName = $this->handlerAdapter->getModule(); - if (!$moduleName) { - $moduleName = 'default'; - $this->handlerAdapter->setModule($moduleName); - $module = $this->setModules($moduleName); - } else { - if (!($module = $this->getModules($moduleName))) - throw new WindActionException( - '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', - 404); - $module = $this->setModules($moduleName, $module); - } - $handlerPath = @$module['controller-path'] . '.' . ucfirst( - $this->handlerAdapter->getController()) . @$module['controller-suffix']; - $handlerPath = trim($handlerPath, '.'); - if (!$handlerPath) + if (!$this->handlerAdapter->getModule()) + $this->handlerAdapter->setModule('default'); + if (!($module = $this->getModules())) throw new WindActionException( - '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', + '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', 404); + $module = WindUtility::mergeArray($this->defaultModule, $module); + $handlerPath = @$module['controller-path'] . '.' . ucfirst( + $this->handlerAdapter->getController()) . @$module['controller-suffix']; + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, + 'wind.core'); - strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, - array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, + array('path' => $handlerPath, 'scope' => 'prototype', 'proxy' => true, 'config' => $this->getConfig('actionmap'), 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); + if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', @@ -207,19 +193,20 @@ protected function sendErrorMessage($exception) { * @return array */ public function setModules($name, $config = array()) { - if (isset($this->_config['modules']['default'])) + if (!isset($this->_config['modules'][$name])) { + $this->_config['modules'][$name] = (array) $config; + } + + /*if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { - $_default = array('controller-path' => 'controller', - 'controller-suffix' => 'Controller', - 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); - return $this->_config['modules'][$name]; + return $this->_config['modules'][$name];*/ } /** @@ -229,6 +216,8 @@ public function setModules($name, $config = array()) { * @return array */ public function getModules($name = '') { + if ($name === '') + return $this->getConfig('modules', $this->handlerAdapter->getModule()); return $this->getConfig('modules', $name, array()); } From c29ef2a9cf7674dd1d6789dd5c2a97304fe1781a Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 11:56:05 +0000 Subject: [PATCH 0405/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2477 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindModule.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index ebed5e20..3c80a0da 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -80,9 +80,6 @@ public function __call($methodName, $args) { } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } - throw new WindException( - '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', - WindException::ERROR_CLASS_METHOD_NOT_EXIST); } /** @@ -135,6 +132,19 @@ public function getConfig($configName = '', $subConfigName = '', $default = '', return $config[$configName][$subConfigName]; } + /** + * @return string|array + */ + public function _getConfig() { + $args = func_get_args(); + $_tmp = ''; + foreach ($args as $value) { + if (!isset($this->_config[$value])) + continue; + $_tmp = $this->_config[$value]; + } + } + /** * Config配置,如果配置信息已经存在,则会合并配置 * From 737e100b9dba6254e9d7d18d1c2d09d543a41c97 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 13:39:26 +0000 Subject: [PATCH 0406/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2478 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 28 ++-- wind/components_config.php | 16 +-- wind/core/filter/WindActionFilter.php | 86 +++++++++++++ wind/core/filter/WindFilter.php | 18 +-- wind/core/filter/WindHandlerInterceptor.php | 6 +- wind/core/web/WindController.php | 11 +- wind/core/web/WindDispatcher.php | 8 +- wind/core/web/WindForward.php | 18 ++- wind/core/web/WindSimpleController.php | 50 ++++++-- wind/core/web/WindWebApplication.php | 31 ++--- .../WindActionInterceptorListener.php | 46 ------- wind/core/web/listener/WindLoggerListener.php | 120 ------------------ 12 files changed, 188 insertions(+), 250 deletions(-) create mode 100644 wind/core/filter/WindActionFilter.php delete mode 100644 wind/core/web/listener/WindActionInterceptorListener.php delete mode 100644 wind/core/web/listener/WindLoggerListener.php diff --git a/wind/Wind.php b/wind/Wind.php index f10fe9f9..0e5657c4 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -35,17 +35,14 @@ class Wind { * @return IWindApplication */ public static function application($appName = 'default', $config = array(), $rootPath = '') { - //self::beforRun($appName, $config, $rootPath); - if (!$appName || in_array($appName, self::$_currentApp)) - throw new WindException('Nested request', WindException::ERROR_SYSTEM_ERROR); - array_push(self::$_currentApp, $appName); - self::$_currentAppName = $appName; + self::beforRun($appName, $config, $rootPath); if (!isset(self::$_app[$appName])) { - Wind::register(($rootPath ? $rootPath : dirname($_SERVER['SCRIPT_FILENAME'])), $appName, - true); $factory = new WindFactory(@include (Wind::getRealPath(self::$_components))); if ($config && !is_array($config)) $config = $factory->getInstance('configParser')->parse($config); + Wind::register( + ($rootPath ? $rootPath : (isset($config['root-path']) ? $config['root-path'] : dirname( + $_SERVER['SCRIPT_FILENAME']))), $appName, true); $appClass = @$config['class'] ? $config['class'] : 'windWebApp'; $application = $factory->getInstance($appClass, array($config, $factory)); if (!$application instanceof IWindApplication) @@ -198,7 +195,12 @@ public static function getRootPath($namespace) { public static function autoLoad($className, $path = '') { if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; - @include $path . '.' . self::$_extensions; + + //TODO + if (WIND_DEBUG & 1) + include $path . '.' . self::$_extensions; + else + @include $path . '.' . self::$_extensions; } /** @@ -215,12 +217,12 @@ public static function getImports($key = '') { * @param boolean $suffix 是否存在文件后缀true,false,default * @return string|array('isPackage','fileName','extension','realPath') */ - public static function getRealPath($filePath, $suffix = '') { + public static function getRealPath($filePath, $suffix = '', $absolut = false) { if (false !== ($pos = strpos($filePath, ':'))) { $namespace = self::getRootPath(substr($filePath, 0, $pos)); $filePath = substr($filePath, $pos + 1); } else - $namespace = self::getRootPath(self::getAppName()); + $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; if ($suffix === '') { $suffix = self::$_extensions; } elseif ($suffix === true) { @@ -237,15 +239,15 @@ public static function getRealPath($filePath, $suffix = '') { /** * 解析路径信息,并返回路径的详情 * @param string $filePath 路径信息 - * @param boolean $info 是否为目录路径 + * @param boolean $absolut 是否返回绝对路径 * @return string|array('isPackage','fileName','extension','realPath') */ - public static function getRealDir($dirPath) { + public static function getRealDir($dirPath, $absolut = false) { if (false !== ($pos = strpos($dirPath, ':'))) { $namespace = self::getRootPath(substr($dirPath, 0, $pos)); $dirPath = substr($dirPath, $pos + 1); } else - $namespace = self::getRootPath(self::getAppName()); + $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; $namespace && $dirPath = $namespace . '/' . str_replace('.', '/', $dirPath); return $dirPath; } diff --git a/wind/components_config.php b/wind/components_config.php index a023197a..43994a13 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -26,15 +26,15 @@ 'dispatcher' => array( 'path' => 'WIND:core.web.WindDispatcher', 'scope' => 'application', - 'properties' => array( - 'urlHelper' => array( - 'ref' => 'urlHelper', - ), - ), ), 'forward' => array( 'path' => 'WIND:core.web.WindForward', 'scope' => 'prototype', + 'properties' => array( + 'windView' => array( + 'ref' => 'windView', + ), + ), ), 'router' => array( 'path' => 'COM:router.WindRouter', @@ -50,9 +50,9 @@ 'config' => array( 'template-dir' => 'template', 'template-ext' => 'htm', - 'is-compile' => '', + 'is-compile' => '0', 'compile-dir' => 'compile.template', - 'is-cache' => '', + 'is-cache' => '0', ), 'properties' => array( 'viewResolver' => array( @@ -91,7 +91,7 @@ 'config' => array( 'dir' => 'data.config', 'suffix' => 'php', - 'expires' => '', + 'expires' => '0', ), ), 'viewCache' => array( diff --git a/wind/core/filter/WindActionFilter.php b/wind/core/filter/WindActionFilter.php new file mode 100644 index 00000000..adbad79e --- /dev/null +++ b/wind/core/filter/WindActionFilter.php @@ -0,0 +1,86 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class WindActionFilter extends WindHandlerInterceptor { + protected $_vars = array(); + /** + * @var WindForward + */ + protected $forward = null; + /** + * @var WindErrorMessage + */ + protected $errorMessage = null; + + /** + * @param WindForward $forward + * @param WindErrorMessage $errorMessage + */ + public function __construct($forward, $errorMessage) { + $this->forward = $forward; + $this->errorMessage = $errorMessage; + $args = func_get_args(); + unset($args[0], $args[1]); + foreach ($args as $key => $value) + property_exists(get_class($this), $key) && $this->$key = $value; + $this->_vars = $forward->getVars(); + } + + /** + * 设置模板数据 + * @param string|array|object $data + * @param string $key + * @return + */ + protected function setOutput($data, $key = '') { + $this->forward->setVars($data, $key); + } + + /** + * 设置模板数据 + * @param string|array|object $data + * @param string $key + * @return + */ + protected function setGlobal($data, $key = '') { + $this->forward->setVars($data, $key, true); + } + + /** + * 获得输入数据 + * 如果输入了回调方法则返回数组: + * 第一个值:value + * 第二个值:验证结果 + * @param string $name input name + * @param string $type input type (GET POST COOKIE) + * @param string $callback | validation for input + * @return array | string + */ + protected function getInput($name, $type = '', $callback = array()) { + $value = ''; + switch (strtolower($type)) { + case 'form': + $value = $this->getRequest()->getData($name); + break; + case IWindRequest::INPUT_TYPE_GET: + $value = $this->getRequest()->getGet($name); + break; + case IWindRequest::INPUT_TYPE_POST: + $value = $this->getRequest()->getPost($name); + break; + case IWindRequest::INPUT_TYPE_COOKIE: + $value = $this->getRequest()->getCookie($name); + break; + default: + $value = $this->getRequest()->getAttribute($name); + } + return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; + } + +} + +?> \ No newline at end of file diff --git a/wind/core/filter/WindFilter.php b/wind/core/filter/WindFilter.php index fca9bb69..827cc218 100644 --- a/wind/core/filter/WindFilter.php +++ b/wind/core/filter/WindFilter.php @@ -6,20 +6,6 @@ * @version $Id$ * @package */ -class WindFilter extends WindHandlerInterceptor { - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - - } - +abstract class WindFilter extends WindHandlerInterceptor { + } \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptor.php b/wind/core/filter/WindHandlerInterceptor.php index 70d7a0b0..7233cccd 100644 --- a/wind/core/filter/WindHandlerInterceptor.php +++ b/wind/core/filter/WindHandlerInterceptor.php @@ -5,13 +5,13 @@ * @version $Id$ * @package */ -class WindHandlerInterceptor extends WindModule { +abstract class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; - public function preHandle() {} + abstract public function preHandle(); - public function postHandle() {} + abstract public function postHandle(); /** * @return mixed diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php index 552931e3..8c70fea6 100644 --- a/wind/core/web/WindController.php +++ b/wind/core/web/WindController.php @@ -7,14 +7,6 @@ */ abstract class WindController extends WindSimpleController { - /* (non-PHPdoc) - * @see WindSimpleController::preAction() - */ - final public function preAction($handlerAdapter) { - parent::preAction($handlerAdapter); - return true; - } - /* (non-PHPdoc) * @see WindAction::resolvedActionMethod() */ @@ -22,10 +14,9 @@ protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); - if ($action == 'doAction') { + if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); - } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php index 3c5926b6..29039784 100644 --- a/wind/core/web/WindDispatcher.php +++ b/wind/core/web/WindDispatcher.php @@ -37,7 +37,9 @@ public function dispatch($forward, $router, $display) { else { $view = $forward->getWindView(); if ($view->templateName) { - Wind::getApp()->getResponse()->setData($forward->getVars(), $view->templateName); + $vars = $forward->getVars(); + Wind::getApp()->getResponse()->setData($vars, $view->templateName); + Wind::getApp()->getResponse()->setData($vars['G'], true); $view->render($forward, $router, $this->display); } $this->display = false; @@ -77,7 +79,7 @@ protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); - + $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); @@ -94,7 +96,7 @@ protected function dispatchWithAction($forward, $router, $display) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); - + Wind::getApp()->processRequest(); } diff --git a/wind/core/web/WindForward.php b/wind/core/web/WindForward.php index 55ffce15..4ad03521 100644 --- a/wind/core/web/WindForward.php +++ b/wind/core/web/WindForward.php @@ -16,7 +16,7 @@ class WindForward extends WindModule { * 模板变量信息 * @var array */ - private $vars = array(); + private $vars = array('G' => array()); /** * 是否为Action请求 * @var boolean @@ -76,15 +76,21 @@ public function forwardAction($action, $args = array(), $isRedirect = false) { * @param string|array|object $vars * @param string $key */ - public function setVars($vars, $key = '') { + public function setVars($vars, $key = '', $isG = false) { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) - $this->vars += $vars; - } else - $this->vars[$key] = $vars; - return; + if ($isG) + $this->vars['G'] = $vars; + else + $this->vars += $vars; + } else { + if ($isG) + $this->vars['G'][$key] = $vars; + else + $this->vars[$key] = $vars; + } } /** diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index b1c8b0ff..ab65c6de 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -7,6 +7,7 @@ * @package */ abstract class WindSimpleController extends WindModule implements IWindController { + protected $_vars = array(); /** * @var WindForward */ @@ -25,6 +26,8 @@ abstract public function run(); * @see IWindController::doAction() */ public function doAction($handlerAdapter) { + if ($this->forward !== null) + $this->_vars = $this->forward->getVars(); $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); @@ -35,6 +38,13 @@ public function doAction($handlerAdapter) { return $this->forward; } + /* (non-PHPdoc) + * @see IWindController::resolveActionFilter($action) + */ + public function resolveActionFilter($action) { + return array(); + } + /** * @param AbstractWindRouter $handlerAdapter */ @@ -85,7 +95,7 @@ protected function setOutput($data, $key = '') { * @return */ protected function setGlobal($data, $key = '') { - $this->getResponse()->setData($data, $key, true); + $this->getForward()->setVars($data, $key, true); } /** @@ -194,19 +204,19 @@ private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': - $value = $this->response->getData($name); + $value = $this->getRequest()->getData($name); break; case IWindRequest::INPUT_TYPE_GET: - $value = $this->request->getGet($name); + $value = $this->getRequest()->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: - $value = $this->request->getPost($name); + $value = $this->getRequest()->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: - $value = $this->request->getCookie($name); + $value = $this->getRequest()->getCookie($name); break; default: - $value = $this->request->getAttribute($name); + $value = $this->getRequest()->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } @@ -227,17 +237,31 @@ private function getInputWithArray($name, $type = '') { /** * @return WindForward */ - protected function getForward() { + public function getForward() { return $this->_getForward(); } /** * @return WindErrorMessage */ - protected function getErrorMessage() { + public function getErrorMessage() { return $this->_getErrorMessage(); } + /** + * @param WindForward $forward + */ + public function setForward($forward) { + $this->forward = $forward; + } + + /** + * @param WindErrorMessage $errorMessage + */ + public function setErrorMessage($errorMessage) { + $this->errorMessage = $errorMessage; + } + } /** @@ -254,5 +278,15 @@ interface IWindController { * @return WindForward */ public function doAction($handlerAdapter); + + /** + * 返回当前Action处理过滤连配置信息 + * + * + * + * @param string $action + * @return array + */ + public function resolveActionFilter($action); } ?> \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 02302200..d51a54a2 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -28,7 +28,6 @@ class WindWebApplication extends WindModule implements IWindApplication { * @var WindRouter */ protected $handlerAdapter = null; - protected $filterChain = 'WIND:filter.WindFilterChain'; protected $defaultModule = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); @@ -113,29 +112,27 @@ public function processRequest() { } /** - * @param WindClassProxy $handler + * @param WindSimpleController $handler * @throws WindActionException */ protected function resolveActionChain($handler) { - $_alias = $handler->_getClassName() . '.' . $this->handlerAdapter->getAction(); - if ($formClassPath = $handler->getConfig($_alias, 'form')) { + /*if ($formClassPath = $handler->getConfig($_alias, 'form')) { $handler->registerEventListener('doAction', new WindFormListener($this->getRequest(), $formClassPath, $this->getComponent('errorMessage'))); - } - if ($_items = $handler->getConfig($_alias, 'item')) { - !isset($_items[0]) && $_items = array($_items); - foreach ((array) $_items as $item) { - if (@$item['type'] === 'interceptor' && @$item['item']) { - /*$className = @$item['class'] ? Wind::import($item['class']) : 'WindActionInterceptorListener'; - $handler->registerEventListener('doAction', - new $className($this->getRequest(), $this->getResponse(), $item['item']));*/ - } elseif (@$item['type'] === 'filter' && @$item['class']) { - $className = Wind::import($item['class']); - $handler->registerEventListener('doAction', - new $className($this->getRequest(), $this->getResponse())); - } + }*/ + $filters = $handler->resolveActionFilter($this->handlerAdapter->getAction()); + foreach ((array) $filters as $filter) { + if (isset($filter['expression']) && !empty($filter['expression'])) { + list($p, $v) = explode('=', $filter['expression'] . '='); + if ($this->getRequest()->getRequest($p) != $v) + continue; } + $args = array($handler->getForward(), $handler->getErrorMessage()); + if (isset($filter['args'])) + $args = $args + (array) $filter['args']; + $handler->registerEventListener('doAction', + WindFactory::createInstance(Wind::import(@$filter['class']), $args)); } } diff --git a/wind/core/web/listener/WindActionInterceptorListener.php b/wind/core/web/listener/WindActionInterceptorListener.php deleted file mode 100644 index 4031fb58..00000000 --- a/wind/core/web/listener/WindActionInterceptorListener.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindActionInterceptorListener extends WindHandlerInterceptor { - /** - * @var WindHttpResponse - */ - protected $response; - /** - * @var WindHttpRequest - */ - protected $request; - /** - * @var array - */ - protected $interceptors = array(); - - /** - * @param WindHttpRequest $request - * @param WindHttpResponse $response - * @param array $interceptors - */ - public function __construct($request, $response, $interceptors) { - $this->request = $request; - $this->response = $response; - $this->interceptors = $interceptors; - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() {} -} - -?> \ No newline at end of file diff --git a/wind/core/web/listener/WindLoggerListener.php b/wind/core/web/listener/WindLoggerListener.php deleted file mode 100644 index 7f1137c1..00000000 --- a/wind/core/web/listener/WindLoggerListener.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindLoggerListener extends WindHandlerInterceptor { - - /** - * Enter description here ... - * @param WindHttpRequest $request - */ - public function __construct($request) { - $this->request = $request; - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - $logger = $this->getLogger(); - if ($logger instanceof WindLogger) { - $logger->info($this->getPreLogMessage(func_get_args())); - } - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - $logger = $this->getLogger(); - if ($logger instanceof WindLogger) { - $logger->info($this->getPostLogMessage(func_get_args())); - } - } - - /** - * @return WindLogger - */ - private function getLogger() { - if (!isset($this->logger)) { - $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); - $this->logger = $factory->getInstance(COMPONENT_LOGGER); - } - return $this->logger; - } - - private function getPreLogMessage($args) { - $log = $this->getLogMessage($args); - $log['caller'] = ' #[caller]: ' . $log['caller']; - $log['excute'] = ' #[excute-begin]: ' . $log['excute']; - $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; - return "{$message}
" . implode("\r\n", $log) . '
'; - } - - private function getPostLogMessage($args) { - $log = $this->getLogMessage($args); - $log['caller'] = ' #[caller]: ' . $log['caller']; - $log['excute'] = ' #[excute-end]: ' . $log['excute']; - $log['output'] = ' #[output]: ' . $this->buildArg($this->result); - $message = 'End ' . $this->event[0] . '->' . $this->event[1]; - return "{$message}
" . implode("\r\n", $log) . '
'; - } - - /** - * 获得调用的堆栈信息中回调的方法信息 - * - * @param array $args - * @return string - */ - private function getLogMessage($args) { - $method = ''; - $info = array(); - $flag = false; - foreach (debug_backtrace(false) as $traceKey => $trace) { - $class = isset($trace['class']) ? $trace['class'] : ''; - if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) - continue; - $function = isset($trace['function']) ? $trace['function'] : ''; - ($class == 'WindClassProxy' && $function == '__call') && $method = trim( - $trace['args'][0]); - ($function == $method) && $flag = true; - if (!isset($trace['file'])) - continue; - $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; - break; - } - list($class, $method) = $this->event; - $args = array_map(array($this, 'buildArg'), $args); - $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; - return $info; - } - - /** - * 将参数进行类型判断返回类型 - * 如果类型是字符串,则直接返回该字符串 - * - * @param mixed $arg - * @return string - */ - private function buildArg($arg) { - switch (gettype($arg)) { - case 'array': - return 'Array'; - break; - case 'object': - return 'Object ' . get_class($arg); - break; - default: - return "'" . $arg . "'"; - break; - } - } -} - -?> \ No newline at end of file From 96cdff0491a17292c3e0e242d5aafd4aff479d23 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 13:39:37 +0000 Subject: [PATCH 0407/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2479 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/config/components_config.xml | 8 ++++---- _compile/wind_basic.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index 443bb38e..5e6770e6 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -21,12 +21,12 @@
- - - + + + @@ -69,7 +69,7 @@ 0
- + data.view diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php index 69543277..1b4bbf6d 100644 --- a/_compile/wind_basic.php +++ b/_compile/wind_basic.php @@ -1 +1 @@ -$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if (!$config) return; if (is_string($config)) { $configParser = $this->getSystemFactory()->getInstance('configParser'); $config = $configParser->parse($config); } if (!$this->_config) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_ALL = 0; const WRITE_LEVEL = 1; const WRITE_TYPE = 2; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = '0'; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType == self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); if ($this->_writeType == self::WRITE_LEVEL) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[0]][] = $value[2]; } foreach ($_logs as $key => $value) { $key = isset($_map[$key]) ? $_map[$key] : 'all'; if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } elseif ($this->_writeType == self::WRITE_TYPE) { $_logs = array(); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logs[$value[1]][] = $value[2]; } foreach ($_logs as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $msg = stripslashes(str_replace(array("
", "\r\n", "
"), "", trim($msg))); $result = ''; switch ($level) { case self::LEVEL_INFO: $msg .= "\t(" . $type . ")"; $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $msg .= "\t(" . $type . ")"; $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $msg .= "\t(" . $type . ")\r\n"; $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $msg .= "\t(" . $type . ")"; $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message: \r\n"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= $profile[1] . "\r\n"; else $_msg .= substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1) . "\r\n"; $_msg .= "(type: $profile[2] time: " . ($timer - $profile[3]) . " mem: " . ($mem - $profile[4]) . ")"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { $this->setError($error); parent::__construct($error->getError(0), $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends WindException {} interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias])) throw new WindException( '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); $definition = $this->classDefinitions[$alias]; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (!$className) throw new WindException('class name is required.'); if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (is_string($alias) && !empty($alias)) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, Wind::getApp()->getComponent('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function execute() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { $this->addInterceptors(new WindHandlerInterceptor()); } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { if (!$this->errorMessage instanceof WindErrorMessage) $this->errorMessage = new WindErrorMessage(); $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} public function preAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } public function postAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->setTemplateName($template); } protected function setTemplatePath($templatePath) { $this->getForward()->setTemplatePath($templatePath); } protected function setTemplateExt($templateExt) { $this->getForward()->setTemplateExt($templateExt); } protected function setLayout($layout) { $this->getForward()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); public function preAction($handlerAdapter); public function postAction($handlerAdapter); } abstract class WindController extends WindSimpleController { protected $validatorClass = 'WIND:component.utility.WindValidator'; protected $formClass = ''; final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); if ($formClassPath = $this->getFormClass()) { $this->registerEventListener('doAction', new WindFormListener($this->request, $formClassPath, $this->getErrorMessage())); } elseif ($rules = $this->validatorFormRule($handlerAdapter->getAction())) { if (!isset($rules['errorMessage'])) { $rules['errorMessage'] = $this->getErrorMessage(); } $this->registerEventListener('doAction', new WindValidateListener($this->request, $rules, $this->getValidatorClass())); } return true; } protected function setDefaultTemplateName($handlerAdapter) { } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } protected function validatorFormRule($type) { return array(); } protected function getFormClass() { return $this->formClass; } protected function getValidatorClass() { return $this->validatorClass; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $this->setTemplatePath('COM:viewer.errorPage'); $this->setTemplate('default_error'); } } class WindForward extends WindModule { private $windView; private $templateName; private $templatePath = null; private $templateExt = null; private $layout; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); if (null == ($filterChain = $this->getFilterChain())) { $this->processRequest(); } else { $filterChain->setCallBack(array($this, 'processRequest')); $filterChain->getHandler()->handle($this->request, $this->response); } restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); if (IS_DEBUG) $this->getComponent('windLogger')->flush(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $handler->preAction($this->handlerAdapter); $forward = $handler->doAction($this->handlerAdapter); $handler->postAction($this->handlerAdapter); $this->doDispatch($forward); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindViewException $e) { $this->sendErrorMessage($e); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error' || !($module = $this->getModules($moduleName))) throw new WindException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->doDispatch($forward); } protected function getFilterChain() { if (!$filters = $this->getConfig('filters')) return null; $filterChainPath = @$filters['class'] ? $filters['class'] : $this->filterChain; unset($filters['class']); if (empty($filters)) return null; $this->windFactory->addClassDefinitions($filterChainPath, array('path' => $filterChainPath, 'scope' => 'singleton')); return $this->windFactory->getInstance($filterChainPath, array($filters)); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { $component = null; switch ($componentName) { case 'windCache': if ($this->getConfig('iscache') !== '0') $component = $this->windFactory->getInstance($componentName); break; default: $component = $this->windFactory->getInstance($componentName); break; } return $component; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); exit(); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); exit(); } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000) . "\n"; $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = $msghtml = ''; if (IS_DEBUG) { $errtrace = "__Stack:\n"; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $errtrace .= "$traceLine\n"; } $msg = "$file\n"; $msghtml = "$file\n"; if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); $msg .= implode("\n", $fileLines) . "\n"; $fileLines[$currentLine] = "" . $fileLines[$currentLine] . ""; $msghtml .= implode("\n", $fileLines) . "\n"; } } $msg .= "$errtrace\n"; $msghtml .= "$errtrace\n"; } $msghtml .= self::errorInfo(); if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); } else $topic = "Wind Framework - Error Caught\n"; $msghtml = "$topic

$topic

$errmessage\n$msghtml
"; $msg = "$topic\n$errmessage\n$msg"; ob_end_clean(); $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msg); $msghtml = str_replace(Wind::getRootPath(Wind::getAppName()), '~', $msghtml); Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', true); die($_errhtml ? $msghtml : $msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); (3 == $node->nodeType && trim($node->nodeValue)) && $childs[0] = (string) $node->nodeValue; if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } class WindDate { public static function getTimeZone() { return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); } public static function setTimezone($timezone) { function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); } public static function format($format = null, $dateTime = null) { return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); } public static function datePart($interval, $dateTime = null) { return date($interval, self::getTimeStamp($dateTime)); } public static function dateDiff($interval, $startDateTime, $endDateTime) { $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); $retval = 0; switch ($interval) { case "y": $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; case "m": $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; case "w": $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; case "d": $retval = bcdiv($diff, (60 * 60 * 24));break; case "h": $retval = bcdiv($diff, (60 * 60));break; case "n": $retval = bcdiv($diff, 60);break; case "s": default:$retval = $diff;break; } return $retval; } public static function dateAdd($interval, $value, $dateTime, $format = null) { $date = getdate(self::getTimeStamp($dateTime)); switch ($interval) { case "y": $date["year"] += $value;break; case "q": $date["mon"] += ($value * 3);break; case "m": $date["mon"] += $value;break; case "w": $date["mday"] += ($value * 7);break; case "d": $date["mday"] += $value;break; case "h": $date["hours"] += $value;break; case "n": $date["minutes"] += $value;break; case "s": default:$date["seconds"] += $value;break; } return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); } public static function getRealDaysInMonthsOfYear($year) { $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if (self::isLeapYear($year)) { $months[1] = 29; } return $months; } public static function getDaysInMonth($month, $year) { if (1 > $month || 12 < $month) { return 0; } if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { return 0; } return $daysInmonths[$month - 1]; } public static function getDaysInYear($year) { return self::isLeapYear($year) ? 366 : 365; } public static function getRFCDate($date = null) { $time = $date ? is_int($date) ? $date : strtotime($date) : time(); $tz = date('Z', $time); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); } public static function getChinaDate($time = null) { list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); } public static function getChinaWeek($week = null) { $week = $week ? $week : (int) date('w', time()); $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); return $weekMap[$week]; } public static function getPeriodOfTime($hour = null) { $hour = $hour ? $hour : (int) date('G', time()); $period = ''; if (0 <= $hour && 6 > $hour) { $period = '凌晨'; } elseif (6 <= $hour && 8 > $hour) { $period = '早上'; } elseif (8 <= $hour && 11 > $hour) { $period = '上午'; } elseif (11 <= $hour && 13 > $hour) { $period = '中午'; } elseif (13 <= $hour && 15 > $hour) { $period = '响午'; } elseif (15 <= $hour && 18 > $hour) { $period = '下午'; } elseif (18 <= $hour && 20 > $hour) { $period = '傍晚'; } elseif (20 <= $hour && 22 > $hour) { $period = '晚上'; } elseif (22 <= $hour && 23 >= $hour) { $period = '深夜'; } return $period; } public static function getUTCDate($dateTime = null) { $oldTimezone = self::getTimezone(); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone('UTC'); } $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone($oldTimezone); } return $date; } public static function getMicroTime($get_as_float = null,$mircrotime = null) { return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); } public static function isLeapYear($year) { if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { return true; } return false; } public static function getTimeStamp($dateTime = null){ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); } public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); $timestamp = $timestamp ? $timestamp : time(); $compareTime = strtotime(self::format('Y-m-d',$timestamp)); $currentTime = strtotime(self::format('Y-m-d',$time)); $decrease = $timestamp - $time; $result = self::format($format,$time); if (0 >= $decrease) { return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } if ($currentTime == $compareTime) { if (1 == $type) { if (60 >= $decrease) { return array($decrease . $timelang['second'], $result); } return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); } return array(self::format('H:i',$time), $result); } elseif ($currentTime == $compareTime - 86400) { return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); } elseif ($currentTime == $compareTime - 172800) { return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); } return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } } class WindGeneralDate { const FILL = 0; const DIGIT = 1; const TEXT = 2; const DEFAULT_FORMAT = 'Y-m-d H:i:s'; private $time = 0; public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { $time = time(); !$month && ((!$year) ? $month = date('m', $time) : $month = 1); !$day && ((!$year) ? $day = date('d', $time) : $day = 1); !$hours && !$year && $hours = date('H', $time); !$minutes && !$year && $minutes = date('i', $time); !$second && !$year && $second = date('s', $time); !$year && $year = date('Y', $time); $this->time = mktime($hours, $minutes, $second, $month, $day, $year); } public function getDaysInMonth() { return date('t', $this->time); } public function getDaysInYear() { return $this->isLeapYear() ? 366 : 365; } public function getDayOfYear() { return date('z', $this->time) + 1; } public function getDayOfMonth() { return date('j', $this->time); } public function getDayOfWeek() { return date('w', $this->time) + 1; } public function getWeekOfYear() { return date('W', $this->time); } public function getYear($format = true) { return date($format ? 'Y' : 'y', $this->time); } public function getMonth($display = self::FILL) { if(self::FILL == $display){ return date('m', $this->time); }elseif(self::DIGIT == $display){ return date('n', $this->time); }elseif(self::TEXT == $display){ return date('M', $this->time); } return date('n', $this->time); } public function getDay($display = self::FILL) { if(self::FILL == $display){ return date('d', $this->time); }elseif(self::DIGIT == $display){ return date('j', $this->time); }elseif(self::TEXT == $display){ return date('jS', $this->time); } return date('j', $this->time); } public function getWeek($display = self::FILL) { if(self::FILL == $display || self::DIGIT == $display){ return date('w', $this->time); }elseif(self::TEXT == $display){ return date('D', $this->time); } return date('N', $this->time); } public function get12Hours($display = self::FILL){ if(self::FILL == $display){ return date('h', $this->time); }elseif(self::DIGIT == $display){ return date('g', $this->time);; } return date('h', $this->time); } public function get24Hours($display = self::FILL){ if(self::FILL == $display){ return date('H', $this->time); }elseif(self::DIGIT == $display){ return date('G', $this->time);; } return date('H', $this->time); } public function getMinutes() { return date('i', $this->time); } public function getSeconds() { return date('s', $this->time); } public function getLocalTimeZone() { return date('T', $this->time); } public function setTime($time) { if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { $this->time = $time; } } public function getNow() { $date = getdate($this->time); return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); } public function __toString() { return $this->toString(); } public function toString($format = null) { return date($format ? $format : self::DEFAULT_FORMAT, $this->time); } public function isLeapYear() { return date('L', $this->time); } } class WindDecoder { const JSON_SLICE = 1; const JSON_IN_STR = 2; const JSON_IN_ARR = 4; const JSON_IN_OBJ = 8; const JSON_IN_CMT = 16; public static function decode($str, $useArray = true) { $str = strtolower(self::reduceString($str)); if ('true' == $str) { return true; } elseif ('false' == $str) { return false; } elseif ('null' == $str) { return null; } elseif (is_numeric($str)) { return (float)$str == (integer)$str ? (integer) $str : (float) $str; }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ return self::jsonToString($str); }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); } return false; } protected static function jsonToString($string) { $delim = substr($string, 0, 1); $chrs = substr($string, 1, -1); $decodeStr = ''; for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { $compare = substr($chrs, $c, 2); $ordCode = ord($chrs{$c}); if('\b' == $compare){ $decodeStr .= chr(0x08); ++$c; }elseif('\t' == $compare){ $decodeStr .= chr(0x09); ++$c; }elseif('\n' == $compare){ $decodeStr .= chr(0x0A); ++$c; }elseif('\f' == $compare){ $decodeStr .= chr(0x0C); ++$c; }elseif('\r' == $compare){ $decodeStr .= chr(0x0D); ++$c; }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { $decodeStr .= $chrs{++$c}; } }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $decodeStr .= self::utf16beToUTF8($utf16); $c += 5; }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ $decodeStr .= $chrs{$c}; }elseif(0xC0 == ($ordCode & 0xE0)){ $decodeStr .= substr($chrs, $c, 2); ++$c; }elseif(0xE0 == ($ordCode & 0xF0)){ $decodeStr .= substr($chrs, $c, 3); $c += 2; }elseif(0xF0 == ($ordCode & 0xF8)){ $decodeStr .= substr($chrs, $c, 4); $c += 3; }elseif(0xF8 == ($ordCode & 0xFC)){ $decodeStr .= substr($chrs, $c, 5); $c += 4; }elseif(0xFC == ($ordCode & 0xFE)){ $decodeStr .= substr($chrs, $c, 6); $c += 5; } } return $decodeStr; } protected static function jsonToArray($str) { return self::complexConvert($str,true); } protected static function jsonToObject($str) { return self::complexConvert($str,false); } protected static function complexConvert($str,$useArray = true){ if ('[' == $str{0}) { $stk = array(self::JSON_IN_ARR); $arr = array(); } else { $obj = $useArray ? array() : new stdClass(); $stk = array(self::JSON_IN_OBJ); } array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = self::reduceString($chrs); if ('' == $chrs) { return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; } for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); if (reset($stk) == self::JSON_IN_ARR) { array_push($arr, self::decode($slice, $useArray)); } elseif (reset($stk) == self::JSON_IN_OBJ) { if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $key = self::decode($parts[1], $useArray); $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { array_pop($stk); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { array_pop($stk); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { array_pop($stk); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { array_pop($stk); for ($i = $top['where']; $i <= ++$c; ++$i){ $chrs = substr_replace($chrs, ' ', $i, 1); } } } if (self::JSON_IN_ARR == reset($stk)) { return $arr; } elseif (self::JSON_IN_OBJ == reset($stk)) { return $obj; } return false; } protected static function unicodeToUTF8(&$str) { $utf8 = ''; foreach ($str as $unicode) { if ($unicode < 128) { $utf8 .= chr($unicode); } elseif ($unicode < 2048) { $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } else { $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } } return $utf8; } protected static function reduceString($str) { return trim(preg_replace(array( '#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str)); } protected static function utf16beToUTF8(&$str) { return self::unicodeToUTF8(unpack('n*', $str)); } } class WindEncoder { public static $charset = 'utf-8'; public static function encode($value) { switch (gettype($value)) { case 'boolean': return $value ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $value; case 'double': case 'float': return (float) $value; case 'string': return self::stringToJson($value); case 'array': return self::arrayToJson($value); case 'object': return self::objectToJson($value); default: return ''; } return ''; } protected static function stringToJson($string) { if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { $string = iconv($enc, 'UTF-8', $string); } $ascii = ''; $strlen = strlen($string); for ($c = 0; $c < $strlen; ++$c) { $ordVar = ord($string{$c}); if (0x08 == $ordVar) { $ascii .= '\b'; } elseif (0x09 == $ordVar) { $ascii .= '\t'; } elseif (0x0A == $ordVar) { $ascii .= '\n'; } elseif (0x0C == $ordVar) { $ascii .= '\f'; } elseif (0x0D == $ordVar) { $ascii .= '\r'; } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { $ascii .= '\\' . $string{$c}; } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { $ascii .= $string{$c}; } elseif (0xC0 == ($ordVar & 0xE0)) { $char = pack('C*', $ordVar, ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xE0 == ($ordVar & 0xF0)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF0 == ($ordVar & 0xF8)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF8 == ($ordVar & 0xFC)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xFC == ($ordVar & 0xFE)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } } return '"' . $ascii . '"'; } protected static function arrayToJson(array $array) { if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; } return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; } protected static function objectToJson($object) { if ($object instanceof Traversable) { $vars = array(); foreach ($object as $k => $v) { $vars[$k] = $v; } } else { $vars = get_object_vars($object); } return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; } protected static function nameValue($name, $value) { return self::encode(strval($name)) . ':' . self::encode($value); } protected static function utf8ToUTF16BE(&$string, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if (function_exists('mb_convert_encoding')) { return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); } $uni = self::utf8ToUnicode($string); foreach ($uni as $cp) { $out .= pack('n', $cp); } return $out; } protected static function utf8ToUnicode(&$string) { $unicode = $values = array(); $lookingFor = 1; for ($i = 0, $length = strlen($string); $i < $length; $i++) { $thisValue = ord($string[$i]); if ($thisValue < 128) { $unicode[] = $thisValue; } else { if (count($values) == 0) { $lookingFor = ($thisValue < 224) ? 2 : 3; } $values[] = $thisValue; if (count($values) == $lookingFor) { $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; $values = array(); $lookingFor = 1; } } } return $unicode; } } class WindArray { public static function mergeArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); unset($array2[$key]); } else { $tmp[$key] = $array; } } return array_merge($tmp, (array) $array2); } public static function filterArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); } } return $tmp; } public static function rebuildArrayWithKey($key, array $array) { if (!$key || !$array) { return array(); } $tmp = array(); foreach ($array as $_array) { if (isset($_array[$key])) { $tmp[$_array[$key]] = $_array; } } return $tmp; } } Wind::import("COM:utility.WindSecurity"); Wind::import("COM:utility.WindString"); class WindFile { const READ = 'rb'; const READWRITE = 'rb+'; const WRITE = 'wb'; const WRITEREAD = 'wb+'; const APPEND_WRITE = 'ab'; const APPEND_WRITEREAD = 'ab+'; public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { $temp = "\r\n "; if (!$isBuildReturn && is_array($data)) { foreach ($data as $key => $value) { if (!preg_match('/^\w+$/', $key)) continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n"; } else { ($isBuildReturn) && $temp .= " return "; $temp .= WindString::varToString($data) . ";\r\n"; } return self::write($fileName, $temp, $method, $ifLock); } public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); fclose($handle); $ifChmod && chmod($fileName, 0777); return $writeCheck; } public static function read($fileName, $method = self::READ) { $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { flock($handle, LOCK_SH); $data = fread($handle, filesize($fileName)); fclose($handle); } return $data; } public static function clearDir($dir, $ifexpiled = false) { if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { self::delFile($fullPath); } } closedir($handle); false === $ifexpiled && rmdir($dir); return true; } public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); if (!$handler = opendir($path)) { return false; } while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { if (substr($filename, 0, 1) != '.') { self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); } } else { self::delFile($path . DIRECTORY_SEPARATOR . $filename); } } } closedir($handler); true == $delDir && $level > 0 && rmdir($path); return true; } public static function getMimeType($fileName) { $suffix = self::getFileSuffix($fileName); $mimes = require rtrim(WIND_PATH, D_S) . D_S . 'component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { throw new WindException('Sorry, can not find the corresponding mime type of the file'); } return false; } public static function getDirectoryIterator($dir) { return new DirectoryIterator($dir); } public static function getFileInfo($fileName) { if (false === is_file($fileName)) { return array(); } $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); $fileInfo['ctime'] = filectime($fileName); $fileInfo['atime'] = fileatime($fileName); $fileInfo['mtime'] = filemtime($fileName); $fileInfo['readable'] = is_readable($fileName); $fileInfo['writable'] = is_writable($fileName); $fileInfo['executable'] = is_executable($fileName); $fileInfo['right'] = fileperms($fileName); $fileInfo['group'] = filegroup($fileName); $fileInfo['owner'] = fileowner($fileName); $fileInfo['mime'] = self::getMimeType($fileName); return $fileInfo; } public static function getDirectoryInfo($dir) { if (false !== is_dir($dir)) { return array(); } return stat($dir); } public static function delFile($filename) { return @unlink($filename); } public static function getFileSuffix($filename) { $filename = explode($filename, '.'); return $filename[count($filename) - 1]; } public static function appendSlashesToDir($path) { return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; } } class WindHtmlHelper { public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function encodeArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; } return $_tmp; } } class WindImage { public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); if (!$imagecreate) return false; $imgwidth = $minitemp['width']; $imgheight = $minitemp['height']; $srcX = $srcY = $dstX = $dstY =0; if (!$isProportion) { $dsDivision = $imgheight / $imgwidth; $fixDivision = $dstH / $dstW; if ($dsDivision > $fixDivision) { $tmp = $imgwidth * $fixDivision; $srcY = round(($imgheight - $tmp) / 2); $imgheight = $tmp; } else { $tmp = $imgheight / $fixDivision; $srcX = round(($imgwidth - $tmp) / 2); $imgwidth = $tmp; } } $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { $black = imagecolorallocate($thumb, 0, 0, 0); imagecolortransparent($thumb, $black); } $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); self::makeImg($minitemp['type'], $thumb, $dstFile); imagedestroy($thumb); return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); } public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { $sourcedb = $waterdb = array(); if (false === ($sourcedb = self::getImgInfo($source))) return false; if (!$waterImg && !$waterText) return false; imagealphablending($sourcedb['source'], true); if ($waterImg) { $waterdb = self::getImgInfo($waterImg); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); if ($waterdb['type'] == 'png') { $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); $sourcedb['source'] = $tmp; } else { imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); } } elseif ($waterText) { list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); empty($waterFont) && $waterFont = 12; $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); $waterdb['width'] = $temp[2] - $temp[6]; $waterdb['height'] = $temp[3] - $temp[7]; unset($temp); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); if (strlen($color) != 7) return false; $R = hexdec(substr($color, 1, 2)); $G = hexdec(substr($color, 3, 2)); $B = hexdec(substr($color, 5)); self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); } $dstsrc && $source = $dstsrc; self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); isset($waterdb['source']) && imagedestroy($waterdb['source']); imagedestroy($sourcedb['source']); return true; } private static function checkAttribute($attribute) { $attribute = is_string($attribute) ? array($attribute) : $attribute; if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; return $attribute; } private static function changeCharset($charset) { $charset = strtolower($charset); return !in_array($charset, array('utf8', 'utf-8')); } private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { if (is_array($waterPos)) return $waterPos; $wX = $wY = 0; switch (intval($waterPos)) { case 0 : $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); break; case 1 : $wX = 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 2: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 3: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 4: $wX = 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 5: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 6: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; default: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; break; } return array($wX, $wY); } private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { if (false === ($imgdata = self::getImgInfo($srcFile))) return false; if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; $imgdata['dstW'] = $dstW; $imgdata['dstH'] = $dstH; if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); } elseif ($dstW > 0 && $dstH > 0) { if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); } if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); } } else { $imgdata = false; } return $imgdata; } public static function getImgInfo($srcFile) { if (false === ($imgdata = self::getImgSize($srcFile))) return false; $imgdata['type'] = self::getTypes($imgdata['type']); if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; $imgdata['source'] = $imagecreatefromtype($srcFile); !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); return $imgdata; } private static function getImgSize($srcFile, $srcExt = null) { empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); $srcdata = array(); $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); in_array($srcExt, $exts) && $srcdata['type'] = 2; if (false === ($info = getimagesize($srcFile))) return false; list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; return $srcdata; } private static function getImgcreate($imagetype) { if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { return array('imagecreatetruecolor', 'imagecopyresampled'); } if (function_exists('imagecreate') && function_exists('imagecopyresized')) { return array('imagecreate', 'imagecopyresized'); } return array('', ''); } private static function makeImg($type, $image, $filename, $quality = '75') { $makeimage = 'image' . $type; if (!function_exists($makeimage)) return false; if ($type == 'jpeg') { $makeimage($image, $filename, $quality); } else { $makeimage($image, $filename); } return true; } private static function getTypes($id) { $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; } } Wind::import('WIND:component.utility.WindFile'); class WindPack { const STRIP_SELF = 'stripWhiteSpaceBySelf'; const STRIP_PHP = 'stripWhiteSpaceByPhp'; const STRIP_TOKEN = 'stripWhiteSpaceByToken'; private $packList = array(); private $contentInjectionPosition; private $contentInjectionCallBack = ''; public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { if (empty($dst) || empty($dir)) { return false; } $suffix = is_array($suffix) ? $suffix : array( $suffix); if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { return false; } $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->stripImport($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { if (empty($dst) || empty($fileList)) { return false; } $content = array(); $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function stripWhiteSpaceByPhp($filename) { return php_strip_whitespace($filename); } public function stripWhiteSpaceBySelf($filename, $compress = true) { $content = $this->getContentFromFile($filename); $content = $this->stripComment($content, ''); return $this->stripSpace($content, ' '); } public function stripWhiteSpaceByToken($filename) { $content = $this->getContentFromFile($filename); $compressContent = ''; $lastToken = 0; foreach (token_get_all($content) as $key => $token) { if (is_array($token)) { if (in_array($token[0], array( T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) { continue; } $compressContent .= ' ' . $token[1]; } else { $compressContent .= $token; } $lastToken = $token[0]; } return $compressContent; } public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { static $content = array(); if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { return false; } $dir = is_array($dir) ? $dir : array( $dir); foreach ($dir as $_dir) { $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; if (is_dir($_dir)) { $handle = dir($_dir); while (false != ($tmp = $handle->read())) { $name = WindFile::appendSlashesToDir($_dir) . $tmp; if (is_dir($name) && !in_array($tmp, $ndir)) { $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); } if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { $content[] = $this->$packMethod($name); $this->setPackList($file, $name); } } $handle->close(); } } return $content; } public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { return array(); } $fileList = is_array($fileList) ? $fileList : array( $fileList); foreach ($fileList as $key => $value) { if (is_array($value) && isset($value[1])) { $parents = class_parents($value[1]); $_fileList = $this->buildFileList($parents, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); $implements = class_implements($value[1]); $_fileList = $this->buildFileList($implements, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); if (key_exists($key, $this->getPackList())) continue; $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; if (is_file($file)) { $content[] = $this->$packMethod($file); $this->setPackList($key, $value); } } } } public function stripComment($content, $replace = '') { return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); } public function stripNR($content, $replace = array('\n','\r\n','\r')) { return preg_replace('/[\n\r]+/', $replace, $content); } public function stripSpace($content, $replace = ' ') { return preg_replace('/[ ]+/', $replace, $content); } public function stripPhpIdentify($content, $replace = '') { return preg_replace('/(?:<\?(?:php)*)|(\)/i', $replace, $content); } public function stripStrByRule($content, $rule, $replace = '') { return preg_replace("/$rule/", $replace, $content); } public function stripImport($content, $replace = '') { $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); if ($matchs[1]) { foreach ($matchs[1] as $key => $value) { $name = substr($value, strrpos($value, '.') + 1); if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { $strip = str_replace(array( '(', ')'), array( '\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; $content = $this->stripStrByRule($content, $strip, $replace); } } } return $content; } public function getPackList() { return $this->packList; } public function getContentFromFile($filename) { if (is_file($filename)) { $content = ''; $fp = fopen($filename, "r"); while (!feof($fp)) { $line = fgets($fp); if (in_array(strlen($line), array( 2, 3)) && in_array(ord($line), array( 9, 10, 13))) continue; $content .= $line; } fclose($fp); return $content; } return false; } public function getContentBySuffix($content, $suffix, $replace = ' ') { switch ($suffix) { case 'php': $content = '' . $replace . $content . ''; break; default: $content = '' . $replace . $content . ''; break; } return $content; } private function buildFileList($list, $fileList) { $_temp = array(); foreach ($list as $fileName) { foreach ($fileList as $key => $value) { if ($value[1] == $fileName) { $_temp[$key] = $value; break; } } } return $_temp; } public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { if (!in_array($position, array( 'before', 'after'))) $position = 'before'; $this->contentInjectionPosition = $position; $this->contentInjectionCallBack = $contentInjectionCallBack; } public function callBack($content, $replace = '') { if ($this->contentInjectionCallBack !== '') { $_content = call_user_func_array($this->contentInjectionCallBack, array( $this->getPackList())); if ($this->contentInjectionPosition == 'before') { $content = $replace . $_content . $content; } elseif ($this->contentInjectionPosition == 'after') { $content .= $replace . $_content . $replace; } } return $content; } private function isValidatePackMethod($packMethod) { return method_exists($this, $packMethod) && in_array($packMethod, array( WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN)); } private function setPackList($key, $value) { if (isset($this->packList[$key])) { if (is_array($this->packList[$key])) { array_push($this->packList[$key], $value); } else { $tmp_name = $this->packList[$key]; $this->packList[$key] = array( $tmp_name, $value); } } else { $this->packList[$key] = $value; } } } class WindSecurity { public static function escapeHTML($str) { return htmlspecialchars($str, ENT_QUOTES); } public static function stripTags($str, $allowTags = "") { return strip_tags($str, $allowTags); } public static function escapePath($fileName, $ifCheck = true) { if (!self::_escapePath($fileName, $ifCheck)) { throw new WindException('file name is illegal'); } return $fileName; } public static function escapeDir($dir) { $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } public static function escapeChar($value) { if (is_array($value)) { foreach ($value as $key => $sub) { $value[$key] = self::escapeChar($sub); } } elseif (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = self::escapeString($value); } return $value; } public static function escapeString($string) { $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } public static function quotemeta($string) { return quotemeta($string); } public function checkInputValue($value, $key = '') { if (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = "'" . addslashes($value) . "'"; } elseif (is_float($value)) { $value = (float) $value; } elseif (is_object($value) || is_array($value)) { $value = "'" . addslashes(serialize($value)). "'"; } return $value; } public static function addSlashesForInput($str) { if (!get_magic_quotes_gpc()) { $str = addslashes($str); } return $str; } public static function addSlashesForOutput($str) { if (!get_magic_quotes_runtime()) { $str = addslashes($str); } return $str; } public static function addSlashes($value, $gpc = false, $df = false) { if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable) )) { return $value; } if(is_string($value)){ if (false === $gpc && true === $df) { return self::addSlashesForOutput($value); } if (false === $df && true === $gpc) { return self::addSlashesForInput($value); } return addslashes($value); } foreach($value as $key=>$_value){ $value[$key] = self::addSlashes($_value,$gpc,$df); } return $value; } public static function stripSlashes($value) { if (!$value) return $value; if (is_string($value)) return stripslashes($value); if (!is_array($value) && !($value instanceof Traversable)) return $value; foreach ($value as $key => $_value) { $value[$key] = self::stripSlashes($_value); } return $value; } public static function sqlEscape($var, $strip = true, $isArray = false) { if (is_array($var)) { if (!$isArray) return " '' "; foreach ($var as $key => $value) { $var[$key] = trim(self::sqlEscape($value, $strip)); } return $var; } elseif (is_numeric($var)) { return " '" . $var . "' "; } else { return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; } } public static function sqlImplode($array, $strip = true) { return implode(',', self::sqlEscape($array, $strip, true)); } public static function sqlSingle($array, $strip = true) { if (!is_array($array)) return ''; $array = self::sqlEscape($array, $strip, true); $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; } return $str; } public static function sqlMulti($array, $strip = true) { if (!is_array($array)) { return ''; } $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; } } return $str; } public static function sqlMetadata($data ,$tlists=array()) { if (empty($tlists) || !in_array($data , $tlists)) { $data = str_replace(array('`', ' '), '',$data); } return ' `'.$data.'` '; } private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; if (strtr($tmpname, $tmparray) != $tmpname) { return false; } return true; } } class WindString { const UTF8 = 'utf8'; const GBK = 'gbk'; public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( $string, $start, $length, $dot); } public static function strlen($string, $charset = self::UTF8) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; $count++; } return $count; } public static function varToString($input, $indent = '') { switch (gettype($input)) { case 'string': return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; case 'array': $output = "array(\r\n"; foreach ($input as $key => $value) { $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( $value, $indent . "\t"); $output .= ",\r\n"; } $output .= $indent . ')'; return $output; case 'boolean': return $input ? 'true' : 'false'; case 'NULL': return 'NULL'; case 'integer': case 'double': case 'float': return "'" . (string) $input . "'"; } return 'NULL'; } public static function jsonEncode($value) { if (!function_exists('json_encode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); } public static function jsonDecode($value) { if (!function_exists('json_decode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); } public static function jsonSimpleEncode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': return '"' . addslashes( str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; case 'array': if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array(); foreach ($var as $name => $value) { $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( $value); } return '{' . join(',', $properties) . '}'; } $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); return '[' . join(',', $elements) . ']'; } return false; } public static function utf8_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j += 2; } else { $word++; } $j++; } $start = $word + 3 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 3); $j += 2; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function utf8_strlen($str) { $i = $count = 0; $len = strlen($str); while ($i < $len) { $chr = ord($str[$i]); $count++; $i++; if ($i >= $len) break; if ($chr & 0x80) { $chr <<= 1; while ($chr & 0x80) { $i++; $chr <<= 1; } } } return $count; } public static function gbk_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j++; } else { $word++; } $j++; } $start = $word + 2 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 2); $j++; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function gbk_strlen($string) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? $i += 2 : $i++; $count++; } return $count; } } class WindUtility { public static function mergeArray($array1, $array2) { foreach ($array2 as $key => $value) { if (!isset($array1[$key]) || !is_array($array1[$key])) { $array1[$key] = $value; continue; } $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); } return $array1; } public static function lcfirst($str) { if (function_exists('lcfirst')) return lcfirst($str); $str[0] = strtolower($str[0]); return $str; } public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { $randnum = rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { $randstr .= chr($randnum + 55); } else { $randstr .= chr($randnum + 61); } } return $randstr; } public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } class WindValidator { public static function isTelPhone($phone) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); } public static function isTelNumber($number) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); } public static function isQQ($qq) { return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); } public static function isZipcode($zipcode) { return 0 < preg_match('/^\d{4,8}$/', $zipcode); } public static function hasEmail($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); } public static function isEmail($string) { return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); } public static function hasIdCard($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); } public static function isIdCard($string) { return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); } public static function hasUrl($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); } public static function isUrl($string) { return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); } public static function hasChinese($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); } public static function isChinese($string) { return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); } public static function hasHtml($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); } public static function isHtml($string) { return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); } public static function hasIpv4($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); } public static function isIpv4($string) { return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); } public static function hasIpv6($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| ::([a-f0-9]{1,4}:){5}| ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )([a-f0-9]{1,4}:[a-f0-9]{1,4}| (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string, $matches, $ifAll); } public static function isIpv6($string) { return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| ::(?:[a-f0-9]{1,4}:){5}| (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string); } public static function hasScript($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); } public static function isScript($string) { return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); } public static function isEmpty($value) { return empty($value); } public static function isNonNegative($number) { return 0 <= (int) $number; } public static function isPositive($number) { return 0 < (int) $number; } public static function isNegative($number) { return 0 > (int) $number; } public static function isArray($array) { return is_array($array); } public static function isRequired($value) { return !self::isEmpty($value); } public static function inArray($needle, array $array, $strict = true) { return in_array($needle, $array, $strict); } public static function isLegalLength($string, $length, $charset = 'utf8') { Wind::import('WIND:component.utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { if (true === $ifAll) { return preg_match_all($regExp, $string, $matches); } return preg_match($regExp, $string, $matches); } }?> \ No newline at end of file +$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if ($config) { if (is_string($config)) $config = Wind::getApp()->getComponent('configParser')->parse($config); if (!empty($this->_config)) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_TYPE = 2; const WRITE_LEVEL = 1; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = 0; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType & self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = $_logTypes = $_logLevels = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logTypes[$value[1]][] = $value[2]; $_logLevels[$value[0]][] = $value[2]; } if ($this->_writeType & 1) { foreach ($_logLevels as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($this->_writeType & 2) { foreach ($_logTypes as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $result = ''; switch ($level) { case self::LEVEL_INFO: $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message:"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= "\r\n\t" . $profile[1]; else $_msg .= "\r\n\t" . substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1); $_msg .= "\r\n\tTime:" . ($timer - $profile[3]) . "\r\n\tMem:" . ($mem - $profile[4]) . "\r\n\tType:$profile[2]"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { if ($error instanceof WindErrorMessage) { $this->setError($error); parent::__construct($error->getError(0), $code); } else parent::__construct($error, $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends Exception{ } interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias])) throw new WindException( '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); $definition = $this->classDefinitions[$alias]; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (!$className || !class_exists($className)) throw new WindException('class is not exist.'); if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (is_string($alias) && !empty($alias)) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, Wind::getApp()->getComponent('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->handle(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function handle() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { return $this; } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindActionInterceptorListener extends WindHandlerInterceptor { protected $response; protected $request; protected $interceptors = array(); public function __construct($request, $response, $interceptors) { $this->request = $request; $this->response = $response; $this->interceptors = $interceptors; } public function preHandle() { } public function postHandle() {} } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } protected function afterAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->getWindView()->templateName = $template; } protected function setTemplatePath($templatePath) { $this->getForward()->getWindView()->templateDir = $templatePath; } protected function setTemplateExt($templateExt) { $this->getForward()->getWindView()->templateExt = $templateExt; } protected function setLayout($layout) { $this->getForward()->getWindView()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); } abstract class WindController extends WindSimpleController { final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); return true; } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; protected $errorDir = 'WIND:core.web.view'; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $errDir = Wind::getApp()->getConfig('errorpage'); !$errDir && $errDir = $this->errorDir; $this->setTemplatePath($errDir); $this->setTemplate('erroraction'); } } class WindForward extends WindModule { protected $windView = null; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->_getWindView(); } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); $this->processRequest(); restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'config' => $this->getConfig('actionmap'), 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $this->resolveActionChain($handler); $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindException $e) { $this->sendErrorMessage($e); } } protected function resolveActionChain($handler) { $_alias = $handler->_getClassName() . '.' . $this->handlerAdapter->getAction(); if ($formClassPath = $handler->getConfig($_alias, 'form')) { $handler->registerEventListener('doAction', new WindFormListener($this->getRequest(), $formClassPath, $this->getComponent('errorMessage'))); } if ($_items = $handler->getConfig($_alias, 'item')) { !isset($_items[0]) && $_items = array($_items); foreach ((array) $_items as $item) { if (@$item['type'] === 'interceptor' && @$item['item']) { } elseif (@$item['type'] === 'filter' && @$item['class']) { $className = Wind::import($item['class']); $handler->registerEventListener('doAction', new $className($this->getRequest(), $this->getResponse())); } } } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error') throw new WindFinalException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { $module = $this->getModules($moduleName); if (empty($module)) $module = $this->setModules('default'); preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { $component = null; switch ($componentName) { case 'windCache': if ($this->getConfig('iscache', '', true)) $component = $this->windFactory->getInstance($componentName); break; default: $component = $this->windFactory->getInstance($componentName); break; } return $component; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; protected static $errorDir = 'WIND:core.web.view'; protected static $errorPage = 'error.htm'; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000); $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (WIND_DEBUG) { $_errorPage = 'error.htm'; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $trace[$key] = $traceLine; } if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); } } $msg .= "$file\n" . implode("\n", $fileLines) . "\n" . implode("\n", $trace); } else $_errorPage = '404.htm'; if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; } else $topic = "Wind Framework - Error Caught"; $msg = "$topic\n$errmessage\n" . $msg . "\n\n" . self::errorInfo(); if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', true); if ($_errhtml) { ob_start(); $errDir = Wind::getApp()->getConfig('errorpage'); !$errDir && $errDir = self::$errorDir; if (isset($_statusMsg)) { header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); is_file(Wind::getRealPath($errDir) . '.' . $status . '.htm') && $_errorPage = $status . '.htm'; } require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, true); $msg = ob_get_clean(); } $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~/', $msg); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); if (3 == $node->nodeType) { $value = trim($node->nodeValue); (is_numeric($value) || $value) && $childs[0] = $value; } if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } class WindDate { public static function getTimeZone() { return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); } public static function setTimezone($timezone) { function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); } public static function format($format = null, $dateTime = null) { return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); } public static function datePart($interval, $dateTime = null) { return date($interval, self::getTimeStamp($dateTime)); } public static function dateDiff($interval, $startDateTime, $endDateTime) { $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); $retval = 0; switch ($interval) { case "y": $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; case "m": $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; case "w": $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; case "d": $retval = bcdiv($diff, (60 * 60 * 24));break; case "h": $retval = bcdiv($diff, (60 * 60));break; case "n": $retval = bcdiv($diff, 60);break; case "s": default:$retval = $diff;break; } return $retval; } public static function dateAdd($interval, $value, $dateTime, $format = null) { $date = getdate(self::getTimeStamp($dateTime)); switch ($interval) { case "y": $date["year"] += $value;break; case "q": $date["mon"] += ($value * 3);break; case "m": $date["mon"] += $value;break; case "w": $date["mday"] += ($value * 7);break; case "d": $date["mday"] += $value;break; case "h": $date["hours"] += $value;break; case "n": $date["minutes"] += $value;break; case "s": default:$date["seconds"] += $value;break; } return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); } public static function getRealDaysInMonthsOfYear($year) { $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if (self::isLeapYear($year)) { $months[1] = 29; } return $months; } public static function getDaysInMonth($month, $year) { if (1 > $month || 12 < $month) { return 0; } if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { return 0; } return $daysInmonths[$month - 1]; } public static function getDaysInYear($year) { return self::isLeapYear($year) ? 366 : 365; } public static function getRFCDate($date = null) { $time = $date ? is_int($date) ? $date : strtotime($date) : time(); $tz = date('Z', $time); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); } public static function getChinaDate($time = null) { list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); } public static function getChinaWeek($week = null) { $week = $week ? $week : (int) date('w', time()); $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); return $weekMap[$week]; } public static function getPeriodOfTime($hour = null) { $hour = $hour ? $hour : (int) date('G', time()); $period = ''; if (0 <= $hour && 6 > $hour) { $period = '凌晨'; } elseif (6 <= $hour && 8 > $hour) { $period = '早上'; } elseif (8 <= $hour && 11 > $hour) { $period = '上午'; } elseif (11 <= $hour && 13 > $hour) { $period = '中午'; } elseif (13 <= $hour && 15 > $hour) { $period = '响午'; } elseif (15 <= $hour && 18 > $hour) { $period = '下午'; } elseif (18 <= $hour && 20 > $hour) { $period = '傍晚'; } elseif (20 <= $hour && 22 > $hour) { $period = '晚上'; } elseif (22 <= $hour && 23 >= $hour) { $period = '深夜'; } return $period; } public static function getUTCDate($dateTime = null) { $oldTimezone = self::getTimezone(); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone('UTC'); } $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone($oldTimezone); } return $date; } public static function getMicroTime($get_as_float = null,$mircrotime = null) { return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); } public static function isLeapYear($year) { if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { return true; } return false; } public static function getTimeStamp($dateTime = null){ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); } public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); $timestamp = $timestamp ? $timestamp : time(); $compareTime = strtotime(self::format('Y-m-d',$timestamp)); $currentTime = strtotime(self::format('Y-m-d',$time)); $decrease = $timestamp - $time; $result = self::format($format,$time); if (0 >= $decrease) { return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } if ($currentTime == $compareTime) { if (1 == $type) { if (60 >= $decrease) { return array($decrease . $timelang['second'], $result); } return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); } return array(self::format('H:i',$time), $result); } elseif ($currentTime == $compareTime - 86400) { return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); } elseif ($currentTime == $compareTime - 172800) { return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); } return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } } class WindGeneralDate { const FILL = 0; const DIGIT = 1; const TEXT = 2; const DEFAULT_FORMAT = 'Y-m-d H:i:s'; private $time = 0; public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { $time = time(); !$month && ((!$year) ? $month = date('m', $time) : $month = 1); !$day && ((!$year) ? $day = date('d', $time) : $day = 1); !$hours && !$year && $hours = date('H', $time); !$minutes && !$year && $minutes = date('i', $time); !$second && !$year && $second = date('s', $time); !$year && $year = date('Y', $time); $this->time = mktime($hours, $minutes, $second, $month, $day, $year); } public function getDaysInMonth() { return date('t', $this->time); } public function getDaysInYear() { return $this->isLeapYear() ? 366 : 365; } public function getDayOfYear() { return date('z', $this->time) + 1; } public function getDayOfMonth() { return date('j', $this->time); } public function getDayOfWeek() { return date('w', $this->time) + 1; } public function getWeekOfYear() { return date('W', $this->time); } public function getYear($format = true) { return date($format ? 'Y' : 'y', $this->time); } public function getMonth($display = self::FILL) { if(self::FILL == $display){ return date('m', $this->time); }elseif(self::DIGIT == $display){ return date('n', $this->time); }elseif(self::TEXT == $display){ return date('M', $this->time); } return date('n', $this->time); } public function getDay($display = self::FILL) { if(self::FILL == $display){ return date('d', $this->time); }elseif(self::DIGIT == $display){ return date('j', $this->time); }elseif(self::TEXT == $display){ return date('jS', $this->time); } return date('j', $this->time); } public function getWeek($display = self::FILL) { if(self::FILL == $display || self::DIGIT == $display){ return date('w', $this->time); }elseif(self::TEXT == $display){ return date('D', $this->time); } return date('N', $this->time); } public function get12Hours($display = self::FILL){ if(self::FILL == $display){ return date('h', $this->time); }elseif(self::DIGIT == $display){ return date('g', $this->time);; } return date('h', $this->time); } public function get24Hours($display = self::FILL){ if(self::FILL == $display){ return date('H', $this->time); }elseif(self::DIGIT == $display){ return date('G', $this->time);; } return date('H', $this->time); } public function getMinutes() { return date('i', $this->time); } public function getSeconds() { return date('s', $this->time); } public function getLocalTimeZone() { return date('T', $this->time); } public function setTime($time) { if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { $this->time = $time; } } public function getNow() { $date = getdate($this->time); return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); } public function __toString() { return $this->toString(); } public function toString($format = null) { return date($format ? $format : self::DEFAULT_FORMAT, $this->time); } public function isLeapYear() { return date('L', $this->time); } } class WindDecoder { const JSON_SLICE = 1; const JSON_IN_STR = 2; const JSON_IN_ARR = 4; const JSON_IN_OBJ = 8; const JSON_IN_CMT = 16; public static function decode($str, $useArray = true) { $str = strtolower(self::reduceString($str)); if ('true' == $str) { return true; } elseif ('false' == $str) { return false; } elseif ('null' == $str) { return null; } elseif (is_numeric($str)) { return (float)$str == (integer)$str ? (integer) $str : (float) $str; }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ return self::jsonToString($str); }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); } return false; } protected static function jsonToString($string) { $delim = substr($string, 0, 1); $chrs = substr($string, 1, -1); $decodeStr = ''; for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { $compare = substr($chrs, $c, 2); $ordCode = ord($chrs{$c}); if('\b' == $compare){ $decodeStr .= chr(0x08); ++$c; }elseif('\t' == $compare){ $decodeStr .= chr(0x09); ++$c; }elseif('\n' == $compare){ $decodeStr .= chr(0x0A); ++$c; }elseif('\f' == $compare){ $decodeStr .= chr(0x0C); ++$c; }elseif('\r' == $compare){ $decodeStr .= chr(0x0D); ++$c; }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { $decodeStr .= $chrs{++$c}; } }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $decodeStr .= self::utf16beToUTF8($utf16); $c += 5; }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ $decodeStr .= $chrs{$c}; }elseif(0xC0 == ($ordCode & 0xE0)){ $decodeStr .= substr($chrs, $c, 2); ++$c; }elseif(0xE0 == ($ordCode & 0xF0)){ $decodeStr .= substr($chrs, $c, 3); $c += 2; }elseif(0xF0 == ($ordCode & 0xF8)){ $decodeStr .= substr($chrs, $c, 4); $c += 3; }elseif(0xF8 == ($ordCode & 0xFC)){ $decodeStr .= substr($chrs, $c, 5); $c += 4; }elseif(0xFC == ($ordCode & 0xFE)){ $decodeStr .= substr($chrs, $c, 6); $c += 5; } } return $decodeStr; } protected static function jsonToArray($str) { return self::complexConvert($str,true); } protected static function jsonToObject($str) { return self::complexConvert($str,false); } protected static function complexConvert($str,$useArray = true){ if ('[' == $str{0}) { $stk = array(self::JSON_IN_ARR); $arr = array(); } else { $obj = $useArray ? array() : new stdClass(); $stk = array(self::JSON_IN_OBJ); } array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = self::reduceString($chrs); if ('' == $chrs) { return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; } for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); if (reset($stk) == self::JSON_IN_ARR) { array_push($arr, self::decode($slice, $useArray)); } elseif (reset($stk) == self::JSON_IN_OBJ) { if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $key = self::decode($parts[1], $useArray); $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { array_pop($stk); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { array_pop($stk); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { array_pop($stk); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { array_pop($stk); for ($i = $top['where']; $i <= ++$c; ++$i){ $chrs = substr_replace($chrs, ' ', $i, 1); } } } if (self::JSON_IN_ARR == reset($stk)) { return $arr; } elseif (self::JSON_IN_OBJ == reset($stk)) { return $obj; } return false; } protected static function unicodeToUTF8(&$str) { $utf8 = ''; foreach ($str as $unicode) { if ($unicode < 128) { $utf8 .= chr($unicode); } elseif ($unicode < 2048) { $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } else { $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } } return $utf8; } protected static function reduceString($str) { return trim(preg_replace(array( '#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str)); } protected static function utf16beToUTF8(&$str) { return self::unicodeToUTF8(unpack('n*', $str)); } } class WindEncoder { public static $charset = 'utf-8'; public static function encode($value) { switch (gettype($value)) { case 'boolean': return $value ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $value; case 'double': case 'float': return (float) $value; case 'string': return self::stringToJson($value); case 'array': return self::arrayToJson($value); case 'object': return self::objectToJson($value); default: return ''; } return ''; } protected static function stringToJson($string) { if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { $string = iconv($enc, 'UTF-8', $string); } $ascii = ''; $strlen = strlen($string); for ($c = 0; $c < $strlen; ++$c) { $ordVar = ord($string{$c}); if (0x08 == $ordVar) { $ascii .= '\b'; } elseif (0x09 == $ordVar) { $ascii .= '\t'; } elseif (0x0A == $ordVar) { $ascii .= '\n'; } elseif (0x0C == $ordVar) { $ascii .= '\f'; } elseif (0x0D == $ordVar) { $ascii .= '\r'; } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { $ascii .= '\\' . $string{$c}; } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { $ascii .= $string{$c}; } elseif (0xC0 == ($ordVar & 0xE0)) { $char = pack('C*', $ordVar, ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xE0 == ($ordVar & 0xF0)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF0 == ($ordVar & 0xF8)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF8 == ($ordVar & 0xFC)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xFC == ($ordVar & 0xFE)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } } return '"' . $ascii . '"'; } protected static function arrayToJson(array $array) { if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; } return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; } protected static function objectToJson($object) { if ($object instanceof Traversable) { $vars = array(); foreach ($object as $k => $v) { $vars[$k] = $v; } } else { $vars = get_object_vars($object); } return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; } protected static function nameValue($name, $value) { return self::encode(strval($name)) . ':' . self::encode($value); } protected static function utf8ToUTF16BE(&$string, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if (function_exists('mb_convert_encoding')) { return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); } $uni = self::utf8ToUnicode($string); foreach ($uni as $cp) { $out .= pack('n', $cp); } return $out; } protected static function utf8ToUnicode(&$string) { $unicode = $values = array(); $lookingFor = 1; for ($i = 0, $length = strlen($string); $i < $length; $i++) { $thisValue = ord($string[$i]); if ($thisValue < 128) { $unicode[] = $thisValue; } else { if (count($values) == 0) { $lookingFor = ($thisValue < 224) ? 2 : 3; } $values[] = $thisValue; if (count($values) == $lookingFor) { $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; $values = array(); $lookingFor = 1; } } } return $unicode; } } class WindArray { public static function mergeArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); unset($array2[$key]); } else { $tmp[$key] = $array; } } return array_merge($tmp, (array) $array2); } public static function filterArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); } } return $tmp; } public static function rebuildArrayWithKey($key, array $array) { if (!$key || !$array) { return array(); } $tmp = array(); foreach ($array as $_array) { if (isset($_array[$key])) { $tmp[$_array[$key]] = $_array; } } return $tmp; } } Wind::import("COM:utility.WindSecurity"); Wind::import("COM:utility.WindString"); class WindFile { const READ = 'rb'; const READWRITE = 'rb+'; const WRITE = 'wb'; const WRITEREAD = 'wb+'; const APPEND_WRITE = 'ab'; const APPEND_WRITEREAD = 'ab+'; public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { $temp = "\r\n "; if (!$isBuildReturn && is_array($data)) { foreach ($data as $key => $value) { if (!preg_match('/^\w+$/', $key)) continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n"; } else { ($isBuildReturn) && $temp .= " return "; $temp .= WindString::varToString($data) . ";\r\n"; } return self::write($fileName, $temp, $method, $ifLock); } public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); fclose($handle); $ifChmod && chmod($fileName, 0777); return $writeCheck; } public static function read($fileName, $method = self::READ) { $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { flock($handle, LOCK_SH); $data = fread($handle, filesize($fileName)); fclose($handle); } return $data; } public static function clearDir($dir, $ifexpiled = false) { if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { self::delFile($fullPath); } } closedir($handle); false === $ifexpiled && rmdir($dir); return true; } public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); if (!$handler = opendir($path)) { return false; } while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { if (substr($filename, 0, 1) != '.') { self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); } } else { self::delFile($path . DIRECTORY_SEPARATOR . $filename); } } } closedir($handler); true == $delDir && $level > 0 && rmdir($path); return true; } public static function getMimeType($fileName) { $suffix = self::getFileSuffix($fileName); $mimes = require WIND_PATH . '/component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { throw new WindException('Sorry, can not find the corresponding mime type of the file'); } return false; } public static function getDirectoryIterator($dir) { return new DirectoryIterator($dir); } public static function getFileInfo($fileName) { if (false === is_file($fileName)) { return array(); } $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); $fileInfo['ctime'] = filectime($fileName); $fileInfo['atime'] = fileatime($fileName); $fileInfo['mtime'] = filemtime($fileName); $fileInfo['readable'] = is_readable($fileName); $fileInfo['writable'] = is_writable($fileName); $fileInfo['executable'] = is_executable($fileName); $fileInfo['right'] = fileperms($fileName); $fileInfo['group'] = filegroup($fileName); $fileInfo['owner'] = fileowner($fileName); $fileInfo['mime'] = self::getMimeType($fileName); return $fileInfo; } public static function getDirectoryInfo($dir) { if (false !== is_dir($dir)) { return array(); } return stat($dir); } public static function delFile($filename) { return @unlink($filename); } public static function getFileSuffix($filename) { $filename = explode($filename, '.'); return $filename[count($filename) - 1]; } public static function appendSlashesToDir($path) { return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; } } class WindHtmlHelper { public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function encodeArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; } return $_tmp; } } class WindImage { public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); if (!$imagecreate) return false; $imgwidth = $minitemp['width']; $imgheight = $minitemp['height']; $srcX = $srcY = $dstX = $dstY =0; if (!$isProportion) { $dsDivision = $imgheight / $imgwidth; $fixDivision = $dstH / $dstW; if ($dsDivision > $fixDivision) { $tmp = $imgwidth * $fixDivision; $srcY = round(($imgheight - $tmp) / 2); $imgheight = $tmp; } else { $tmp = $imgheight / $fixDivision; $srcX = round(($imgwidth - $tmp) / 2); $imgwidth = $tmp; } } $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { $black = imagecolorallocate($thumb, 0, 0, 0); imagecolortransparent($thumb, $black); } $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); self::makeImg($minitemp['type'], $thumb, $dstFile); imagedestroy($thumb); return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); } public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { $sourcedb = $waterdb = array(); if (false === ($sourcedb = self::getImgInfo($source))) return false; if (!$waterImg && !$waterText) return false; imagealphablending($sourcedb['source'], true); if ($waterImg) { $waterdb = self::getImgInfo($waterImg); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); if ($waterdb['type'] == 'png') { $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); $sourcedb['source'] = $tmp; } else { imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); } } elseif ($waterText) { list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); empty($waterFont) && $waterFont = 12; $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); $waterdb['width'] = $temp[2] - $temp[6]; $waterdb['height'] = $temp[3] - $temp[7]; unset($temp); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); if (strlen($color) != 7) return false; $R = hexdec(substr($color, 1, 2)); $G = hexdec(substr($color, 3, 2)); $B = hexdec(substr($color, 5)); self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); } $dstsrc && $source = $dstsrc; self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); isset($waterdb['source']) && imagedestroy($waterdb['source']); imagedestroy($sourcedb['source']); return true; } private static function checkAttribute($attribute) { $attribute = is_string($attribute) ? array($attribute) : $attribute; if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; return $attribute; } private static function changeCharset($charset) { $charset = strtolower($charset); return !in_array($charset, array('utf8', 'utf-8')); } private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { if (is_array($waterPos)) return $waterPos; $wX = $wY = 0; switch (intval($waterPos)) { case 0 : $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); break; case 1 : $wX = 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 2: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 3: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 4: $wX = 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 5: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 6: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; default: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; break; } return array($wX, $wY); } private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { if (false === ($imgdata = self::getImgInfo($srcFile))) return false; if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; $imgdata['dstW'] = $dstW; $imgdata['dstH'] = $dstH; if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); } elseif ($dstW > 0 && $dstH > 0) { if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); } if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); } } else { $imgdata = false; } return $imgdata; } public static function getImgInfo($srcFile) { if (false === ($imgdata = self::getImgSize($srcFile))) return false; $imgdata['type'] = self::getTypes($imgdata['type']); if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; $imgdata['source'] = $imagecreatefromtype($srcFile); !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); return $imgdata; } private static function getImgSize($srcFile, $srcExt = null) { empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); $srcdata = array(); $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); in_array($srcExt, $exts) && $srcdata['type'] = 2; if (false === ($info = getimagesize($srcFile))) return false; list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; return $srcdata; } private static function getImgcreate($imagetype) { if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { return array('imagecreatetruecolor', 'imagecopyresampled'); } if (function_exists('imagecreate') && function_exists('imagecopyresized')) { return array('imagecreate', 'imagecopyresized'); } return array('', ''); } private static function makeImg($type, $image, $filename, $quality = '75') { $makeimage = 'image' . $type; if (!function_exists($makeimage)) return false; if ($type == 'jpeg') { $makeimage($image, $filename, $quality); } else { $makeimage($image, $filename); } return true; } private static function getTypes($id) { $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; } } Wind::import('WIND:component.utility.WindFile'); class WindPack { const STRIP_SELF = 'stripWhiteSpaceBySelf'; const STRIP_PHP = 'stripWhiteSpaceByPhp'; const STRIP_TOKEN = 'stripWhiteSpaceByToken'; private $packList = array(); private $contentInjectionPosition; private $contentInjectionCallBack = ''; public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { if (empty($dst) || empty($dir)) { return false; } $suffix = is_array($suffix) ? $suffix : array( $suffix); if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { return false; } $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->stripImport($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { if (empty($dst) || empty($fileList)) { return false; } $content = array(); $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function stripWhiteSpaceByPhp($filename) { return php_strip_whitespace($filename); } public function stripWhiteSpaceBySelf($filename, $compress = true) { $content = $this->getContentFromFile($filename); $content = $this->stripComment($content, ''); return $this->stripSpace($content, ' '); } public function stripWhiteSpaceByToken($filename) { $content = $this->getContentFromFile($filename); $compressContent = ''; $lastToken = 0; foreach (token_get_all($content) as $key => $token) { if (is_array($token)) { if (in_array($token[0], array( T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) { continue; } $compressContent .= ' ' . $token[1]; } else { $compressContent .= $token; } $lastToken = $token[0]; } return $compressContent; } public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { static $content = array(); if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { return false; } $dir = is_array($dir) ? $dir : array( $dir); foreach ($dir as $_dir) { $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; if (is_dir($_dir)) { $handle = dir($_dir); while (false != ($tmp = $handle->read())) { $name = WindFile::appendSlashesToDir($_dir) . $tmp; if (is_dir($name) && !in_array($tmp, $ndir)) { $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); } if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { $content[] = $this->$packMethod($name); $this->setPackList($file, $name); } } $handle->close(); } } return $content; } public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { return array(); } $fileList = is_array($fileList) ? $fileList : array( $fileList); foreach ($fileList as $key => $value) { if (is_array($value) && isset($value[1])) { $parents = class_parents($value[1]); $_fileList = $this->buildFileList($parents, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); $implements = class_implements($value[1]); $_fileList = $this->buildFileList($implements, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); if (key_exists($key, $this->getPackList())) continue; $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; if (is_file($file)) { $content[] = $this->$packMethod($file); $this->setPackList($key, $value); } } } } public function stripComment($content, $replace = '') { return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); } public function stripNR($content, $replace = array('\n','\r\n','\r')) { return preg_replace('/[\n\r]+/', $replace, $content); } public function stripSpace($content, $replace = ' ') { return preg_replace('/[ ]+/', $replace, $content); } public function stripPhpIdentify($content, $replace = '') { return preg_replace('/(?:<\?(?:php)*)|(\)/i', $replace, $content); } public function stripStrByRule($content, $rule, $replace = '') { return preg_replace("/$rule/", $replace, $content); } public function stripImport($content, $replace = '') { $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); if ($matchs[1]) { foreach ($matchs[1] as $key => $value) { $name = substr($value, strrpos($value, '.') + 1); if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { $strip = str_replace(array( '(', ')'), array( '\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; $content = $this->stripStrByRule($content, $strip, $replace); } } } return $content; } public function getPackList() { return $this->packList; } public function getContentFromFile($filename) { if (is_file($filename)) { $content = ''; $fp = fopen($filename, "r"); while (!feof($fp)) { $line = fgets($fp); if (in_array(strlen($line), array( 2, 3)) && in_array(ord($line), array( 9, 10, 13))) continue; $content .= $line; } fclose($fp); return $content; } return false; } public function getContentBySuffix($content, $suffix, $replace = ' ') { switch ($suffix) { case 'php': $content = '' . $replace . $content . ''; break; default: $content = '' . $replace . $content . ''; break; } return $content; } private function buildFileList($list, $fileList) { $_temp = array(); foreach ($list as $fileName) { foreach ($fileList as $key => $value) { if ($value[1] == $fileName) { $_temp[$key] = $value; break; } } } return $_temp; } public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { if (!in_array($position, array( 'before', 'after'))) $position = 'before'; $this->contentInjectionPosition = $position; $this->contentInjectionCallBack = $contentInjectionCallBack; } public function callBack($content, $replace = '') { if ($this->contentInjectionCallBack !== '') { $_content = call_user_func_array($this->contentInjectionCallBack, array( $this->getPackList())); if ($this->contentInjectionPosition == 'before') { $content = $replace . $_content . $content; } elseif ($this->contentInjectionPosition == 'after') { $content .= $replace . $_content . $replace; } } return $content; } private function isValidatePackMethod($packMethod) { return method_exists($this, $packMethod) && in_array($packMethod, array( WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN)); } private function setPackList($key, $value) { if (isset($this->packList[$key])) { if (is_array($this->packList[$key])) { array_push($this->packList[$key], $value); } else { $tmp_name = $this->packList[$key]; $this->packList[$key] = array( $tmp_name, $value); } } else { $this->packList[$key] = $value; } } } class WindSecurity { public static function escapeHTML($str) { return htmlspecialchars($str, ENT_QUOTES); } public static function stripTags($str, $allowTags = "") { return strip_tags($str, $allowTags); } public static function escapePath($fileName, $ifCheck = true) { if (!self::_escapePath($fileName, $ifCheck)) { throw new WindException('file name is illegal'); } return $fileName; } public static function escapeDir($dir) { $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } public static function escapeChar($value) { if (is_array($value)) { foreach ($value as $key => $sub) { $value[$key] = self::escapeChar($sub); } } elseif (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = self::escapeString($value); } return $value; } public static function escapeString($string) { $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } public static function quotemeta($string) { return quotemeta($string); } public function checkInputValue($value, $key = '') { if (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = "'" . addslashes($value) . "'"; } elseif (is_float($value)) { $value = (float) $value; } elseif (is_object($value) || is_array($value)) { $value = "'" . addslashes(serialize($value)). "'"; } return $value; } public static function addSlashesForInput($str) { if (!get_magic_quotes_gpc()) { $str = addslashes($str); } return $str; } public static function addSlashesForOutput($str) { if (!get_magic_quotes_runtime()) { $str = addslashes($str); } return $str; } public static function addSlashes($value, $gpc = false, $df = false) { if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable) )) { return $value; } if(is_string($value)){ if (false === $gpc && true === $df) { return self::addSlashesForOutput($value); } if (false === $df && true === $gpc) { return self::addSlashesForInput($value); } return addslashes($value); } foreach($value as $key=>$_value){ $value[$key] = self::addSlashes($_value,$gpc,$df); } return $value; } public static function stripSlashes($value) { if (!$value) return $value; if (is_string($value)) return stripslashes($value); if (!is_array($value) && !($value instanceof Traversable)) return $value; foreach ($value as $key => $_value) { $value[$key] = self::stripSlashes($_value); } return $value; } public static function sqlEscape($var, $strip = true, $isArray = false) { if (is_array($var)) { if (!$isArray) return " '' "; foreach ($var as $key => $value) { $var[$key] = trim(self::sqlEscape($value, $strip)); } return $var; } elseif (is_numeric($var)) { return " '" . $var . "' "; } else { return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; } } public static function sqlImplode($array, $strip = true) { return implode(',', self::sqlEscape($array, $strip, true)); } public static function sqlSingle($array, $strip = true) { if (!is_array($array)) return ''; $array = self::sqlEscape($array, $strip, true); $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; } return $str; } public static function sqlMulti($array, $strip = true) { if (!is_array($array)) { return ''; } $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; } } return $str; } public static function sqlMetadata($data ,$tlists=array()) { if (empty($tlists) || !in_array($data , $tlists)) { $data = str_replace(array('`', ' '), '',$data); } return ' `'.$data.'` '; } private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; if (strtr($tmpname, $tmparray) != $tmpname) { return false; } return true; } } class WindString { const UTF8 = 'utf8'; const GBK = 'gbk'; public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( $string, $start, $length, $dot); } public static function strlen($string, $charset = self::UTF8) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; $count++; } return $count; } public static function varToString($input, $indent = '') { switch (gettype($input)) { case 'string': return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; case 'array': $output = "array(\r\n"; foreach ($input as $key => $value) { $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( $value, $indent . "\t"); $output .= ",\r\n"; } $output .= $indent . ')'; return $output; case 'boolean': return $input ? 'true' : 'false'; case 'NULL': return 'NULL'; case 'integer': case 'double': case 'float': return "'" . (string) $input . "'"; } return 'NULL'; } public static function jsonEncode($value) { if (!function_exists('json_encode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); } public static function jsonDecode($value) { if (!function_exists('json_decode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); } public static function jsonSimpleEncode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': return '"' . addslashes( str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; case 'array': if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array(); foreach ($var as $name => $value) { $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( $value); } return '{' . join(',', $properties) . '}'; } $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); return '[' . join(',', $elements) . ']'; } return false; } public static function utf8_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j += 2; } else { $word++; } $j++; } $start = $word + 3 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 3); $j += 2; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function utf8_strlen($str) { $i = $count = 0; $len = strlen($str); while ($i < $len) { $chr = ord($str[$i]); $count++; $i++; if ($i >= $len) break; if ($chr & 0x80) { $chr <<= 1; while ($chr & 0x80) { $i++; $chr <<= 1; } } } return $count; } public static function gbk_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j++; } else { $word++; } $j++; } $start = $word + 2 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 2); $j++; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function gbk_strlen($string) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? $i += 2 : $i++; $count++; } return $count; } } class WindUtility { public static function mergeArray($array1, $array2) { foreach ($array2 as $key => $value) { if (!isset($array1[$key]) || !is_array($array1[$key])) { $array1[$key] = $value; continue; } $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); } return $array1; } public static function lcfirst($str) { if (function_exists('lcfirst')) return lcfirst($str); $str[0] = strtolower($str[0]); return $str; } public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { $randnum = rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { $randstr .= chr($randnum + 55); } else { $randstr .= chr($randnum + 61); } } return $randstr; } public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } class WindValidator { public static function isTelPhone($phone) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); } public static function isTelNumber($number) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); } public static function isQQ($qq) { return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); } public static function isZipcode($zipcode) { return 0 < preg_match('/^\d{4,8}$/', $zipcode); } public static function hasEmail($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); } public static function isEmail($string) { return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); } public static function hasIdCard($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); } public static function isIdCard($string) { return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); } public static function hasUrl($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); } public static function isUrl($string) { return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); } public static function hasChinese($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); } public static function isChinese($string) { return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); } public static function hasHtml($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); } public static function isHtml($string) { return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); } public static function hasIpv4($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); } public static function isIpv4($string) { return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); } public static function hasIpv6($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| ::([a-f0-9]{1,4}:){5}| ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )([a-f0-9]{1,4}:[a-f0-9]{1,4}| (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string, $matches, $ifAll); } public static function isIpv6($string) { return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| ::(?:[a-f0-9]{1,4}:){5}| (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string); } public static function hasScript($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); } public static function isScript($string) { return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); } public static function isEmpty($value) { return empty($value); } public static function isNonNegative($number) { return 0 <= (int) $number; } public static function isPositive($number) { return 0 < (int) $number; } public static function isNegative($number) { return 0 > (int) $number; } public static function isArray($array) { return is_array($array); } public static function isRequired($value) { return !self::isEmpty($value); } public static function inArray($needle, array $array, $strict = true) { return in_array($needle, $array, $strict); } public static function isLegalLength($string, $length, $charset = 'utf8') { Wind::import('WIND:component.utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { if (true === $ifAll) { return preg_match_all($regExp, $string, $matches); } return preg_match($regExp, $string, $matches); } }?> \ No newline at end of file From 6ece9bdbf95ae25f937446cd72e63b183893cad8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 13:39:54 +0000 Subject: [PATCH 0408/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2480 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/config/db_config.xml | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/docs/config/db_config.xml b/docs/config/db_config.xml index e91f7deb..c6dd458e 100644 --- a/docs/config/db_config.xml +++ b/docs/config/db_config.xml @@ -1,22 +1,28 @@ + - - COM:db.WindConnection + mysql:host=localhost;dbname=test + root + root + utf8 + pw_ + + + + + mysql:host=localhost;dbname=test root root utf8 pw_ - - COM:db.WindConnectionManager - - mysql:host=localhost;dbname=test - root - root - utf8 - pw_ - + + mysql:host=localhost;dbname=test + root + root + utf8 + pw_ \ No newline at end of file From 24d736a2f4ccb41db008b9d09753df369d2d5ec8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 26 Aug 2011 14:32:48 +0000 Subject: [PATCH 0409/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2481 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindWebApplication.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index d51a54a2..e20bef93 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -115,24 +115,26 @@ public function processRequest() { * @param WindSimpleController $handler * @throws WindActionException */ - protected function resolveActionChain($handler) { + protected function resolveActionChain($__handler) { /*if ($formClassPath = $handler->getConfig($_alias, 'form')) { $handler->registerEventListener('doAction', new WindFormListener($this->getRequest(), $formClassPath, $this->getComponent('errorMessage'))); }*/ - $filters = $handler->resolveActionFilter($this->handlerAdapter->getAction()); - foreach ((array) $filters as $filter) { - if (isset($filter['expression']) && !empty($filter['expression'])) { - list($p, $v) = explode('=', $filter['expression'] . '='); + @extract(@$this->getRequest()->getRequest(), EXTR_REFS); + $__filters = $__handler->resolveActionFilter($this->handlerAdapter->getAction()); + foreach ((array) $__filters as $__filter) { + if (isset($__filter['expression']) && !empty($__filter['expression'])) { + var_dump(@eval('return ' . addcslashes($__filter['expression'], '"') . ';')); + /*list($p, $v) = explode('=', $__filter['expression'] . '='); if ($this->getRequest()->getRequest($p) != $v) - continue; + continue;*/ } - $args = array($handler->getForward(), $handler->getErrorMessage()); - if (isset($filter['args'])) - $args = $args + (array) $filter['args']; - $handler->registerEventListener('doAction', - WindFactory::createInstance(Wind::import(@$filter['class']), $args)); + $__args = array($__handler->getForward(), $__handler->getErrorMessage()); + if (isset($__filter['args'])) + $__args = $__args + (array) $__filter['args']; + $__handler->registerEventListener('doAction', + WindFactory::createInstance(Wind::import(@$__filter['class']), $__args)); } } From d46f8002c1c66fb1380fc0e5db5823872236a615 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 02:27:59 +0000 Subject: [PATCH 0410/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2482 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 9 +++++---- _compile/components_config.php | 25 +++++++++++++++++-------- _compile/config/components_config.xml | 5 +++++ _compile/wind_basic.php | 2 +- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/_compile/compile.php b/_compile/compile.php index 1c839c3f..482871d1 100644 --- a/_compile/compile.php +++ b/_compile/compile.php @@ -4,6 +4,7 @@ * @author wuq **/ error_reporting(E_ALL); +define('WIND_DEBUG', 1); include '../wind/Wind.php'; define('_COMPILE_PATH', dirname(__FILE__) . '/'); Wind::clear(); @@ -32,8 +33,7 @@ } $pack->packFromFileList($fileList, _COMPILE_PATH . 'wind_basic.php', WindPack::STRIP_PHP, true); /* import信息写入编译文件 */ -WindFile::write(_COMPILE_PATH . 'wind_imports.php', - 'parse(_COMPILE_PATH . 'config/' . $file); $file = preg_replace('/\.(\w)*$/i', '', $file); - WindFile::write(WIND_PATH . $file . '.php', - ' array( 'path' => 'WIND:core.web.WindDispatcher', 'scope' => 'application', - 'properties' => array( - 'urlHelper' => array( - 'ref' => 'urlHelper', - ), - ), ), 'forward' => array( 'path' => 'WIND:core.web.WindForward', 'scope' => 'prototype', + 'properties' => array( + 'windView' => array( + 'ref' => 'windView', + ), + ), ), 'router' => array( 'path' => 'COM:router.WindRouter', @@ -50,9 +50,9 @@ 'config' => array( 'template-dir' => 'template', 'template-ext' => 'htm', - 'is-compile' => '', + 'is-compile' => '0', 'compile-dir' => 'compile.template', - 'is-cache' => '', + 'is-cache' => '0', ), 'properties' => array( 'viewResolver' => array( @@ -66,6 +66,15 @@ 'viewResolver' => array( 'path' => 'COM:viewer.WindViewerResolver', 'scope' => 'prototype', + 'properties' => array( + 'windLayout' => array( + 'ref' => 'layout', + ), + ), + ), + 'layout' => array( + 'path' => 'COM:viewer.WindLayout', + 'scope' => 'prototype', ), 'template' => array( 'path' => 'COM:viewer.compiler.WindViewTemplate', @@ -91,7 +100,7 @@ 'config' => array( 'dir' => 'data.config', 'suffix' => 'php', - 'expires' => '', + 'expires' => '0', ), ), 'viewCache' => array( diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index 5e6770e6..5f69bb5c 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -48,6 +48,11 @@
+ + + + + diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php index 1b4bbf6d..9bbdf6d7 100644 --- a/_compile/wind_basic.php +++ b/_compile/wind_basic.php @@ -1 +1 @@ -$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } throw new WindException( '[core.WindModule.__call] ' . get_class($this) . '->' . $methodName . '()', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function setConfig($config) { if ($config) { if (is_string($config)) $config = Wind::getApp()->getComponent('configParser')->parse($config); if (!empty($this->_config)) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_TYPE = 2; const WRITE_LEVEL = 1; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = 0; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType & self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = $_logTypes = $_logLevels = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logTypes[$value[1]][] = $value[2]; $_logLevels[$value[0]][] = $value[2]; } if ($this->_writeType & 1) { foreach ($_logLevels as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($this->_writeType & 2) { foreach ($_logTypes as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $result = ''; switch ($level) { case self::LEVEL_INFO: $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message:"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= "\r\n\t" . $profile[1]; else $_msg .= "\r\n\t" . substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1); $_msg .= "\r\n\tTime:" . ($timer - $profile[3]) . "\r\n\tMem:" . ($mem - $profile[4]) . "\r\n\tType:$profile[2]"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { if ($error instanceof WindErrorMessage) { $this->setError($error); parent::__construct($error->getError(0), $code); } else parent::__construct($error, $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends Exception{ } interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { if (isset($this->prototype[$alias])) return clone $this->prototype[$alias]; if (isset($this->instances[$alias])) return $this->instances[$alias]; if (!isset($this->classDefinitions[$alias])) throw new WindException( '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); $definition = $this->classDefinitions[$alias]; if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (!$className || !class_exists($className)) throw new WindException('class is not exist.'); if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (is_string($alias) && !empty($alias)) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, Wind::getApp()->getComponent('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; public function preHandle() {} public function postHandle() {} public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->handle(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindFilter extends WindHandlerInterceptor { public function preHandle() { } public function postHandle() { } } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function handle() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { return $this; } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindActionInterceptorListener extends WindHandlerInterceptor { protected $response; protected $request; protected $interceptors = array(); public function __construct($request, $response, $interceptors) { $this->request = $request; $this->response = $response; $this->interceptors = $interceptors; } public function preHandle() { } public function postHandle() {} } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindLoggerListener extends WindHandlerInterceptor { public function __construct($request) { $this->request = $request; } public function preHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPreLogMessage(func_get_args())); } } public function postHandle() { $logger = $this->getLogger(); if ($logger instanceof WindLogger) { $logger->info($this->getPostLogMessage(func_get_args())); } } private function getLogger() { if (!isset($this->logger)) { $factory = $this->request->getAttribute(WindFrontController::WIND_FACTORY); $this->logger = $factory->getInstance(COMPONENT_LOGGER); } return $this->logger; } private function getPreLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-begin]: ' . $log['excute']; $message = 'Begin ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getPostLogMessage($args) { $log = $this->getLogMessage($args); $log['caller'] = ' #[caller]: ' . $log['caller']; $log['excute'] = ' #[excute-end]: ' . $log['excute']; $log['output'] = ' #[output]: ' . $this->buildArg($this->result); $message = 'End ' . $this->event[0] . '->' . $this->event[1]; return "{$message}
" . implode("\r\n", $log) . '
'; } private function getLogMessage($args) { $method = ''; $info = array(); $flag = false; foreach (debug_backtrace(false) as $traceKey => $trace) { $class = isset($trace['class']) ? $trace['class'] : ''; if (in_array($class, array('', 'WindLogger', __CLASS__, 'WindHandlerInterceptor'))) continue; $function = isset($trace['function']) ? $trace['function'] : ''; ($class == 'WindClassProxy' && $function == '__call') && $method = trim( $trace['args'][0]); ($function == $method) && $flag = true; if (!isset($trace['file'])) continue; $info['caller'] = addslashes($trace['file']) . '(' . $trace['line'] . '): '; break; } list($class, $method) = $this->event; $args = array_map(array($this, 'buildArg'), $args); $info['excute'] = $class . '->' . $method . '(' . implode(', ', $args) . ')'; return $info; } private function buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $forward = null; protected $errorMessage = null; abstract public function run(); protected function beforeAction($handlerAdapter) { $this->urlHelper = null; $this->errorMessage = null; $this->forward = null; } protected function afterAction($handlerAdapter) {} public function doAction($handlerAdapter) { $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } protected function forwardAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getResponse()->setData($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->getWindView()->templateName = $template; } protected function setTemplatePath($templatePath) { $this->getForward()->getWindView()->templateDir = $templatePath; } protected function setTemplateExt($templateExt) { $this->getForward()->getWindView()->templateExt = $templateExt; } protected function setLayout($layout) { $this->getForward()->getWindView()->setLayout($layout); } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->response->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->request->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->request->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->request->getCookie($name); break; default: $value = $this->request->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } protected function getForward() { return $this->_getForward(); } protected function getErrorMessage() { return $this->_getErrorMessage(); } } interface IWindController { public function doAction($handlerAdapter); } abstract class WindController extends WindSimpleController { final public function preAction($handlerAdapter) { parent::preAction($handlerAdapter); return true; } protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $processCache = array(); protected $display = false; public function dispatch($forward, $router, $display) { $this->checkProcess($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else $this->render($forward, $router); } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); $router->reParse(); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if (!$this->checkProcess($router)) { throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $router->getController() . ',' . $router->getAction(), WindException::ERROR_SYSTEM_ERROR); } Wind::getApp()->processRequest(); } protected function render($forward, $router) { if ($windViewClass = $forward->getWindView()) { $_className = Wind::import($windViewClass); $view = $this->getSystemFactory()->createInstance($windViewClass); } else $view = $this->getSystemFactory()->getInstance('windView'); $view->render($forward, $router, $this->display); $this->display = false; } protected function checkProcess($router, $check = true) { if ($check === false) { $this->processCache['action'] = $router->getAction(); $this->processCache['controller'] = $router->getController(); $this->processCache['module'] = $router->getModule(); } elseif ($router->getAction() === @$this->processCache['action'] && $router->getController() === @$this->processCache['controller'] && $router->getModule() === @$this->processCache['module']) return false; return true; } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; protected $errorDir = 'WIND:core.web.view'; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $errDir = Wind::getApp()->getConfig('errorpage'); !$errDir && $errDir = $this->errorDir; $this->setTemplatePath($errDir); $this->setTemplate('erroraction'); } } class WindForward extends WindModule { protected $windView = null; private $vars = array(); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) $this->vars += $vars; } else $this->vars[$key] = $vars; return; } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getTemplateName() { return $this->templateName; } public function getTemplatePath() { return $this->templatePath; } public function getTemplateExt() { return $this->templateExt; } public function getLayout() { return $this->layout; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function setTemplatePath($templatePath) { $this->templatePath = $templatePath; } public function setTemplateExt($templateExt) { $this->templateExt = $templateExt; } public function setLayout($layout) { $this->layout = $layout; } public function getWindView() { return $this->_getWindView(); } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $filterChain = 'WIND:filter.WindFilterChain'; public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); $this->processRequest(); restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $moduleName = $this->handlerAdapter->getModule(); if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.doDispatch] Your requested \'' . $moduleName . '\' was not found on this server.', 404); if ($forward->getTemplateExt() === null && isset($module['template-ext'])) $forward->setTemplateExt($module['template-ext']); if ($forward->getTemplatePath() === null && isset($module['template-dir'])) $forward->setTemplatePath($module['template-dir']); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { $moduleName = $this->handlerAdapter->getModule(); if (!$moduleName) { $moduleName = 'default'; $this->handlerAdapter->setModule($moduleName); $module = $this->setModules($moduleName); } else { if (!($module = $this->getModules($moduleName))) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $moduleName . '\' was not found on this server.', 404); $module = $this->setModules($moduleName, $module); } $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; $handlerPath = trim($handlerPath, '.'); if (!$handlerPath) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); strpos($handlerPath, ':') === false && $handlerPath = Wind::getAppName() . ':' . $handlerPath; $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'singleton', 'proxy' => true, 'config' => $this->getConfig('actionmap'), 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $this->resolveActionChain($handler); $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindException $e) { $this->sendErrorMessage($e); } } protected function resolveActionChain($handler) { $_alias = $handler->_getClassName() . '.' . $this->handlerAdapter->getAction(); if ($formClassPath = $handler->getConfig($_alias, 'form')) { $handler->registerEventListener('doAction', new WindFormListener($this->getRequest(), $formClassPath, $this->getComponent('errorMessage'))); } if ($_items = $handler->getConfig($_alias, 'item')) { !isset($_items[0]) && $_items = array($_items); foreach ((array) $_items as $item) { if (@$item['type'] === 'interceptor' && @$item['item']) { } elseif (@$item['type'] === 'filter' && @$item['class']) { $className = Wind::import($item['class']); $handler->registerEventListener('doAction', new $className($this->getRequest(), $this->getResponse())); } } } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error') throw new WindFinalException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { $module = $this->getModules($moduleName); if (empty($module)) $module = $this->setModules('default'); preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); } public function setModules($name, $config = array()) { if (isset($this->_config['modules']['default'])) $_default = $this->_config['modules']['default']; else { $_default = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { $component = null; switch ($componentName) { case 'windCache': if ($this->getConfig('iscache', '', true)) $component = $this->windFactory->getInstance($componentName); break; default: $component = $this->windFactory->getInstance($componentName); break; } return $component; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; protected static $errorDir = 'WIND:core.web.view'; protected static $errorPage = 'error.htm'; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000); $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (WIND_DEBUG) { $_errorPage = 'error.htm'; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $trace[$key] = $traceLine; } if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); } } $msg .= "$file\n" . implode("\n", $fileLines) . "\n" . implode("\n", $trace); } else $_errorPage = '404.htm'; if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; } else $topic = "Wind Framework - Error Caught"; $msg = "$topic\n$errmessage\n" . $msg . "\n\n" . self::errorInfo(); if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', true); if ($_errhtml) { ob_start(); $errDir = Wind::getApp()->getConfig('errorpage'); !$errDir && $errDir = self::$errorDir; if (isset($_statusMsg)) { header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); is_file(Wind::getRealPath($errDir) . '.' . $status . '.htm') && $_errorPage = $status . '.htm'; } require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, true); $msg = ob_get_clean(); } $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~/', $msg); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); if (3 == $node->nodeType) { $value = trim($node->nodeValue); (is_numeric($value) || $value) && $childs[0] = $value; } if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindHandlerInterceptor { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } class WindDate { public static function getTimeZone() { return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); } public static function setTimezone($timezone) { function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); } public static function format($format = null, $dateTime = null) { return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); } public static function datePart($interval, $dateTime = null) { return date($interval, self::getTimeStamp($dateTime)); } public static function dateDiff($interval, $startDateTime, $endDateTime) { $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); $retval = 0; switch ($interval) { case "y": $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; case "m": $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; case "w": $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; case "d": $retval = bcdiv($diff, (60 * 60 * 24));break; case "h": $retval = bcdiv($diff, (60 * 60));break; case "n": $retval = bcdiv($diff, 60);break; case "s": default:$retval = $diff;break; } return $retval; } public static function dateAdd($interval, $value, $dateTime, $format = null) { $date = getdate(self::getTimeStamp($dateTime)); switch ($interval) { case "y": $date["year"] += $value;break; case "q": $date["mon"] += ($value * 3);break; case "m": $date["mon"] += $value;break; case "w": $date["mday"] += ($value * 7);break; case "d": $date["mday"] += $value;break; case "h": $date["hours"] += $value;break; case "n": $date["minutes"] += $value;break; case "s": default:$date["seconds"] += $value;break; } return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); } public static function getRealDaysInMonthsOfYear($year) { $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if (self::isLeapYear($year)) { $months[1] = 29; } return $months; } public static function getDaysInMonth($month, $year) { if (1 > $month || 12 < $month) { return 0; } if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { return 0; } return $daysInmonths[$month - 1]; } public static function getDaysInYear($year) { return self::isLeapYear($year) ? 366 : 365; } public static function getRFCDate($date = null) { $time = $date ? is_int($date) ? $date : strtotime($date) : time(); $tz = date('Z', $time); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); } public static function getChinaDate($time = null) { list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); } public static function getChinaWeek($week = null) { $week = $week ? $week : (int) date('w', time()); $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); return $weekMap[$week]; } public static function getPeriodOfTime($hour = null) { $hour = $hour ? $hour : (int) date('G', time()); $period = ''; if (0 <= $hour && 6 > $hour) { $period = '凌晨'; } elseif (6 <= $hour && 8 > $hour) { $period = '早上'; } elseif (8 <= $hour && 11 > $hour) { $period = '上午'; } elseif (11 <= $hour && 13 > $hour) { $period = '中午'; } elseif (13 <= $hour && 15 > $hour) { $period = '响午'; } elseif (15 <= $hour && 18 > $hour) { $period = '下午'; } elseif (18 <= $hour && 20 > $hour) { $period = '傍晚'; } elseif (20 <= $hour && 22 > $hour) { $period = '晚上'; } elseif (22 <= $hour && 23 >= $hour) { $period = '深夜'; } return $period; } public static function getUTCDate($dateTime = null) { $oldTimezone = self::getTimezone(); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone('UTC'); } $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone($oldTimezone); } return $date; } public static function getMicroTime($get_as_float = null,$mircrotime = null) { return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); } public static function isLeapYear($year) { if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { return true; } return false; } public static function getTimeStamp($dateTime = null){ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); } public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); $timestamp = $timestamp ? $timestamp : time(); $compareTime = strtotime(self::format('Y-m-d',$timestamp)); $currentTime = strtotime(self::format('Y-m-d',$time)); $decrease = $timestamp - $time; $result = self::format($format,$time); if (0 >= $decrease) { return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } if ($currentTime == $compareTime) { if (1 == $type) { if (60 >= $decrease) { return array($decrease . $timelang['second'], $result); } return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); } return array(self::format('H:i',$time), $result); } elseif ($currentTime == $compareTime - 86400) { return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); } elseif ($currentTime == $compareTime - 172800) { return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); } return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } } class WindGeneralDate { const FILL = 0; const DIGIT = 1; const TEXT = 2; const DEFAULT_FORMAT = 'Y-m-d H:i:s'; private $time = 0; public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { $time = time(); !$month && ((!$year) ? $month = date('m', $time) : $month = 1); !$day && ((!$year) ? $day = date('d', $time) : $day = 1); !$hours && !$year && $hours = date('H', $time); !$minutes && !$year && $minutes = date('i', $time); !$second && !$year && $second = date('s', $time); !$year && $year = date('Y', $time); $this->time = mktime($hours, $minutes, $second, $month, $day, $year); } public function getDaysInMonth() { return date('t', $this->time); } public function getDaysInYear() { return $this->isLeapYear() ? 366 : 365; } public function getDayOfYear() { return date('z', $this->time) + 1; } public function getDayOfMonth() { return date('j', $this->time); } public function getDayOfWeek() { return date('w', $this->time) + 1; } public function getWeekOfYear() { return date('W', $this->time); } public function getYear($format = true) { return date($format ? 'Y' : 'y', $this->time); } public function getMonth($display = self::FILL) { if(self::FILL == $display){ return date('m', $this->time); }elseif(self::DIGIT == $display){ return date('n', $this->time); }elseif(self::TEXT == $display){ return date('M', $this->time); } return date('n', $this->time); } public function getDay($display = self::FILL) { if(self::FILL == $display){ return date('d', $this->time); }elseif(self::DIGIT == $display){ return date('j', $this->time); }elseif(self::TEXT == $display){ return date('jS', $this->time); } return date('j', $this->time); } public function getWeek($display = self::FILL) { if(self::FILL == $display || self::DIGIT == $display){ return date('w', $this->time); }elseif(self::TEXT == $display){ return date('D', $this->time); } return date('N', $this->time); } public function get12Hours($display = self::FILL){ if(self::FILL == $display){ return date('h', $this->time); }elseif(self::DIGIT == $display){ return date('g', $this->time);; } return date('h', $this->time); } public function get24Hours($display = self::FILL){ if(self::FILL == $display){ return date('H', $this->time); }elseif(self::DIGIT == $display){ return date('G', $this->time);; } return date('H', $this->time); } public function getMinutes() { return date('i', $this->time); } public function getSeconds() { return date('s', $this->time); } public function getLocalTimeZone() { return date('T', $this->time); } public function setTime($time) { if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { $this->time = $time; } } public function getNow() { $date = getdate($this->time); return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); } public function __toString() { return $this->toString(); } public function toString($format = null) { return date($format ? $format : self::DEFAULT_FORMAT, $this->time); } public function isLeapYear() { return date('L', $this->time); } } class WindDecoder { const JSON_SLICE = 1; const JSON_IN_STR = 2; const JSON_IN_ARR = 4; const JSON_IN_OBJ = 8; const JSON_IN_CMT = 16; public static function decode($str, $useArray = true) { $str = strtolower(self::reduceString($str)); if ('true' == $str) { return true; } elseif ('false' == $str) { return false; } elseif ('null' == $str) { return null; } elseif (is_numeric($str)) { return (float)$str == (integer)$str ? (integer) $str : (float) $str; }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ return self::jsonToString($str); }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); } return false; } protected static function jsonToString($string) { $delim = substr($string, 0, 1); $chrs = substr($string, 1, -1); $decodeStr = ''; for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { $compare = substr($chrs, $c, 2); $ordCode = ord($chrs{$c}); if('\b' == $compare){ $decodeStr .= chr(0x08); ++$c; }elseif('\t' == $compare){ $decodeStr .= chr(0x09); ++$c; }elseif('\n' == $compare){ $decodeStr .= chr(0x0A); ++$c; }elseif('\f' == $compare){ $decodeStr .= chr(0x0C); ++$c; }elseif('\r' == $compare){ $decodeStr .= chr(0x0D); ++$c; }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { $decodeStr .= $chrs{++$c}; } }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $decodeStr .= self::utf16beToUTF8($utf16); $c += 5; }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ $decodeStr .= $chrs{$c}; }elseif(0xC0 == ($ordCode & 0xE0)){ $decodeStr .= substr($chrs, $c, 2); ++$c; }elseif(0xE0 == ($ordCode & 0xF0)){ $decodeStr .= substr($chrs, $c, 3); $c += 2; }elseif(0xF0 == ($ordCode & 0xF8)){ $decodeStr .= substr($chrs, $c, 4); $c += 3; }elseif(0xF8 == ($ordCode & 0xFC)){ $decodeStr .= substr($chrs, $c, 5); $c += 4; }elseif(0xFC == ($ordCode & 0xFE)){ $decodeStr .= substr($chrs, $c, 6); $c += 5; } } return $decodeStr; } protected static function jsonToArray($str) { return self::complexConvert($str,true); } protected static function jsonToObject($str) { return self::complexConvert($str,false); } protected static function complexConvert($str,$useArray = true){ if ('[' == $str{0}) { $stk = array(self::JSON_IN_ARR); $arr = array(); } else { $obj = $useArray ? array() : new stdClass(); $stk = array(self::JSON_IN_OBJ); } array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = self::reduceString($chrs); if ('' == $chrs) { return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; } for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); if (reset($stk) == self::JSON_IN_ARR) { array_push($arr, self::decode($slice, $useArray)); } elseif (reset($stk) == self::JSON_IN_OBJ) { if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $key = self::decode($parts[1], $useArray); $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { array_pop($stk); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { array_pop($stk); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { array_pop($stk); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { array_pop($stk); for ($i = $top['where']; $i <= ++$c; ++$i){ $chrs = substr_replace($chrs, ' ', $i, 1); } } } if (self::JSON_IN_ARR == reset($stk)) { return $arr; } elseif (self::JSON_IN_OBJ == reset($stk)) { return $obj; } return false; } protected static function unicodeToUTF8(&$str) { $utf8 = ''; foreach ($str as $unicode) { if ($unicode < 128) { $utf8 .= chr($unicode); } elseif ($unicode < 2048) { $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } else { $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } } return $utf8; } protected static function reduceString($str) { return trim(preg_replace(array( '#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str)); } protected static function utf16beToUTF8(&$str) { return self::unicodeToUTF8(unpack('n*', $str)); } } class WindEncoder { public static $charset = 'utf-8'; public static function encode($value) { switch (gettype($value)) { case 'boolean': return $value ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $value; case 'double': case 'float': return (float) $value; case 'string': return self::stringToJson($value); case 'array': return self::arrayToJson($value); case 'object': return self::objectToJson($value); default: return ''; } return ''; } protected static function stringToJson($string) { if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { $string = iconv($enc, 'UTF-8', $string); } $ascii = ''; $strlen = strlen($string); for ($c = 0; $c < $strlen; ++$c) { $ordVar = ord($string{$c}); if (0x08 == $ordVar) { $ascii .= '\b'; } elseif (0x09 == $ordVar) { $ascii .= '\t'; } elseif (0x0A == $ordVar) { $ascii .= '\n'; } elseif (0x0C == $ordVar) { $ascii .= '\f'; } elseif (0x0D == $ordVar) { $ascii .= '\r'; } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { $ascii .= '\\' . $string{$c}; } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { $ascii .= $string{$c}; } elseif (0xC0 == ($ordVar & 0xE0)) { $char = pack('C*', $ordVar, ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xE0 == ($ordVar & 0xF0)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF0 == ($ordVar & 0xF8)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF8 == ($ordVar & 0xFC)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xFC == ($ordVar & 0xFE)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } } return '"' . $ascii . '"'; } protected static function arrayToJson(array $array) { if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; } return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; } protected static function objectToJson($object) { if ($object instanceof Traversable) { $vars = array(); foreach ($object as $k => $v) { $vars[$k] = $v; } } else { $vars = get_object_vars($object); } return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; } protected static function nameValue($name, $value) { return self::encode(strval($name)) . ':' . self::encode($value); } protected static function utf8ToUTF16BE(&$string, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if (function_exists('mb_convert_encoding')) { return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); } $uni = self::utf8ToUnicode($string); foreach ($uni as $cp) { $out .= pack('n', $cp); } return $out; } protected static function utf8ToUnicode(&$string) { $unicode = $values = array(); $lookingFor = 1; for ($i = 0, $length = strlen($string); $i < $length; $i++) { $thisValue = ord($string[$i]); if ($thisValue < 128) { $unicode[] = $thisValue; } else { if (count($values) == 0) { $lookingFor = ($thisValue < 224) ? 2 : 3; } $values[] = $thisValue; if (count($values) == $lookingFor) { $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; $values = array(); $lookingFor = 1; } } } return $unicode; } } class WindArray { public static function mergeArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); unset($array2[$key]); } else { $tmp[$key] = $array; } } return array_merge($tmp, (array) $array2); } public static function filterArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); } } return $tmp; } public static function rebuildArrayWithKey($key, array $array) { if (!$key || !$array) { return array(); } $tmp = array(); foreach ($array as $_array) { if (isset($_array[$key])) { $tmp[$_array[$key]] = $_array; } } return $tmp; } } Wind::import("COM:utility.WindSecurity"); Wind::import("COM:utility.WindString"); class WindFile { const READ = 'rb'; const READWRITE = 'rb+'; const WRITE = 'wb'; const WRITEREAD = 'wb+'; const APPEND_WRITE = 'ab'; const APPEND_WRITEREAD = 'ab+'; public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { $temp = "\r\n "; if (!$isBuildReturn && is_array($data)) { foreach ($data as $key => $value) { if (!preg_match('/^\w+$/', $key)) continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n"; } else { ($isBuildReturn) && $temp .= " return "; $temp .= WindString::varToString($data) . ";\r\n"; } return self::write($fileName, $temp, $method, $ifLock); } public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); fclose($handle); $ifChmod && chmod($fileName, 0777); return $writeCheck; } public static function read($fileName, $method = self::READ) { $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { flock($handle, LOCK_SH); $data = fread($handle, filesize($fileName)); fclose($handle); } return $data; } public static function clearDir($dir, $ifexpiled = false) { if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { self::delFile($fullPath); } } closedir($handle); false === $ifexpiled && rmdir($dir); return true; } public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); if (!$handler = opendir($path)) { return false; } while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { if (substr($filename, 0, 1) != '.') { self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); } } else { self::delFile($path . DIRECTORY_SEPARATOR . $filename); } } } closedir($handler); true == $delDir && $level > 0 && rmdir($path); return true; } public static function getMimeType($fileName) { $suffix = self::getFileSuffix($fileName); $mimes = require WIND_PATH . '/component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { throw new WindException('Sorry, can not find the corresponding mime type of the file'); } return false; } public static function getDirectoryIterator($dir) { return new DirectoryIterator($dir); } public static function getFileInfo($fileName) { if (false === is_file($fileName)) { return array(); } $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); $fileInfo['ctime'] = filectime($fileName); $fileInfo['atime'] = fileatime($fileName); $fileInfo['mtime'] = filemtime($fileName); $fileInfo['readable'] = is_readable($fileName); $fileInfo['writable'] = is_writable($fileName); $fileInfo['executable'] = is_executable($fileName); $fileInfo['right'] = fileperms($fileName); $fileInfo['group'] = filegroup($fileName); $fileInfo['owner'] = fileowner($fileName); $fileInfo['mime'] = self::getMimeType($fileName); return $fileInfo; } public static function getDirectoryInfo($dir) { if (false !== is_dir($dir)) { return array(); } return stat($dir); } public static function delFile($filename) { return @unlink($filename); } public static function getFileSuffix($filename) { $filename = explode($filename, '.'); return $filename[count($filename) - 1]; } public static function appendSlashesToDir($path) { return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; } } class WindHtmlHelper { public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function encodeArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; } return $_tmp; } } class WindImage { public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); if (!$imagecreate) return false; $imgwidth = $minitemp['width']; $imgheight = $minitemp['height']; $srcX = $srcY = $dstX = $dstY =0; if (!$isProportion) { $dsDivision = $imgheight / $imgwidth; $fixDivision = $dstH / $dstW; if ($dsDivision > $fixDivision) { $tmp = $imgwidth * $fixDivision; $srcY = round(($imgheight - $tmp) / 2); $imgheight = $tmp; } else { $tmp = $imgheight / $fixDivision; $srcX = round(($imgwidth - $tmp) / 2); $imgwidth = $tmp; } } $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { $black = imagecolorallocate($thumb, 0, 0, 0); imagecolortransparent($thumb, $black); } $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); self::makeImg($minitemp['type'], $thumb, $dstFile); imagedestroy($thumb); return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); } public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { $sourcedb = $waterdb = array(); if (false === ($sourcedb = self::getImgInfo($source))) return false; if (!$waterImg && !$waterText) return false; imagealphablending($sourcedb['source'], true); if ($waterImg) { $waterdb = self::getImgInfo($waterImg); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); if ($waterdb['type'] == 'png') { $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); $sourcedb['source'] = $tmp; } else { imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); } } elseif ($waterText) { list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); empty($waterFont) && $waterFont = 12; $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); $waterdb['width'] = $temp[2] - $temp[6]; $waterdb['height'] = $temp[3] - $temp[7]; unset($temp); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); if (strlen($color) != 7) return false; $R = hexdec(substr($color, 1, 2)); $G = hexdec(substr($color, 3, 2)); $B = hexdec(substr($color, 5)); self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); } $dstsrc && $source = $dstsrc; self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); isset($waterdb['source']) && imagedestroy($waterdb['source']); imagedestroy($sourcedb['source']); return true; } private static function checkAttribute($attribute) { $attribute = is_string($attribute) ? array($attribute) : $attribute; if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; return $attribute; } private static function changeCharset($charset) { $charset = strtolower($charset); return !in_array($charset, array('utf8', 'utf-8')); } private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { if (is_array($waterPos)) return $waterPos; $wX = $wY = 0; switch (intval($waterPos)) { case 0 : $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); break; case 1 : $wX = 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 2: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 3: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 4: $wX = 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 5: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 6: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; default: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; break; } return array($wX, $wY); } private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { if (false === ($imgdata = self::getImgInfo($srcFile))) return false; if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; $imgdata['dstW'] = $dstW; $imgdata['dstH'] = $dstH; if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); } elseif ($dstW > 0 && $dstH > 0) { if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); } if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); } } else { $imgdata = false; } return $imgdata; } public static function getImgInfo($srcFile) { if (false === ($imgdata = self::getImgSize($srcFile))) return false; $imgdata['type'] = self::getTypes($imgdata['type']); if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; $imgdata['source'] = $imagecreatefromtype($srcFile); !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); return $imgdata; } private static function getImgSize($srcFile, $srcExt = null) { empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); $srcdata = array(); $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); in_array($srcExt, $exts) && $srcdata['type'] = 2; if (false === ($info = getimagesize($srcFile))) return false; list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; return $srcdata; } private static function getImgcreate($imagetype) { if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { return array('imagecreatetruecolor', 'imagecopyresampled'); } if (function_exists('imagecreate') && function_exists('imagecopyresized')) { return array('imagecreate', 'imagecopyresized'); } return array('', ''); } private static function makeImg($type, $image, $filename, $quality = '75') { $makeimage = 'image' . $type; if (!function_exists($makeimage)) return false; if ($type == 'jpeg') { $makeimage($image, $filename, $quality); } else { $makeimage($image, $filename); } return true; } private static function getTypes($id) { $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; } } Wind::import('WIND:component.utility.WindFile'); class WindPack { const STRIP_SELF = 'stripWhiteSpaceBySelf'; const STRIP_PHP = 'stripWhiteSpaceByPhp'; const STRIP_TOKEN = 'stripWhiteSpaceByToken'; private $packList = array(); private $contentInjectionPosition; private $contentInjectionCallBack = ''; public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { if (empty($dst) || empty($dir)) { return false; } $suffix = is_array($suffix) ? $suffix : array( $suffix); if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { return false; } $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->stripImport($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { if (empty($dst) || empty($fileList)) { return false; } $content = array(); $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function stripWhiteSpaceByPhp($filename) { return php_strip_whitespace($filename); } public function stripWhiteSpaceBySelf($filename, $compress = true) { $content = $this->getContentFromFile($filename); $content = $this->stripComment($content, ''); return $this->stripSpace($content, ' '); } public function stripWhiteSpaceByToken($filename) { $content = $this->getContentFromFile($filename); $compressContent = ''; $lastToken = 0; foreach (token_get_all($content) as $key => $token) { if (is_array($token)) { if (in_array($token[0], array( T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) { continue; } $compressContent .= ' ' . $token[1]; } else { $compressContent .= $token; } $lastToken = $token[0]; } return $compressContent; } public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { static $content = array(); if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { return false; } $dir = is_array($dir) ? $dir : array( $dir); foreach ($dir as $_dir) { $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; if (is_dir($_dir)) { $handle = dir($_dir); while (false != ($tmp = $handle->read())) { $name = WindFile::appendSlashesToDir($_dir) . $tmp; if (is_dir($name) && !in_array($tmp, $ndir)) { $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); } if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { $content[] = $this->$packMethod($name); $this->setPackList($file, $name); } } $handle->close(); } } return $content; } public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { return array(); } $fileList = is_array($fileList) ? $fileList : array( $fileList); foreach ($fileList as $key => $value) { if (is_array($value) && isset($value[1])) { $parents = class_parents($value[1]); $_fileList = $this->buildFileList($parents, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); $implements = class_implements($value[1]); $_fileList = $this->buildFileList($implements, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); if (key_exists($key, $this->getPackList())) continue; $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; if (is_file($file)) { $content[] = $this->$packMethod($file); $this->setPackList($key, $value); } } } } public function stripComment($content, $replace = '') { return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); } public function stripNR($content, $replace = array('\n','\r\n','\r')) { return preg_replace('/[\n\r]+/', $replace, $content); } public function stripSpace($content, $replace = ' ') { return preg_replace('/[ ]+/', $replace, $content); } public function stripPhpIdentify($content, $replace = '') { return preg_replace('/(?:<\?(?:php)*)|(\)/i', $replace, $content); } public function stripStrByRule($content, $rule, $replace = '') { return preg_replace("/$rule/", $replace, $content); } public function stripImport($content, $replace = '') { $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); if ($matchs[1]) { foreach ($matchs[1] as $key => $value) { $name = substr($value, strrpos($value, '.') + 1); if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { $strip = str_replace(array( '(', ')'), array( '\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; $content = $this->stripStrByRule($content, $strip, $replace); } } } return $content; } public function getPackList() { return $this->packList; } public function getContentFromFile($filename) { if (is_file($filename)) { $content = ''; $fp = fopen($filename, "r"); while (!feof($fp)) { $line = fgets($fp); if (in_array(strlen($line), array( 2, 3)) && in_array(ord($line), array( 9, 10, 13))) continue; $content .= $line; } fclose($fp); return $content; } return false; } public function getContentBySuffix($content, $suffix, $replace = ' ') { switch ($suffix) { case 'php': $content = '' . $replace . $content . ''; break; default: $content = '' . $replace . $content . ''; break; } return $content; } private function buildFileList($list, $fileList) { $_temp = array(); foreach ($list as $fileName) { foreach ($fileList as $key => $value) { if ($value[1] == $fileName) { $_temp[$key] = $value; break; } } } return $_temp; } public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { if (!in_array($position, array( 'before', 'after'))) $position = 'before'; $this->contentInjectionPosition = $position; $this->contentInjectionCallBack = $contentInjectionCallBack; } public function callBack($content, $replace = '') { if ($this->contentInjectionCallBack !== '') { $_content = call_user_func_array($this->contentInjectionCallBack, array( $this->getPackList())); if ($this->contentInjectionPosition == 'before') { $content = $replace . $_content . $content; } elseif ($this->contentInjectionPosition == 'after') { $content .= $replace . $_content . $replace; } } return $content; } private function isValidatePackMethod($packMethod) { return method_exists($this, $packMethod) && in_array($packMethod, array( WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN)); } private function setPackList($key, $value) { if (isset($this->packList[$key])) { if (is_array($this->packList[$key])) { array_push($this->packList[$key], $value); } else { $tmp_name = $this->packList[$key]; $this->packList[$key] = array( $tmp_name, $value); } } else { $this->packList[$key] = $value; } } } class WindSecurity { public static function escapeHTML($str) { return htmlspecialchars($str, ENT_QUOTES); } public static function stripTags($str, $allowTags = "") { return strip_tags($str, $allowTags); } public static function escapePath($fileName, $ifCheck = true) { if (!self::_escapePath($fileName, $ifCheck)) { throw new WindException('file name is illegal'); } return $fileName; } public static function escapeDir($dir) { $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } public static function escapeChar($value) { if (is_array($value)) { foreach ($value as $key => $sub) { $value[$key] = self::escapeChar($sub); } } elseif (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = self::escapeString($value); } return $value; } public static function escapeString($string) { $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } public static function quotemeta($string) { return quotemeta($string); } public function checkInputValue($value, $key = '') { if (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = "'" . addslashes($value) . "'"; } elseif (is_float($value)) { $value = (float) $value; } elseif (is_object($value) || is_array($value)) { $value = "'" . addslashes(serialize($value)). "'"; } return $value; } public static function addSlashesForInput($str) { if (!get_magic_quotes_gpc()) { $str = addslashes($str); } return $str; } public static function addSlashesForOutput($str) { if (!get_magic_quotes_runtime()) { $str = addslashes($str); } return $str; } public static function addSlashes($value, $gpc = false, $df = false) { if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable) )) { return $value; } if(is_string($value)){ if (false === $gpc && true === $df) { return self::addSlashesForOutput($value); } if (false === $df && true === $gpc) { return self::addSlashesForInput($value); } return addslashes($value); } foreach($value as $key=>$_value){ $value[$key] = self::addSlashes($_value,$gpc,$df); } return $value; } public static function stripSlashes($value) { if (!$value) return $value; if (is_string($value)) return stripslashes($value); if (!is_array($value) && !($value instanceof Traversable)) return $value; foreach ($value as $key => $_value) { $value[$key] = self::stripSlashes($_value); } return $value; } public static function sqlEscape($var, $strip = true, $isArray = false) { if (is_array($var)) { if (!$isArray) return " '' "; foreach ($var as $key => $value) { $var[$key] = trim(self::sqlEscape($value, $strip)); } return $var; } elseif (is_numeric($var)) { return " '" . $var . "' "; } else { return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; } } public static function sqlImplode($array, $strip = true) { return implode(',', self::sqlEscape($array, $strip, true)); } public static function sqlSingle($array, $strip = true) { if (!is_array($array)) return ''; $array = self::sqlEscape($array, $strip, true); $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; } return $str; } public static function sqlMulti($array, $strip = true) { if (!is_array($array)) { return ''; } $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; } } return $str; } public static function sqlMetadata($data ,$tlists=array()) { if (empty($tlists) || !in_array($data , $tlists)) { $data = str_replace(array('`', ' '), '',$data); } return ' `'.$data.'` '; } private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; if (strtr($tmpname, $tmparray) != $tmpname) { return false; } return true; } } class WindString { const UTF8 = 'utf8'; const GBK = 'gbk'; public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( $string, $start, $length, $dot); } public static function strlen($string, $charset = self::UTF8) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; $count++; } return $count; } public static function varToString($input, $indent = '') { switch (gettype($input)) { case 'string': return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; case 'array': $output = "array(\r\n"; foreach ($input as $key => $value) { $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( $value, $indent . "\t"); $output .= ",\r\n"; } $output .= $indent . ')'; return $output; case 'boolean': return $input ? 'true' : 'false'; case 'NULL': return 'NULL'; case 'integer': case 'double': case 'float': return "'" . (string) $input . "'"; } return 'NULL'; } public static function jsonEncode($value) { if (!function_exists('json_encode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); } public static function jsonDecode($value) { if (!function_exists('json_decode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); } public static function jsonSimpleEncode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': return '"' . addslashes( str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; case 'array': if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array(); foreach ($var as $name => $value) { $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( $value); } return '{' . join(',', $properties) . '}'; } $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); return '[' . join(',', $elements) . ']'; } return false; } public static function utf8_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j += 2; } else { $word++; } $j++; } $start = $word + 3 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 3); $j += 2; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function utf8_strlen($str) { $i = $count = 0; $len = strlen($str); while ($i < $len) { $chr = ord($str[$i]); $count++; $i++; if ($i >= $len) break; if ($chr & 0x80) { $chr <<= 1; while ($chr & 0x80) { $i++; $chr <<= 1; } } } return $count; } public static function gbk_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j++; } else { $word++; } $j++; } $start = $word + 2 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 2); $j++; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function gbk_strlen($string) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? $i += 2 : $i++; $count++; } return $count; } } class WindUtility { public static function mergeArray($array1, $array2) { foreach ($array2 as $key => $value) { if (!isset($array1[$key]) || !is_array($array1[$key])) { $array1[$key] = $value; continue; } $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); } return $array1; } public static function lcfirst($str) { if (function_exists('lcfirst')) return lcfirst($str); $str[0] = strtolower($str[0]); return $str; } public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { $randnum = rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { $randstr .= chr($randnum + 55); } else { $randstr .= chr($randnum + 61); } } return $randstr; } public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } class WindValidator { public static function isTelPhone($phone) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); } public static function isTelNumber($number) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); } public static function isQQ($qq) { return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); } public static function isZipcode($zipcode) { return 0 < preg_match('/^\d{4,8}$/', $zipcode); } public static function hasEmail($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); } public static function isEmail($string) { return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); } public static function hasIdCard($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); } public static function isIdCard($string) { return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); } public static function hasUrl($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); } public static function isUrl($string) { return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); } public static function hasChinese($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); } public static function isChinese($string) { return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); } public static function hasHtml($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); } public static function isHtml($string) { return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); } public static function hasIpv4($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); } public static function isIpv4($string) { return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); } public static function hasIpv6($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| ::([a-f0-9]{1,4}:){5}| ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )([a-f0-9]{1,4}:[a-f0-9]{1,4}| (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string, $matches, $ifAll); } public static function isIpv6($string) { return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| ::(?:[a-f0-9]{1,4}:){5}| (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string); } public static function hasScript($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); } public static function isScript($string) { return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); } public static function isEmpty($value) { return empty($value); } public static function isNonNegative($number) { return 0 <= (int) $number; } public static function isPositive($number) { return 0 < (int) $number; } public static function isNegative($number) { return 0 > (int) $number; } public static function isArray($array) { return is_array($array); } public static function isRequired($value) { return !self::isEmpty($value); } public static function inArray($needle, array $array, $strict = true) { return in_array($needle, $array, $strict); } public static function isLegalLength($string, $length, $charset = 'utf8') { Wind::import('WIND:component.utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { if (true === $ifAll) { return preg_match_all($regExp, $string, $matches); } return preg_match($regExp, $string, $matches); } }?> \ No newline at end of file +$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function _getConfig() { $args = func_get_args(); $_tmp = ''; foreach ($args as $value) { if (!isset($this->_config[$value])) continue; $_tmp = $this->_config[$value]; } } public function setConfig($config) { if ($config) { if (is_string($config)) $config = Wind::getApp()->getComponent('configParser')->parse($config); if (!empty($this->_config)) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_TYPE = 2; const WRITE_LEVEL = 1; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = 0; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType & self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = $_logTypes = $_logLevels = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logTypes[$value[1]][] = $value[2]; $_logLevels[$value[0]][] = $value[2]; } if ($this->_writeType & 1) { foreach ($_logLevels as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($this->_writeType & 2) { foreach ($_logTypes as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $result = ''; switch ($level) { case self::LEVEL_INFO: $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message:"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= "\r\n\t" . $profile[1]; else $_msg .= "\r\n\t" . substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1); $_msg .= "\r\n\tTime:" . ($timer - $profile[3]) . "\r\n\tMem:" . ($mem - $profile[4]) . "\r\n\tType:$profile[2]"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { if ($error instanceof WindErrorMessage) { $this->setError($error); parent::__construct($error->getError(0), $code); } else parent::__construct($error, $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends Exception{ } interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { $instance = null; $definition = isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : array(); if (isset($this->prototype[$alias])) { $instance = clone $this->prototype[$alias]; } elseif (isset($this->instances[$alias])) { $instance = $this->instances[$alias]; } else { if (!$definition) throw new WindException( '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); } if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (!$className || !class_exists($className)) throw new WindException('class is not exist.'); if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (is_string($alias) && !empty($alias)) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, Wind::getApp()->getComponent('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } abstract class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; abstract public function preHandle(); abstract public function postHandle(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->handle(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } abstract class WindActionFilter extends WindHandlerInterceptor { protected $_vars = array(); protected $forward = null; protected $errorMessage = null; public function __construct($forward, $errorMessage) { $this->forward = $forward; $this->errorMessage = $errorMessage; $args = func_get_args(); unset($args[0], $args[1]); foreach ($args as $key => $value) property_exists(get_class($this), $key) && $this->$key = $value; $this->_vars = $forward->getVars(); } protected function setOutput($data, $key = '') { $this->forward->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->forward->setVars($data, $key, true); } protected function getInput($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->getRequest()->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->getRequest()->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->getRequest()->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->getRequest()->getCookie($name); break; default: $value = $this->getRequest()->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } } Wind::import('COM:fitler.WindHandlerInterceptor'); abstract class WindFilter extends WindHandlerInterceptor { } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function handle() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { return $this; } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $_vars = array(); protected $forward = null; protected $errorMessage = null; abstract public function run(); public function doAction($handlerAdapter) { if ($this->forward !== null) $this->_vars = $this->forward->getVars(); $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } public function resolveActionFilter($action) { return array(); } protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} protected function forwardAction($action = 'run', $args = array(), $isRedirect = false) { $this->getForward()->forwardAction($action, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getForward()->setVars($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->getWindView()->templateName = $template; } protected function setTemplatePath($templatePath) { $this->getForward()->getWindView()->templateDir = $templatePath; } protected function setTemplateExt($templateExt) { $this->getForward()->getWindView()->templateExt = $templateExt; } protected function setTheme($theme) { $this->getForward()->getWindView()->thems = $theme; } protected function setLayout($layout) { $this->getForward()->getWindView()->layout = $layout; } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->getRequest()->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->getRequest()->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->getRequest()->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->getRequest()->getCookie($name); break; default: $value = $this->getRequest()->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } public function getForward() { return $this->_getForward(); } public function getErrorMessage() { return $this->_getErrorMessage(); } public function setForward($forward) { $this->forward = $forward; } public function setErrorMessage($errorMessage) { $this->errorMessage = $errorMessage; } } interface IWindController { public function doAction($handlerAdapter); public function resolveActionFilter($action); } abstract class WindController extends WindSimpleController { protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $token; protected $display = false; public function dispatch($forward, $router, $display) { $this->checkToken($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else { $view = $forward->getWindView(); if ($view->templateName) { $vars = $forward->getVars(); Wind::getApp()->getResponse()->setData($vars, $view->templateName); Wind::getApp()->getResponse()->setData($vars['G'], true); $view->render($forward, $router, $this->display); } $this->display = false; } } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); if ($this->checkToken($router)) throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if ($this->checkToken($router)) throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); Wind::getApp()->processRequest(); } protected function checkToken($router, $check = true) { $token = $router->getModule() . '/' . $router->getController() . '/' . $router->getAction(); if ($check === false) { $this->token = $token; } else return !strcasecmp($token, $this->token); } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; protected $errorDir = 'WIND:core.web.view'; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $errDir = Wind::getApp()->getConfig('errorpage'); !$errDir && $errDir = $this->errorDir; $this->setTemplatePath($errDir); $this->setTemplate('erroraction'); } } class WindForward extends WindModule { protected $windView = null; private $vars = array('G' => array()); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '', $isG = false) { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) if ($isG) $this->vars['G'] = $vars; else $this->vars += $vars; } else { if ($isG) $this->vars['G'][$key] = $vars; else $this->vars[$key] = $vars; } } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getWindView() { if ($this->windView === null) $this->_getWindView(); $module = Wind::getApp()->getModules(); isset($module['template-dir']) && $this->windView->templateDir = $module['template-dir']; isset($module['compile-dir']) && $this->windView->compileDir = $module['compile-dir']; return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $defaultModule = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->setModules('default', $this->defaultModule); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); $this->processRequest(); restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { if (!$this->handlerAdapter->getModule()) $this->handlerAdapter->setModule('default'); if (!($module = $this->getModules())) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', 404); $module = WindUtility::mergeArray($this->defaultModule, $module); $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'prototype', 'proxy' => true, 'config' => $this->getConfig('actionmap'), 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $this->resolveActionChain($handler); $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindException $e) { $this->sendErrorMessage($e); } } protected function resolveActionChain($__handler) { @extract(@$this->getRequest()->getRequest(), EXTR_REFS); $__filters = $__handler->resolveActionFilter($this->handlerAdapter->getAction()); foreach ((array) $__filters as $__filter) { if (isset($__filter['expression']) && !empty($__filter['expression'])) { if (!@eval('return ' . $__filter['expression'] . ';')) continue; } $__args = array($__handler->getForward(), $__handler->getErrorMessage()); if (isset($__filter['args'])) $__args = $__args + (array) $__filter['args']; $__handler->registerEventListener('doAction', WindFactory::createInstance(Wind::import(@$__filter['class']), $__args)); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error') throw new WindFinalException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { $module = $this->getModules($moduleName); if (empty($module)) $module = $this->setModules('default'); preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); } public function setModules($name, $config = array()) { if (!isset($this->_config['modules'][$name])) { $this->_config['modules'][$name] = (array) $config; } } public function getModules($name = '') { if ($name === '') return $this->getConfig('modules', $this->handlerAdapter->getModule()); return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { $component = null; switch ($componentName) { case 'windCache': if ($this->getConfig('iscache', '', true)) $component = $this->windFactory->getInstance($componentName); break; default: $component = $this->windFactory->getInstance($componentName); break; } return $component; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; protected static $errorDir = 'WIND:core.web.view'; protected static $errorPage = 'error.htm'; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000); $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (WIND_DEBUG) { $_errorPage = 'error.htm'; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $trace[$key] = $traceLine; } $fileLines = array(); if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); } } $msg .= "$file\n" . implode("\n", $fileLines) . "\n" . implode("\n", $trace); } else $_errorPage = '404.htm'; if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; } else $topic = "Wind Framework - Error Caught"; $msg = "$topic\n$errmessage\n" . $msg . "\n\n" . self::errorInfo(); if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', true); if ($_errhtml) { ob_start(); $errDir = Wind::getApp()->getConfig('errorpage'); !$errDir && $errDir = self::$errorDir; if (isset($_statusMsg)) { header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); is_file(Wind::getRealPath($errDir) . '.' . $status . '.htm') && $_errorPage = $status . '.htm'; } require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, true); $msg = ob_get_clean(); } $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~/', $msg); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); if (3 == $node->nodeType) { $value = trim($node->nodeValue); (is_numeric($value) || $value) && $childs[0] = $value; } if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindModule { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } class WindDate { public static function getTimeZone() { return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); } public static function setTimezone($timezone) { function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); } public static function format($format = null, $dateTime = null) { return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); } public static function datePart($interval, $dateTime = null) { return date($interval, self::getTimeStamp($dateTime)); } public static function dateDiff($interval, $startDateTime, $endDateTime) { $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); $retval = 0; switch ($interval) { case "y": $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; case "m": $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; case "w": $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; case "d": $retval = bcdiv($diff, (60 * 60 * 24));break; case "h": $retval = bcdiv($diff, (60 * 60));break; case "n": $retval = bcdiv($diff, 60);break; case "s": default:$retval = $diff;break; } return $retval; } public static function dateAdd($interval, $value, $dateTime, $format = null) { $date = getdate(self::getTimeStamp($dateTime)); switch ($interval) { case "y": $date["year"] += $value;break; case "q": $date["mon"] += ($value * 3);break; case "m": $date["mon"] += $value;break; case "w": $date["mday"] += ($value * 7);break; case "d": $date["mday"] += $value;break; case "h": $date["hours"] += $value;break; case "n": $date["minutes"] += $value;break; case "s": default:$date["seconds"] += $value;break; } return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); } public static function getRealDaysInMonthsOfYear($year) { $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if (self::isLeapYear($year)) { $months[1] = 29; } return $months; } public static function getDaysInMonth($month, $year) { if (1 > $month || 12 < $month) { return 0; } if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { return 0; } return $daysInmonths[$month - 1]; } public static function getDaysInYear($year) { return self::isLeapYear($year) ? 366 : 365; } public static function getRFCDate($date = null) { $time = $date ? is_int($date) ? $date : strtotime($date) : time(); $tz = date('Z', $time); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); } public static function getChinaDate($time = null) { list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); } public static function getChinaWeek($week = null) { $week = $week ? $week : (int) date('w', time()); $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); return $weekMap[$week]; } public static function getPeriodOfTime($hour = null) { $hour = $hour ? $hour : (int) date('G', time()); $period = ''; if (0 <= $hour && 6 > $hour) { $period = '凌晨'; } elseif (6 <= $hour && 8 > $hour) { $period = '早上'; } elseif (8 <= $hour && 11 > $hour) { $period = '上午'; } elseif (11 <= $hour && 13 > $hour) { $period = '中午'; } elseif (13 <= $hour && 15 > $hour) { $period = '响午'; } elseif (15 <= $hour && 18 > $hour) { $period = '下午'; } elseif (18 <= $hour && 20 > $hour) { $period = '傍晚'; } elseif (20 <= $hour && 22 > $hour) { $period = '晚上'; } elseif (22 <= $hour && 23 >= $hour) { $period = '深夜'; } return $period; } public static function getUTCDate($dateTime = null) { $oldTimezone = self::getTimezone(); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone('UTC'); } $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone($oldTimezone); } return $date; } public static function getMicroTime($get_as_float = null,$mircrotime = null) { return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); } public static function isLeapYear($year) { if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { return true; } return false; } public static function getTimeStamp($dateTime = null){ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); } public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); $timestamp = $timestamp ? $timestamp : time(); $compareTime = strtotime(self::format('Y-m-d',$timestamp)); $currentTime = strtotime(self::format('Y-m-d',$time)); $decrease = $timestamp - $time; $result = self::format($format,$time); if (0 >= $decrease) { return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } if ($currentTime == $compareTime) { if (1 == $type) { if (60 >= $decrease) { return array($decrease . $timelang['second'], $result); } return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); } return array(self::format('H:i',$time), $result); } elseif ($currentTime == $compareTime - 86400) { return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); } elseif ($currentTime == $compareTime - 172800) { return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); } return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } } class WindGeneralDate { const FILL = 0; const DIGIT = 1; const TEXT = 2; const DEFAULT_FORMAT = 'Y-m-d H:i:s'; private $time = 0; public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { $time = time(); !$month && ((!$year) ? $month = date('m', $time) : $month = 1); !$day && ((!$year) ? $day = date('d', $time) : $day = 1); !$hours && !$year && $hours = date('H', $time); !$minutes && !$year && $minutes = date('i', $time); !$second && !$year && $second = date('s', $time); !$year && $year = date('Y', $time); $this->time = mktime($hours, $minutes, $second, $month, $day, $year); } public function getDaysInMonth() { return date('t', $this->time); } public function getDaysInYear() { return $this->isLeapYear() ? 366 : 365; } public function getDayOfYear() { return date('z', $this->time) + 1; } public function getDayOfMonth() { return date('j', $this->time); } public function getDayOfWeek() { return date('w', $this->time) + 1; } public function getWeekOfYear() { return date('W', $this->time); } public function getYear($format = true) { return date($format ? 'Y' : 'y', $this->time); } public function getMonth($display = self::FILL) { if(self::FILL == $display){ return date('m', $this->time); }elseif(self::DIGIT == $display){ return date('n', $this->time); }elseif(self::TEXT == $display){ return date('M', $this->time); } return date('n', $this->time); } public function getDay($display = self::FILL) { if(self::FILL == $display){ return date('d', $this->time); }elseif(self::DIGIT == $display){ return date('j', $this->time); }elseif(self::TEXT == $display){ return date('jS', $this->time); } return date('j', $this->time); } public function getWeek($display = self::FILL) { if(self::FILL == $display || self::DIGIT == $display){ return date('w', $this->time); }elseif(self::TEXT == $display){ return date('D', $this->time); } return date('N', $this->time); } public function get12Hours($display = self::FILL){ if(self::FILL == $display){ return date('h', $this->time); }elseif(self::DIGIT == $display){ return date('g', $this->time);; } return date('h', $this->time); } public function get24Hours($display = self::FILL){ if(self::FILL == $display){ return date('H', $this->time); }elseif(self::DIGIT == $display){ return date('G', $this->time);; } return date('H', $this->time); } public function getMinutes() { return date('i', $this->time); } public function getSeconds() { return date('s', $this->time); } public function getLocalTimeZone() { return date('T', $this->time); } public function setTime($time) { if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { $this->time = $time; } } public function getNow() { $date = getdate($this->time); return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); } public function __toString() { return $this->toString(); } public function toString($format = null) { return date($format ? $format : self::DEFAULT_FORMAT, $this->time); } public function isLeapYear() { return date('L', $this->time); } } class WindDecoder { const JSON_SLICE = 1; const JSON_IN_STR = 2; const JSON_IN_ARR = 4; const JSON_IN_OBJ = 8; const JSON_IN_CMT = 16; public static function decode($str, $useArray = true) { $str = strtolower(self::reduceString($str)); if ('true' == $str) { return true; } elseif ('false' == $str) { return false; } elseif ('null' == $str) { return null; } elseif (is_numeric($str)) { return (float)$str == (integer)$str ? (integer) $str : (float) $str; }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ return self::jsonToString($str); }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); } return false; } protected static function jsonToString($string) { $delim = substr($string, 0, 1); $chrs = substr($string, 1, -1); $decodeStr = ''; for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { $compare = substr($chrs, $c, 2); $ordCode = ord($chrs{$c}); if('\b' == $compare){ $decodeStr .= chr(0x08); ++$c; }elseif('\t' == $compare){ $decodeStr .= chr(0x09); ++$c; }elseif('\n' == $compare){ $decodeStr .= chr(0x0A); ++$c; }elseif('\f' == $compare){ $decodeStr .= chr(0x0C); ++$c; }elseif('\r' == $compare){ $decodeStr .= chr(0x0D); ++$c; }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { $decodeStr .= $chrs{++$c}; } }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $decodeStr .= self::utf16beToUTF8($utf16); $c += 5; }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ $decodeStr .= $chrs{$c}; }elseif(0xC0 == ($ordCode & 0xE0)){ $decodeStr .= substr($chrs, $c, 2); ++$c; }elseif(0xE0 == ($ordCode & 0xF0)){ $decodeStr .= substr($chrs, $c, 3); $c += 2; }elseif(0xF0 == ($ordCode & 0xF8)){ $decodeStr .= substr($chrs, $c, 4); $c += 3; }elseif(0xF8 == ($ordCode & 0xFC)){ $decodeStr .= substr($chrs, $c, 5); $c += 4; }elseif(0xFC == ($ordCode & 0xFE)){ $decodeStr .= substr($chrs, $c, 6); $c += 5; } } return $decodeStr; } protected static function jsonToArray($str) { return self::complexConvert($str,true); } protected static function jsonToObject($str) { return self::complexConvert($str,false); } protected static function complexConvert($str,$useArray = true){ if ('[' == $str{0}) { $stk = array(self::JSON_IN_ARR); $arr = array(); } else { $obj = $useArray ? array() : new stdClass(); $stk = array(self::JSON_IN_OBJ); } array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = self::reduceString($chrs); if ('' == $chrs) { return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; } for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); if (reset($stk) == self::JSON_IN_ARR) { array_push($arr, self::decode($slice, $useArray)); } elseif (reset($stk) == self::JSON_IN_OBJ) { if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $key = self::decode($parts[1], $useArray); $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { array_pop($stk); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { array_pop($stk); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { array_pop($stk); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { array_pop($stk); for ($i = $top['where']; $i <= ++$c; ++$i){ $chrs = substr_replace($chrs, ' ', $i, 1); } } } if (self::JSON_IN_ARR == reset($stk)) { return $arr; } elseif (self::JSON_IN_OBJ == reset($stk)) { return $obj; } return false; } protected static function unicodeToUTF8(&$str) { $utf8 = ''; foreach ($str as $unicode) { if ($unicode < 128) { $utf8 .= chr($unicode); } elseif ($unicode < 2048) { $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } else { $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } } return $utf8; } protected static function reduceString($str) { return trim(preg_replace(array( '#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str)); } protected static function utf16beToUTF8(&$str) { return self::unicodeToUTF8(unpack('n*', $str)); } } class WindEncoder { public static $charset = 'utf-8'; public static function encode($value) { switch (gettype($value)) { case 'boolean': return $value ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $value; case 'double': case 'float': return (float) $value; case 'string': return self::stringToJson($value); case 'array': return self::arrayToJson($value); case 'object': return self::objectToJson($value); default: return ''; } return ''; } protected static function stringToJson($string) { if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { $string = iconv($enc, 'UTF-8', $string); } $ascii = ''; $strlen = strlen($string); for ($c = 0; $c < $strlen; ++$c) { $ordVar = ord($string{$c}); if (0x08 == $ordVar) { $ascii .= '\b'; } elseif (0x09 == $ordVar) { $ascii .= '\t'; } elseif (0x0A == $ordVar) { $ascii .= '\n'; } elseif (0x0C == $ordVar) { $ascii .= '\f'; } elseif (0x0D == $ordVar) { $ascii .= '\r'; } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { $ascii .= '\\' . $string{$c}; } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { $ascii .= $string{$c}; } elseif (0xC0 == ($ordVar & 0xE0)) { $char = pack('C*', $ordVar, ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xE0 == ($ordVar & 0xF0)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF0 == ($ordVar & 0xF8)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF8 == ($ordVar & 0xFC)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xFC == ($ordVar & 0xFE)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } } return '"' . $ascii . '"'; } protected static function arrayToJson(array $array) { if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; } return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; } protected static function objectToJson($object) { if ($object instanceof Traversable) { $vars = array(); foreach ($object as $k => $v) { $vars[$k] = $v; } } else { $vars = get_object_vars($object); } return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; } protected static function nameValue($name, $value) { return self::encode(strval($name)) . ':' . self::encode($value); } protected static function utf8ToUTF16BE(&$string, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if (function_exists('mb_convert_encoding')) { return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); } $uni = self::utf8ToUnicode($string); foreach ($uni as $cp) { $out .= pack('n', $cp); } return $out; } protected static function utf8ToUnicode(&$string) { $unicode = $values = array(); $lookingFor = 1; for ($i = 0, $length = strlen($string); $i < $length; $i++) { $thisValue = ord($string[$i]); if ($thisValue < 128) { $unicode[] = $thisValue; } else { if (count($values) == 0) { $lookingFor = ($thisValue < 224) ? 2 : 3; } $values[] = $thisValue; if (count($values) == $lookingFor) { $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; $values = array(); $lookingFor = 1; } } } return $unicode; } } class WindArray { public static function mergeArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); unset($array2[$key]); } else { $tmp[$key] = $array; } } return array_merge($tmp, (array) $array2); } public static function filterArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); } } return $tmp; } public static function rebuildArrayWithKey($key, array $array) { if (!$key || !$array) { return array(); } $tmp = array(); foreach ($array as $_array) { if (isset($_array[$key])) { $tmp[$_array[$key]] = $_array; } } return $tmp; } } Wind::import("COM:utility.WindSecurity"); Wind::import("COM:utility.WindString"); class WindFile { const READ = 'rb'; const READWRITE = 'rb+'; const WRITE = 'wb'; const WRITEREAD = 'wb+'; const APPEND_WRITE = 'ab'; const APPEND_WRITEREAD = 'ab+'; public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { $temp = "\r\n "; if (!$isBuildReturn && is_array($data)) { foreach ($data as $key => $value) { if (!preg_match('/^\w+$/', $key)) continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n"; } else { ($isBuildReturn) && $temp .= " return "; $temp .= WindString::varToString($data) . ";\r\n"; } return self::write($fileName, $temp, $method, $ifLock); } public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); fclose($handle); $ifChmod && chmod($fileName, 0777); return $writeCheck; } public static function read($fileName, $method = self::READ) { $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { flock($handle, LOCK_SH); $data = fread($handle, filesize($fileName)); fclose($handle); } return $data; } public static function clearDir($dir, $ifexpiled = false) { if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { self::delFile($fullPath); } } closedir($handle); false === $ifexpiled && rmdir($dir); return true; } public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); if (!$handler = opendir($path)) { return false; } while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { if (substr($filename, 0, 1) != '.') { self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); } } else { self::delFile($path . DIRECTORY_SEPARATOR . $filename); } } } closedir($handler); true == $delDir && $level > 0 && rmdir($path); return true; } public static function getMimeType($fileName) { $suffix = self::getFileSuffix($fileName); $mimes = require WIND_PATH . '/component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { throw new WindException('Sorry, can not find the corresponding mime type of the file'); } return false; } public static function getDirectoryIterator($dir) { return new DirectoryIterator($dir); } public static function getFileInfo($fileName) { if (false === is_file($fileName)) { return array(); } $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); $fileInfo['ctime'] = filectime($fileName); $fileInfo['atime'] = fileatime($fileName); $fileInfo['mtime'] = filemtime($fileName); $fileInfo['readable'] = is_readable($fileName); $fileInfo['writable'] = is_writable($fileName); $fileInfo['executable'] = is_executable($fileName); $fileInfo['right'] = fileperms($fileName); $fileInfo['group'] = filegroup($fileName); $fileInfo['owner'] = fileowner($fileName); $fileInfo['mime'] = self::getMimeType($fileName); return $fileInfo; } public static function getDirectoryInfo($dir) { if (false !== is_dir($dir)) { return array(); } return stat($dir); } public static function delFile($filename) { return @unlink($filename); } public static function getFileSuffix($filename) { $filename = explode($filename, '.'); return $filename[count($filename) - 1]; } public static function appendSlashesToDir($path) { return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; } } class WindHtmlHelper { public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function encodeArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; } return $_tmp; } } class WindImage { public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); if (!$imagecreate) return false; $imgwidth = $minitemp['width']; $imgheight = $minitemp['height']; $srcX = $srcY = $dstX = $dstY =0; if (!$isProportion) { $dsDivision = $imgheight / $imgwidth; $fixDivision = $dstH / $dstW; if ($dsDivision > $fixDivision) { $tmp = $imgwidth * $fixDivision; $srcY = round(($imgheight - $tmp) / 2); $imgheight = $tmp; } else { $tmp = $imgheight / $fixDivision; $srcX = round(($imgwidth - $tmp) / 2); $imgwidth = $tmp; } } $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { $black = imagecolorallocate($thumb, 0, 0, 0); imagecolortransparent($thumb, $black); } $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); self::makeImg($minitemp['type'], $thumb, $dstFile); imagedestroy($thumb); return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); } public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { $sourcedb = $waterdb = array(); if (false === ($sourcedb = self::getImgInfo($source))) return false; if (!$waterImg && !$waterText) return false; imagealphablending($sourcedb['source'], true); if ($waterImg) { $waterdb = self::getImgInfo($waterImg); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); if ($waterdb['type'] == 'png') { $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); $sourcedb['source'] = $tmp; } else { imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); } } elseif ($waterText) { list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); empty($waterFont) && $waterFont = 12; $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); $waterdb['width'] = $temp[2] - $temp[6]; $waterdb['height'] = $temp[3] - $temp[7]; unset($temp); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); if (strlen($color) != 7) return false; $R = hexdec(substr($color, 1, 2)); $G = hexdec(substr($color, 3, 2)); $B = hexdec(substr($color, 5)); self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); } $dstsrc && $source = $dstsrc; self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); isset($waterdb['source']) && imagedestroy($waterdb['source']); imagedestroy($sourcedb['source']); return true; } private static function checkAttribute($attribute) { $attribute = is_string($attribute) ? array($attribute) : $attribute; if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; return $attribute; } private static function changeCharset($charset) { $charset = strtolower($charset); return !in_array($charset, array('utf8', 'utf-8')); } private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { if (is_array($waterPos)) return $waterPos; $wX = $wY = 0; switch (intval($waterPos)) { case 0 : $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); break; case 1 : $wX = 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 2: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 3: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 4: $wX = 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 5: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 6: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; default: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; break; } return array($wX, $wY); } private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { if (false === ($imgdata = self::getImgInfo($srcFile))) return false; if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; $imgdata['dstW'] = $dstW; $imgdata['dstH'] = $dstH; if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); } elseif ($dstW > 0 && $dstH > 0) { if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); } if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); } } else { $imgdata = false; } return $imgdata; } public static function getImgInfo($srcFile) { if (false === ($imgdata = self::getImgSize($srcFile))) return false; $imgdata['type'] = self::getTypes($imgdata['type']); if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; $imgdata['source'] = $imagecreatefromtype($srcFile); !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); return $imgdata; } private static function getImgSize($srcFile, $srcExt = null) { empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); $srcdata = array(); $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); in_array($srcExt, $exts) && $srcdata['type'] = 2; if (false === ($info = getimagesize($srcFile))) return false; list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; return $srcdata; } private static function getImgcreate($imagetype) { if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { return array('imagecreatetruecolor', 'imagecopyresampled'); } if (function_exists('imagecreate') && function_exists('imagecopyresized')) { return array('imagecreate', 'imagecopyresized'); } return array('', ''); } private static function makeImg($type, $image, $filename, $quality = '75') { $makeimage = 'image' . $type; if (!function_exists($makeimage)) return false; if ($type == 'jpeg') { $makeimage($image, $filename, $quality); } else { $makeimage($image, $filename); } return true; } private static function getTypes($id) { $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; } } Wind::import('WIND:component.utility.WindFile'); class WindPack { const STRIP_SELF = 'stripWhiteSpaceBySelf'; const STRIP_PHP = 'stripWhiteSpaceByPhp'; const STRIP_TOKEN = 'stripWhiteSpaceByToken'; private $packList = array(); private $contentInjectionPosition; private $contentInjectionCallBack = ''; public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { if (empty($dst) || empty($dir)) { return false; } $suffix = is_array($suffix) ? $suffix : array( $suffix); if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { return false; } $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->stripImport($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { if (empty($dst) || empty($fileList)) { return false; } $content = array(); $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function stripWhiteSpaceByPhp($filename) { return php_strip_whitespace($filename); } public function stripWhiteSpaceBySelf($filename, $compress = true) { $content = $this->getContentFromFile($filename); $content = $this->stripComment($content, ''); return $this->stripSpace($content, ' '); } public function stripWhiteSpaceByToken($filename) { $content = $this->getContentFromFile($filename); $compressContent = ''; $lastToken = 0; foreach (token_get_all($content) as $key => $token) { if (is_array($token)) { if (in_array($token[0], array( T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) { continue; } $compressContent .= ' ' . $token[1]; } else { $compressContent .= $token; } $lastToken = $token[0]; } return $compressContent; } public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { static $content = array(); if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { return false; } $dir = is_array($dir) ? $dir : array( $dir); foreach ($dir as $_dir) { $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; if (is_dir($_dir)) { $handle = dir($_dir); while (false != ($tmp = $handle->read())) { $name = WindFile::appendSlashesToDir($_dir) . $tmp; if (is_dir($name) && !in_array($tmp, $ndir)) { $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); } if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { $content[] = $this->$packMethod($name); $this->setPackList($file, $name); } } $handle->close(); } } return $content; } public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { return array(); } $fileList = is_array($fileList) ? $fileList : array( $fileList); foreach ($fileList as $key => $value) { if (is_array($value) && isset($value[1])) { $parents = class_parents($value[1]); $_fileList = $this->buildFileList($parents, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); $implements = class_implements($value[1]); $_fileList = $this->buildFileList($implements, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); if (key_exists($key, $this->getPackList())) continue; $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; if (is_file($file)) { $content[] = $this->$packMethod($file); $this->setPackList($key, $value); } } } } public function stripComment($content, $replace = '') { return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); } public function stripNR($content, $replace = array('\n','\r\n','\r')) { return preg_replace('/[\n\r]+/', $replace, $content); } public function stripSpace($content, $replace = ' ') { return preg_replace('/[ ]+/', $replace, $content); } public function stripPhpIdentify($content, $replace = '') { return preg_replace('/(?:<\?(?:php)*)|(\)/i', $replace, $content); } public function stripStrByRule($content, $rule, $replace = '') { return preg_replace("/$rule/", $replace, $content); } public function stripImport($content, $replace = '') { $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); if ($matchs[1]) { foreach ($matchs[1] as $key => $value) { $name = substr($value, strrpos($value, '.') + 1); if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { $strip = str_replace(array( '(', ')'), array( '\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; $content = $this->stripStrByRule($content, $strip, $replace); } } } return $content; } public function getPackList() { return $this->packList; } public function getContentFromFile($filename) { if (is_file($filename)) { $content = ''; $fp = fopen($filename, "r"); while (!feof($fp)) { $line = fgets($fp); if (in_array(strlen($line), array( 2, 3)) && in_array(ord($line), array( 9, 10, 13))) continue; $content .= $line; } fclose($fp); return $content; } return false; } public function getContentBySuffix($content, $suffix, $replace = ' ') { switch ($suffix) { case 'php': $content = '' . $replace . $content . ''; break; default: $content = '' . $replace . $content . ''; break; } return $content; } private function buildFileList($list, $fileList) { $_temp = array(); foreach ($list as $fileName) { foreach ($fileList as $key => $value) { if ($value[1] == $fileName) { $_temp[$key] = $value; break; } } } return $_temp; } public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { if (!in_array($position, array( 'before', 'after'))) $position = 'before'; $this->contentInjectionPosition = $position; $this->contentInjectionCallBack = $contentInjectionCallBack; } public function callBack($content, $replace = '') { if ($this->contentInjectionCallBack !== '') { $_content = call_user_func_array($this->contentInjectionCallBack, array( $this->getPackList())); if ($this->contentInjectionPosition == 'before') { $content = $replace . $_content . $content; } elseif ($this->contentInjectionPosition == 'after') { $content .= $replace . $_content . $replace; } } return $content; } private function isValidatePackMethod($packMethod) { return method_exists($this, $packMethod) && in_array($packMethod, array( WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN)); } private function setPackList($key, $value) { if (isset($this->packList[$key])) { if (is_array($this->packList[$key])) { array_push($this->packList[$key], $value); } else { $tmp_name = $this->packList[$key]; $this->packList[$key] = array( $tmp_name, $value); } } else { $this->packList[$key] = $value; } } } class WindSecurity { public static function escapeHTMLForArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::escapeHTMLForArray($value); $_tmp[$key] = $value; } return $_tmp; } public static function escapeHTML($str) { if (is_array($str)) return self::escapeHTMLForArray($str); return htmlspecialchars($str, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function stripTags($str, $allowTags = "") { return strip_tags($str, $allowTags); } public static function escapePath($fileName, $ifCheck = true) { if (!self::_escapePath($fileName, $ifCheck)) { throw new WindException('file name is illegal'); } return $fileName; } public static function escapeDir($dir) { $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } public static function escapeChar($value) { if (is_array($value)) { foreach ($value as $key => $sub) { $value[$key] = self::escapeChar($sub); } } elseif (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = self::escapeString($value); } return $value; } public static function escapeString($string) { $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); return preg_replace( array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } public static function quotemeta($string) { return quotemeta($string); } public function checkInputValue($value, $key = '') { if (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = "'" . addslashes($value) . "'"; } elseif (is_float($value)) { $value = (float) $value; } elseif (is_object($value) || is_array($value)) { $value = "'" . addslashes(serialize($value)) . "'"; } return $value; } public static function addSlashesForInput($str) { if (!get_magic_quotes_gpc()) { $str = addslashes($str); } return $str; } public static function addSlashesForOutput($str) { if (!get_magic_quotes_runtime()) { $str = addslashes($str); } return $str; } public static function addSlashes($value, $gpc = false, $df = false) { if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable))) { return $value; } if (is_string($value)) { if (false === $gpc && true === $df) { return self::addSlashesForOutput($value); } if (false === $df && true === $gpc) { return self::addSlashesForInput($value); } return addslashes($value); } foreach ($value as $key => $_value) { $value[$key] = self::addSlashes($_value, $gpc, $df); } return $value; } public static function stripSlashes($value) { if (!$value) return $value; if (is_string($value)) return stripslashes($value); if (!is_array($value) && !($value instanceof Traversable)) return $value; foreach ($value as $key => $_value) { $value[$key] = self::stripSlashes($_value); } return $value; } public static function sqlEscape($var, $strip = true, $isArray = false) { if (is_array($var)) { if (!$isArray) return " '' "; foreach ($var as $key => $value) { $var[$key] = trim(self::sqlEscape($value, $strip)); } return $var; } elseif (is_numeric($var)) { return " '" . $var . "' "; } else { return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; } } public static function sqlImplode($array, $strip = true) { return implode(',', self::sqlEscape($array, $strip, true)); } public static function sqlSingle($array, $strip = true) { if (!is_array($array)) return ''; $array = self::sqlEscape($array, $strip, true); $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; } return $str; } public static function sqlMulti($array, $strip = true) { if (!is_array($array)) { return ''; } $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; } } return $str; } public static function sqlMetadata($data, $tlists = array()) { if (empty($tlists) || !in_array($data, $tlists)) { $data = str_replace(array('`', ' '), '', $data); } return ' `' . $data . '` '; } private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; if (strtr($tmpname, $tmparray) != $tmpname) { return false; } return true; } } class WindString { const UTF8 = 'utf8'; const GBK = 'gbk'; public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( $string, $start, $length, $dot); } public static function strlen($string, $charset = self::UTF8) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; $count++; } return $count; } public static function varToString($input, $indent = '') { switch (gettype($input)) { case 'string': return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; case 'array': $output = "array(\r\n"; foreach ($input as $key => $value) { $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( $value, $indent . "\t"); $output .= ",\r\n"; } $output .= $indent . ')'; return $output; case 'boolean': return $input ? 'true' : 'false'; case 'NULL': return 'NULL'; case 'integer': case 'double': case 'float': return "'" . (string) $input . "'"; } return 'NULL'; } public static function jsonEncode($value) { if (!function_exists('json_encode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); } public static function jsonDecode($value) { if (!function_exists('json_decode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); } public static function jsonSimpleEncode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': return '"' . addslashes( str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; case 'array': if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array(); foreach ($var as $name => $value) { $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( $value); } return '{' . join(',', $properties) . '}'; } $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); return '[' . join(',', $elements) . ']'; } return false; } public static function utf8_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j += 2; } else { $word++; } $j++; } $start = $word + 3 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 3); $j += 2; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function utf8_strlen($str) { $i = $count = 0; $len = strlen($str); while ($i < $len) { $chr = ord($str[$i]); $count++; $i++; if ($i >= $len) break; if ($chr & 0x80) { $chr <<= 1; while ($chr & 0x80) { $i++; $chr <<= 1; } } } return $count; } public static function gbk_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j++; } else { $word++; } $j++; } $start = $word + 2 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 2); $j++; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function gbk_strlen($string) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? $i += 2 : $i++; $count++; } return $count; } } class WindUtility { public static function mergeArray($array1, $array2) { foreach ($array2 as $key => $value) { if (!isset($array1[$key]) || !is_array($array1[$key])) { $array1[$key] = $value; continue; } $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); } return $array1; } public static function lcfirst($str) { if (function_exists('lcfirst')) return lcfirst($str); $str[0] = strtolower($str[0]); return $str; } public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { $randnum = rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { $randstr .= chr($randnum + 55); } else { $randstr .= chr($randnum + 61); } } return $randstr; } public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } class WindValidator { public static function isTelPhone($phone) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); } public static function isTelNumber($number) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); } public static function isQQ($qq) { return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); } public static function isZipcode($zipcode) { return 0 < preg_match('/^\d{4,8}$/', $zipcode); } public static function hasEmail($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); } public static function isEmail($string) { return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); } public static function hasIdCard($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); } public static function isIdCard($string) { return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); } public static function hasUrl($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); } public static function isUrl($string) { return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); } public static function hasChinese($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); } public static function isChinese($string) { return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); } public static function hasHtml($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); } public static function isHtml($string) { return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); } public static function hasIpv4($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); } public static function isIpv4($string) { return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); } public static function hasIpv6($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| ::([a-f0-9]{1,4}:){5}| ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )([a-f0-9]{1,4}:[a-f0-9]{1,4}| (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string, $matches, $ifAll); } public static function isIpv6($string) { return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| ::(?:[a-f0-9]{1,4}:){5}| (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string); } public static function hasScript($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); } public static function isScript($string) { return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); } public static function isEmpty($value) { return empty($value); } public static function isNonNegative($number) { return 0 <= (int) $number; } public static function isPositive($number) { return 0 < (int) $number; } public static function isNegative($number) { return 0 > (int) $number; } public static function isArray($array) { return is_array($array); } public static function isRequired($value) { return !self::isEmpty($value); } public static function inArray($needle, array $array, $strict = true) { return in_array($needle, $array, $strict); } public static function isLegalLength($string, $length, $charset = 'utf8') { Wind::import('WIND:component.utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { if (true === $ifAll) { return preg_match_all($regExp, $string, $matches); } return preg_match($regExp, $string, $matches); } }?> \ No newline at end of file From c15e8babc4c4c4a6e7da636f435e712b548cafa4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 02:29:50 +0000 Subject: [PATCH 0411/1065] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2483 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/components_config.php | 114 --------------------------------- _compile/wind_basic.php | 1 - 2 files changed, 115 deletions(-) delete mode 100644 _compile/components_config.php delete mode 100644 _compile/wind_basic.php diff --git a/_compile/components_config.php b/_compile/components_config.php deleted file mode 100644 index 9778e06b..00000000 --- a/_compile/components_config.php +++ /dev/null @@ -1,114 +0,0 @@ - array( - 'path' => 'WIND:core.web.WindWebApplication', - 'scope' => 'singleton', - 'properties' => array( - 'dispatcher' => array( - 'ref' => 'dispatcher', - ), - 'handlerAdapter' => array( - 'ref' => 'router', - ), - ), - ), - 'windLogger' => array( - 'path' => 'COM:log.WindLogger', - 'scope' => 'singleton', - 'constructor-arg' => array( - '0' => array( - 'value' => 'data.log', - ), - '1' => array( - 'value' => '0', - ), - ), - ), - 'dispatcher' => array( - 'path' => 'WIND:core.web.WindDispatcher', - 'scope' => 'application', - ), - 'forward' => array( - 'path' => 'WIND:core.web.WindForward', - 'scope' => 'prototype', - 'properties' => array( - 'windView' => array( - 'ref' => 'windView', - ), - ), - ), - 'router' => array( - 'path' => 'COM:router.WindRouter', - 'scope' => 'application', - ), - 'urlHelper' => array( - 'path' => 'WIND:core.web.WindUrlHelper', - 'scope' => 'application', - ), - 'windView' => array( - 'path' => 'COM:viewer.WindView', - 'scope' => 'prototype', - 'config' => array( - 'template-dir' => 'template', - 'template-ext' => 'htm', - 'is-compile' => '0', - 'compile-dir' => 'compile.template', - 'is-cache' => '0', - ), - 'properties' => array( - 'viewResolver' => array( - 'ref' => 'viewResolver', - ), - 'viewCache' => array( - 'ref' => 'viewCache', - ), - ), - ), - 'viewResolver' => array( - 'path' => 'COM:viewer.WindViewerResolver', - 'scope' => 'prototype', - 'properties' => array( - 'windLayout' => array( - 'ref' => 'layout', - ), - ), - ), - 'layout' => array( - 'path' => 'COM:viewer.WindLayout', - 'scope' => 'prototype', - ), - 'template' => array( - 'path' => 'COM:viewer.compiler.WindViewTemplate', - 'scope' => 'prototype', - ), - 'db' => array( - 'path' => 'COM:db.WindConnection', - 'scope' => 'singleton', - 'config' => array( - 'resource' => 'db_config.xml', - ), - ), - 'errorMessage' => array( - 'path' => 'WIND:core.web.WindErrorMessage', - 'scope' => 'prototype', - ), - 'configParser' => array( - 'path' => 'COM:parser.WindConfigParser', - 'scope' => 'singleton', - ), - 'windCache' => array( - 'path' => 'COM:cache.strategy.WindFileCache', - 'config' => array( - 'dir' => 'data.config', - 'suffix' => 'php', - 'expires' => '0', - ), - ), - 'viewCache' => array( - 'path' => 'COM:cache.strategy.WindFileCache', - 'config' => array( - 'dir' => 'data.view', - 'suffix' => 'php', - 'expires' => '10', - ), - ), -); \ No newline at end of file diff --git a/_compile/wind_basic.php b/_compile/wind_basic.php deleted file mode 100644 index 9bbdf6d7..00000000 --- a/_compile/wind_basic.php +++ /dev/null @@ -1 +0,0 @@ -$_setter($value); } public function __get($propertyName) { $_getter = 'get' . ucfirst($propertyName); if (method_exists($this, $_getter)) return $this->$_getter(); } public function __call($methodName, $args) { $_prefix = substr($methodName, 0, 4); $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { if (isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { $_value = $_property['value']; } elseif (isset($_property['ref'])) { $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); } elseif (isset($_property['path'])) { $_className = Wind::import($_property['path']); $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { $this->$_propertyName = $args[0]; } } public function __clone() { foreach ($this->writeTableCloneProperty() as $value) { if (!is_object($this->$value) || !isset($this->$value)) continue; $this->$value = clone $this->$value; } } public function toArray() { $reflection = new ReflectionClass(get_class($this)); $properties = $reflection->getProperties(); $_result = array(); foreach ($properties as $property) { $_propertyName = $property->name; $_result[$_propertyName] = $this->$_propertyName; } return $_result; } public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { if (empty($config)) $config = $this->_config; if ($configName === '') return $config; if (!isset($config[$configName])) return $default; if ($subConfigName === '') return $config[$configName]; if (!isset($config[$configName][$subConfigName])) return $default; return $config[$configName][$subConfigName]; } public function _getConfig() { $args = func_get_args(); $_tmp = ''; foreach ($args as $value) { if (!isset($this->_config[$value])) continue; $_tmp = $this->_config[$value]; } } public function setConfig($config) { if ($config) { if (is_string($config)) $config = Wind::getApp()->getComponent('configParser')->parse($config); if (!empty($this->_config)) { $this->_config = array_merge($this->_config, (array) $config); } else $this->_config = $config; } } protected function writeTableForProperty() { return array('delayAttributes' => 'array'); } protected function writeTableCloneProperty() { return array(); } protected function getSystemFactory() { return Wind::getApp()->getWindFactory(); } protected function getRequest() { return Wind::getApp()->getRequest(); } protected function getResponse() { return Wind::getApp()->getResponse(); } public function setDelayAttributes($delayAttributes) { $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); } } class WindLogger extends WindModule { const LEVEL_INFO = 1; const LEVEL_TRACE = 2; const LEVEL_DEBUG = 3; const LEVEL_ERROR = 4; const LEVEL_PROFILE = 5; const WRITE_TYPE = 2; const WRITE_LEVEL = 1; const TOKEN_BEGIN = 'begin:'; const TOKEN_END = 'end:'; private $_autoFlush = 1000; private $_logs = array(); private $_logCount = 0; private $_profiles = array(); private $_logDir; private $_maxFileSize = 100; private $_writeType = 0; private $_types = array(); private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); public function __construct($logDir = '', $writeType = 0) { $this->setLogDir($logDir); $this->_writeType = $writeType; } public function info($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_INFO, $type, $flush); } public function trace($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_TRACE, $type, $flush); } public function debug($msg, $type = 'wind.system', $flush = false) { $this->log($msg, self::LEVEL_DEBUG, $type, $flush); } public function error($msg, $type = 'wind.core', $flush = false) { $this->log($msg, self::LEVEL_ERROR, $type, $flush); } public function profileBegin($msg, $type = 'wind.core', $flush = false) { $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function profileEnd($msg, $type = 'wind.core', $flush = false) { $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); } public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { if (!$this->_logDir) return; if ($this->_writeType & self::WRITE_TYPE) (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else $message = $this->_build($msg, $level, $type); $this->_logs[] = array($level, $type, $message); $this->_logCount++; if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) $this->_types[] = $type; if ($flush) $this->flush(); } public function flush() { if (empty($this->_logs)) return false; Wind::import('WIND:component.utility.WindFile'); $_l = $_logTypes = $_logLevels = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; $_logTypes[$value[1]][] = $value[2]; $_logLevels[$value[0]][] = $value[2]; } if ($this->_writeType & 1) { foreach ($_logLevels as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($this->_writeType & 2) { foreach ($_logTypes as $key => $value) { if (!$fileName = $this->_getFileName($key)) continue; WindFile::write($fileName, join("", $value), 'a'); } } if ($fileName = $this->_getFileName()) { WindFile::write($fileName, join("", $_l), 'a'); } $this->_logs = array(); $this->_logCount = 0; return true; } public function getMemoryUsage($peak = true) { if ($peak && function_exists('memory_get_peak_usage')) return memory_get_peak_usage(); elseif (function_exists('memory_get_usage')) return memory_get_usage(); $pid = getmypid(); if (strncmp(PHP_OS, 'WIN', 3) === 0) { exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; } else { exec("ps -eo%mem,rss,pid | grep $pid", $output); $output = explode(" ", $output[0]); return isset($output[1]) ? $output[1] * 1024 : 0; } } private function _build($msg, $level, $type, $timer = 0, $mem = 0) { $result = ''; switch ($level) { case self::LEVEL_INFO: $result = $this->_buildInfo($msg); break; case self::LEVEL_ERROR: $result = $this->_buildError($msg); break; case self::LEVEL_DEBUG: $result = $this->_buildDebug($msg); break; case self::LEVEL_TRACE: $result = $this->_buildTrace($msg); break; case self::LEVEL_PROFILE: $result = $this->_buildProfile($msg, $type, $timer, $mem); break; default: break; } return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; } private function _buildProfile($msg, $type, $timer, $mem) { $_msg = ''; if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message:"; $_token = substr($msg, strlen(self::TOKEN_END)); $_token = substr($_token, 0, strpos($_token, ':')); foreach ($this->_profiles as $key => $profile) { if ($profile[0] !== $_token) continue; if ($profile[1]) $_msg .= "\r\n\t" . $profile[1]; else $_msg .= "\r\n\t" . substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1); $_msg .= "\r\n\tTime:" . ($timer - $profile[3]) . "\r\n\tMem:" . ($mem - $profile[4]) . "\r\n\tType:$profile[2]"; break; } unset($this->_profiles[$key]); } return $_msg; } private function _buildInfo($msg) { return "INFO! Message: " . $msg; } private function _buildTrace($msg) { return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); } private function _buildDebug($msg) { return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); } private function _buildError($msg) { return 'ERROR! Message: ' . $msg; } private function _getTrace() { $num = 0; $info[] = 'Stack trace:'; $traces = debug_backtrace(); foreach ($traces as $traceKey => $trace) { if ($num >= 7) break; if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( $trace['file'], __CLASS__ . '.php') !== false) continue; $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; if ($function == 'WindBase::log') continue; $args = array_map(array($this, '_buildArg'), $trace['args']); $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; } return $info; } private function _buildArg($arg) { switch (gettype($arg)) { case 'array': return 'Array'; break; case 'object': return 'Object ' . get_class($arg); break; default: return "'" . $arg . "'"; break; } } private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { $counter = 0; do { $counter++; $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } public function __destruct() { $this->flush(); } public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); $this->_logDir = $logDir; } public function setMaxFileSize($maxFileSize) { $this->_maxFileSize = (int) $maxFileSize; } } class WindException extends Exception { const ERROR_SYSTEM_ERROR = '0'; const ERROR_CLASS_NOT_EXIST = '100'; const ERROR_CLASS_TYPE_ERROR = '101'; const ERROR_CLASS_METHOD_NOT_EXIST = '102'; const ERROR_OBJECT_NOT_EXIST = '103'; const ERROR_PARAMETER_TYPE_ERROR = '110'; const ERROR_CONFIG_ERROR = '120'; const ERROR_RETURN_TYPE_ERROR = '130'; private $innerException = null; public function __construct($message = '', $code = 0, Exception $innerException = null) { $message = $this->buildMessage($message, $code); parent::__construct($message, $code); $this->innerException = $innerException; } public function getInnerException() { return $this->innerException; } public function getStackTrace() { if ($this->innerException) { $thisTrace = $this->getTrace(); $class = __CLASS__; $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); foreach ($innerTrace as $trace) $thisTrace[] = $trace; return $thisTrace; } else { return $this->getTrace(); } return array(); } public function buildMessage($message, $code) { $message = str_replace(array("
", "
", "\r\n"), '', $message); eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); return $message; } protected function messageMapper($code) { $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); return isset($messages[$code]) ? $messages[$code] : '$message'; } } class WindActionException extends WindException { private $error; public function __construct($error, $code = 0) { if ($error instanceof WindErrorMessage) { $this->setError($error); parent::__construct($error->getError(0), $code); } else parent::__construct($error, $code); } protected function messageMapper($code) { $messages = array(); return isset($messages[$code]) ? $messages[$code] : '$message'; } public function getError() { return $this->error; } public function setError($error) { $this->error = $error; } } class WindFinalException extends Exception{ } interface IWindFactory { public function getInstance($classAlias); public function getPrototype($classAlias); static public function createInstance($className, $args = array()); } class WindClassProxy { const EVENT_TYPE_METHOD = 'method'; const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; protected $_classPath = ''; protected $_reflection = null; protected $_instance = null; protected $_listener = array(); public function __construct($targetObject = null) { $targetObject && $this->registerTargetObject($targetObject); } public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); array_push($this->_listener[$type][$event], $listener); } public function registerTargetObject($targetObject) { if ($this->_instance !== null || !is_object($targetObject)) return; $this->_setClassName(get_class($targetObject)); $this->_instance = $targetObject; $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); foreach ($types as $type) $this->_listener[$type] = array(); return $this; } public function __set($propertyName, $value) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); return $interceptorChain->getHandler()->handle($value); } public function __get($propertyName) { $property = $this->_getReflection()->getProperty($propertyName); if (!$property || !$property->isPublic()) { throw new WindException('undefined property name. '); } $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); if (empty($listeners)) return call_user_func_array(array($this, '_getProperty'), array($propertyName)); $interceptorChain = $this->_getInterceptorChain($propertyName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); return $interceptorChain->getHandler()->handle($propertyName); } public function __call($methodName, $args) { $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); if (empty($listeners)) return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); $interceptorChain = $this->_getInterceptorChain($methodName); $interceptorChain->addInterceptors($listeners); $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); } private function _getInterceptorChain($event = '') { if (null === $this->_interceptorChainObj) { $chain = Wind::import($this->_interceptorChain); $interceptorChain = WindFactory::createInstance($chain); if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; } private function _getListenerByType($type, $subType) { $listener = array(); if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { $listener = $this->_listener[$type][$subType]; } return $listener; } public function _getInstance() { return $this->_instance; } public function _getClassName() { return $this->_className; } public function _getClassPath() { return $this->_classPath; } public function _setClassName($className) { $this->_className = $className; } public function _setClassPath($classPath) { $this->_setClassName(Wind::import($classPath)); $this->_classPath = $classPath; } public function _setProperty($propertyName, $value) { $this->_getInstance()->$propertyName = $value; } public function _getProperty($propertyName) { return $this->_getInstance()->$propertyName; } } Wind::import('COM:utility.WindUtility'); class WindFactory implements IWindFactory { protected $proxyType = 'WIND:core.factory.WindClassProxy'; protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); public function __construct($classDefinitions = array()) { if (is_array($classDefinitions)) { $this->classDefinitions = $classDefinitions; } } public function getInstance($alias, $args = array()) { $instance = null; $definition = isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : array(); if (isset($this->prototype[$alias])) { $instance = clone $this->prototype[$alias]; } elseif (isset($this->instances[$alias])) { $instance = $this->instances[$alias]; } else { if (!$definition) throw new WindException( '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { if (isset($_var['value'])) { $args[] = $_var['value']; } elseif (isset($_var['ref'])) $args[] = $this->getInstance($_var['ref']); } if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); if (isset($definition['config'])) $this->resolveConfig($definition['config'], $alias, $instance); if (isset($definition['properties'])) $this->buildProperties($definition['properties'], $instance); if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); } if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); return $instance; } public function registInstance($instance, $alias, $scope = 'singleton') { if (!is_object($instance) || !$alias) return false; return $this->setScope($alias, $scope, $instance); } static public function createInstance($className, $args = array()) { try { if (!$className || !class_exists($className)) throw new WindException('class is not exist.'); if (empty($args)) { return new $className(); } else { $reflection = new ReflectionClass($className); return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } public function getPrototype($alias) { return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; } public function addClassDefinitions($alias, $classDefinition) { if (is_string($alias) && !empty($alias)) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } public function loadClassDefinitions($classDefinitions, $merge = true) { foreach ((array) $classDefinitions as $alias => $definition) { if (!is_array($definition)) continue; if (!isset($this->classDefinitions[$alias]) || $merge === false) { $this->classDefinitions[$alias] = $definition; continue; } $this->classDefinitions[$alias] = WindUtility::mergeArray( $this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } public function checkAlias($alias) { if (isset($this->prototype[$alias])) return true; elseif (isset($this->instances[$alias])) return true; return false; } protected function setScope($alias, $scope, $instance) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; break; default: $this->instances[$alias] = $instance; break; } return true; } protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); $config = $configParser->parse($_configPath, $alias, true, Wind::getApp()->getComponent('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); } protected function executeInitMethod($initMethod, $instance) { try { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } protected function setProxyForClass($proxy, $instance) { if ($proxy === 'false' || $proxy === false) return $instance; if ($proxy === 'true' || $proxy === true) $proxy = $this->proxyType; $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); return $this->getInstance($proxy)->registerTargetObject($instance); } protected function buildProperties($properties, $instance) { if (!isset($properties['delay'])) { $instance->setDelayAttributes($properties); } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { foreach ($properties as $key => $subDefinition) { $_value = ''; if (isset($subDefinition['value'])) $_value = $subDefinition['value']; elseif (isset($subDefinition['ref'])) $_value = $this->getInstance($subDefinition['ref']); elseif (isset($subDefinition['path'])) { $_className = Wind::import($subDefinition['path']); $_value = $this->createInstance($_className); } $_setter = 'set' . ucfirst(trim($key, '_')); if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value)); } } else $instance->setDelayAttributes($properties); } } abstract class WindHandlerInterceptor extends WindModule { protected $result = null; protected $interceptorChain = null; abstract public function preHandle(); abstract public function postHandle(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'preHandle'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->handle(); } call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } public function setHandlerInterceptorChain($interceptorChain) { $this->interceptorChain = $interceptorChain; } } abstract class WindActionFilter extends WindHandlerInterceptor { protected $_vars = array(); protected $forward = null; protected $errorMessage = null; public function __construct($forward, $errorMessage) { $this->forward = $forward; $this->errorMessage = $errorMessage; $args = func_get_args(); unset($args[0], $args[1]); foreach ($args as $key => $value) property_exists(get_class($this), $key) && $this->$key = $value; $this->_vars = $forward->getVars(); } protected function setOutput($data, $key = '') { $this->forward->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->forward->setVars($data, $key, true); } protected function getInput($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->getRequest()->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->getRequest()->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->getRequest()->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->getRequest()->getCookie($name); break; default: $value = $this->getRequest()->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } } Wind::import('COM:fitler.WindHandlerInterceptor'); abstract class WindFilter extends WindHandlerInterceptor { } class WindHandlerInterceptorChain extends WindModule { protected $_interceptors = array(); protected $_callBack = null; protected $_args = array(); protected $_state = 0; public function setCallBack($callBack, $args = array()) { $this->_callBack = $callBack; $this->_args = $args; } public function handle() { if ($this->_callBack === null) return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); } public function getHandler() { if (count($this->_interceptors) <= 0) { return $this; } if ($this->_state >= count($this->_interceptors)) return null; $handler = $this->_interceptors[$this->_state++]; if ($handler instanceof WindHandlerInterceptor) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } public function addInterceptors($interceptors) { if (is_array($interceptors)) $this->_interceptors += $interceptors; else $this->_interceptors[] = $interceptors; } public function reset() { $this->_interceptors = array(); $this->_callBack = null; $this->_args = array(); $this->_state = 0; return true; } } class WindFilterChain extends WindHandlerInterceptorChain { public function __construct($filterConfig) { $this->_initFilters($filterConfig); } public function deleteFilter($alias) { unset($this->_interceptors[$alias]); } public function addFilter($filter, $beforFilter = '') { if ($beforFilter === '') { $this->addInterceptors(array(get_class($filter) => $filter)); return true; } $_interceptors = array(); foreach ($this->_interceptors as $key => $interceptor) { if ($beforFilter === $key) break; $_interceptors[$key] = $interceptor; unset($this->_interceptors[$key]); } $_interceptors[get_class($filter)] = $filter; $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; } private function _initFilters($filters = array()) { $_temp = array(); foreach ((array) $filters as $key => $filter) { if (!is_array($filter)) continue; $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); if (!class_exists($filterClass)) continue; $_temp[$key] = new $filterClass(); } $this->addInterceptors($_temp); } } interface IWindApplication { public function run(); public function getRequest(); public function getResponse(); public function getWindFactory(); } class WindUrlFilter extends WindFilter { public function preHandle($request = null, $response = null) { } public function postHandle($request = null, $response = null) { } } class WindFormListener extends WindHandlerInterceptor { private $request = null; private $formPath = ''; private $errorMessage = null; public function __construct($request, $formPath, $errorMessage) { $this->request = $request; $this->formPath = $formPath; $this->errorMessage = $errorMessage; } public function preHandle() { $className = Wind::import($this->formPath); if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) throw new WindException( 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( $_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); } call_user_func_array(array($form, 'validate'), array($form)); if (($error = $form->getErrors())) { list($errorController, $errorAction) = $form->getErrorControllerAndAction(); $this->sendError($errorController, $errorAction, $error); } $this->request->setAttribute('formData', $form); } private function sendError($errorController, $errorAction, $errors) { $this->errorMessage->setErrorController($errorController); $this->errorMessage->setErrorAction($errorAction); $this->errorMessage->addError($errors); $this->errorMessage->sendError(); } public function postHandle() { } } Wind::import('COM:fitler.WindHandlerInterceptor'); class WindValidateListener extends WindHandlerInterceptor { private $request = null; private $validateRules = array(); private $validator = null; private $validatorClass = ''; private $defaultMessage = '验证失败'; public function __construct($request, $validateRules, $validatorClass) { $this->request = $request; $this->validateRules = (array) $validateRules; $this->validatorClass = $validatorClass; } public function preHandle() { if (!isset($this->validateRules['errorMessage'])) $errorMessage = new WindErrorMessage(); else { $errorMessage = $this->validateRules['errorMessage']; unset($this->validateRules['errorMessage']); } $_input = new stdClass(); foreach ((array) $this->validateRules as $rule) { if (!is_array($rule)) continue; $key = $rule['field']; $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( $key); $args = $rule['args']; array_unshift($args, $value); if (call_user_func_array(array($this->getValidator(), $rule['validator']), (array) $args) === false) { if (null === $rule['default']) $errorMessage->addError( ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); else $value = $rule['default']; } $this->request->setAttribute($key, $value); $_input->$key = $value; } if ($errorMessage->getError()) $errorMessage->sendError(); else $this->request->setAttribute('inputData', $_input); } private function getValidator() { if ($this->validator === null) { $_className = Wind::import($this->validatorClass); $this->validator = WindFactory::createInstance($_className); if ($this->validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->validator; } public function postHandle() { } } abstract class WindSimpleController extends WindModule implements IWindController { protected $_vars = array(); protected $forward = null; protected $errorMessage = null; abstract public function run(); public function doAction($handlerAdapter) { if ($this->forward !== null) $this->_vars = $this->forward->getVars(); $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); call_user_func_array(array($this, $method), array()); if ($this->errorMessage !== null) $this->getErrorMessage()->sendError(); $this->afterAction($handlerAdapter); return $this->forward; } public function resolveActionFilter($action) { return array(); } protected function beforeAction($handlerAdapter) {} protected function afterAction($handlerAdapter) {} protected function forwardAction($action = 'run', $args = array(), $isRedirect = false) { $this->getForward()->forwardAction($action, $args, $isRedirect); } protected function forwardRedirect($url) { $this->getForward()->setIsRedirect(true); $this->getForward()->setUrl($url); } protected function setOutput($data, $key = '') { $this->getForward()->setVars($data, $key); } protected function setGlobal($data, $key = '') { $this->getForward()->setVars($data, $key, true); } protected function getInput($name, $type = '', $callback = null) { if (is_array($name)) return $this->getInputWithArray($name, $type); else return $this->getInputWithString($name, $type, $callback); } protected function setTemplate($template) { $this->getForward()->getWindView()->templateName = $template; } protected function setTemplatePath($templatePath) { $this->getForward()->getWindView()->templateDir = $templatePath; } protected function setTemplateExt($templateExt) { $this->getForward()->getWindView()->templateExt = $templateExt; } protected function setTheme($theme) { $this->getForward()->getWindView()->thems = $theme; } protected function setLayout($layout) { $this->getForward()->getWindView()->layout = $layout; } protected function addMessage($message, $key = '') { $this->getErrorMessage()->addError($message, $key); } protected function showMessage($message = '', $key = '', $errorAction = '') { $this->addMessage($message, $key); $this->getErrorMessage()->setErrorAction($errorAction); $this->getErrorMessage()->sendError(); } protected function setDefaultTemplateName($handlerAdapter) {} protected function resolvedActionMethod($handlerAdapter) { return 'run'; } private function getInputWithString($name, $type = '', $callback = array()) { $value = ''; switch (strtolower($type)) { case 'form': $value = $this->getRequest()->getData($name); break; case IWindRequest::INPUT_TYPE_GET: $value = $this->getRequest()->getGet($name); break; case IWindRequest::INPUT_TYPE_POST: $value = $this->getRequest()->getPost($name); break; case IWindRequest::INPUT_TYPE_COOKIE: $value = $this->getRequest()->getCookie($name); break; default: $value = $this->getRequest()->getAttribute($name); } return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; } private function getInputWithArray($name, $type = '') { $result = array(); foreach ($name as $key => $value) { $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); } return $result; } public function getForward() { return $this->_getForward(); } public function getErrorMessage() { return $this->_getErrorMessage(); } public function setForward($forward) { $this->forward = $forward; } public function setErrorMessage($errorMessage) { $this->errorMessage = $errorMessage; } } interface IWindController { public function doAction($handlerAdapter); public function resolveActionFilter($action); } abstract class WindController extends WindSimpleController { protected function resolvedActionMethod($handlerAdapter) { $action = $handlerAdapter->getAction(); if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { throw new WindException('[core.web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; } protected function resolvedActionName($action) { return $action . 'Action'; } } Wind::import('COM:viewer.exception.WindViewException'); class WindDispatcher extends WindModule { protected $token; protected $display = false; public function dispatch($forward, $router, $display) { $this->checkToken($router, false); if ($forward->getIsRedirect()) $this->dispatchWithRedirect($forward, $router); elseif ($forward->getIsReAction()) $this->dispatchWithAction($forward, $router, $display); else { $view = $forward->getWindView(); if ($view->templateName) { $vars = $forward->getVars(); Wind::getApp()->getResponse()->setData($vars, $view->templateName); Wind::getApp()->getResponse()->setData($vars['G'], true); $view->render($forward, $router, $this->display); } $this->display = false; } } protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), $forward->getArgs()); if ($this->checkToken($router)) throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); } else $_url = $this->_getUrlHelper()->checkUrl($_url); $this->getResponse()->sendRedirect($_url); } protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); $this->display = $display; list($action, $_args) = explode('?', $action . '?'); $action = trim($action, '/') . '/'; $action = explode('/', $action); end($action); if ($_tmp = prev($action)) $router->setAction($_tmp); if ($_tmp = prev($action)) $router->setController($_tmp); if ($_tmp = prev($action)) $router->setModule($_tmp); if ($this->checkToken($router)) throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); Wind::getApp()->processRequest(); } protected function checkToken($router, $check = true) { $token = $router->getModule() . '/' . $router->getController() . '/' . $router->getAction(); if ($check === false) { $this->token = $token; } else return !strcasecmp($token, $this->token); } } class WindErrorHandler extends WindController { protected $error = array(); protected $errorCode = 0; protected $urlReferer = ''; protected $errorDir = 'WIND:core.web.view'; public function beforeAction($handlerAdapter) { $this->error = $this->getInput('error'); $this->errorCode = (int) $this->getInput('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else $this->urlReferer = $this->getRequest()->getBaseUrl(); } public function run() { if ($this->errorCode >= 400 && $this->errorCode <= 505) { $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); $topic = "$this->errorCode - " . $_statusMsg; $this->getResponse()->setStatus($this->errorCode); } else $topic = "Error message"; $this->setOutput($topic, "errorHeader"); $this->setOutput($this->urlReferer, "baseUrl"); $this->setOutput($this->error, "errors"); $errDir = Wind::getApp()->getConfig('errorpage'); !$errDir && $errDir = $this->errorDir; $this->setTemplatePath($errDir); $this->setTemplate('erroraction'); } } class WindForward extends WindModule { protected $windView = null; private $vars = array('G' => array()); private $isReAction = false; private $isRedirect = false; private $url; private $action; private $controller; private $args; public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setController($controller); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function forwardAction($action, $args = array(), $isRedirect = false) { $this->setIsReAction(true); $this->setAction($action); $this->setArgs($args); $this->setIsRedirect($isRedirect); } public function setVars($vars, $key = '', $isG = false) { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) if ($isG) $this->vars['G'] = $vars; else $this->vars += $vars; } else { if ($isG) $this->vars['G'][$key] = $vars; else $this->vars[$key] = $vars; } } public function getIsRedirect() { return $this->isRedirect; } public function setIsRedirect($isRedirect) { $this->isRedirect = $isRedirect; } public function getIsReAction() { return $this->isReAction; } public function setIsReAction($isReAction) { $this->isReAction = $isReAction; } public function getVars() { return $this->vars; } public function getUrl() { return $this->url; } public function setUrl($url) { $this->url = $url; } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function getArgs() { return $this->args; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function setArgs($args) { $this->args = $args; } public function getWindView() { if ($this->windView === null) $this->_getWindView(); $module = Wind::getApp()->getModules(); isset($module['template-dir']) && $this->windView->templateDir = $module['template-dir']; isset($module['compile-dir']) && $this->windView->compileDir = $module['compile-dir']; return $this->windView; } public function setWindView($windView) { $this->windView = $windView; } } class WindSystemConfig extends WindModule { private $appName = ''; private $modules = array(); public function __construct($config, $appName, $factory) { $this->appName = $appName; $this->setConfig($config, $factory); } public function setConfig($config, $factory = null) { if (empty($config)) return; if (is_string($config)) { $configParser = $factory->getInstance('configParser'); $config = $configParser->parse($config); if (isset($config[$this->appName])) $this->_config = $config[$this->appName]; } else $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; } public function getAppName() { return $this->appName; } public function getAppClass($default = '') { return $this->getConfig('class', '', $default); } public function getCharset() { return $this->getConfig('charset', '', 'utf-8'); } public function getFilters() { return $this->getConfig('filters'); } public function getFilterClass() { return $this->getConfig('filters', 'class'); } public function getRouter() { return $this->getConfig('router'); } public function getRouterClass() { return $this->getConfig('router', 'class', COMPONENT_ROUTER); } public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } public function setModules($name, $config = array()) { if (!$_default = @$this->_config['modules']['default']) { $_default = $this->getDefaultConfigStruct('modules'); $this->_config['modules']['default'] = $_default; } if (!$config) $this->_config['modules'][$name] = $_default; else $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); return $this->_config['modules'][$name]; } public function getModuleTemplateDir($name, $default = '') { return $this->getConfig('template-dir', '', $default, $this->getModules($name)); } public function getModuleErrorHandler($name, $default = '') { return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); } public function getModuleControllerPath($name, $default = '') { return $this->getConfig('controller-path', '', $default, $this->getModules($name)); } public function getModuleControllerSuffix($name, $default = '') { return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); } public function getComponents($name = '', $default = array()) { return $this->getConfig('components', $name, $default); } public function getDbConfig($dbName = '') { $config = $this->getConfig('db'); if (isset($config['resource']) && !empty($config['resource'])) { $_resource = Wind::getRealPath($config['resource'], true); $this->_config['db'] = $this->parseConfig($_resource, 'db'); } return $this->getConfig('db', $dbName); } private function parseConfig($config, $key = 'config', $append = true) { if (!$config) return array(); $configParser = $this->getSystemConfig()->getInstance('configParser'); return $configParser->parse($config); } public function getDefaultConfigStruct($configName) { $_tmp = array(); $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', 'WIND:core.web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } class WindUrlHelper extends WindModule { public function createUrl($action, $controller = '', $params = array()) { $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); return $router->buildUrl($action, $controller, $params); } } Wind::import('COM:http.request.WindHttpRequest'); Wind::import('COM:http.response.WindHttpResponse'); class WindWebApplication extends WindModule implements IWindApplication { private $request; private $response; protected $windFactory = null; protected $dispatcher = null; protected $handlerAdapter = null; protected $defaultModule = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); public function __construct($config, $factory) { $this->request = new WindHttpRequest(); $this->response = $this->request->getResponse(@$config['charset']); $this->windFactory = $factory; $this->setConfig($config); } public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); $this->setModules('default', $this->defaultModule); $this->windFactory->loadClassDefinitions($this->getConfig('components')); $this->_getHandlerAdapter()->route(); $this->processRequest(); restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); Wind::resetApp(); } public function doDispatch($forward, $display = false) { if ($forward === null) return; $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); } public function processRequest() { try { if (!$this->handlerAdapter->getModule()) $this->handlerAdapter->setModule('default'); if (!($module = $this->getModules())) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', 404); $module = WindUtility::mergeArray($this->defaultModule, $module); $handlerPath = @$module['controller-path'] . '.' . ucfirst( $this->handlerAdapter->getController()) . @$module['controller-suffix']; if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'prototype', 'proxy' => true, 'config' => $this->getConfig('actionmap'), 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $this->resolveActionChain($handler); $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { $this->sendErrorMessage($e); } catch (WindException $e) { $this->sendErrorMessage($e); } } protected function resolveActionChain($__handler) { @extract(@$this->getRequest()->getRequest(), EXTR_REFS); $__filters = $__handler->resolveActionFilter($this->handlerAdapter->getAction()); foreach ((array) $__filters as $__filter) { if (isset($__filter['expression']) && !empty($__filter['expression'])) { if (!@eval('return ' . $__filter['expression'] . ';')) continue; } $__args = array($__handler->getForward(), $__handler->getErrorMessage()); if (isset($__filter['args'])) $__args = $__args + (array) $__filter['args']; $__handler->registerEventListener('doAction', WindFactory::createInstance(Wind::import(@$__filter['class']), $__args)); } } protected function sendErrorMessage($exception) { $moduleName = $this->handlerAdapter->getModule(); if ($moduleName === 'error') throw new WindFinalException($exception->getMessage()); $errorMessage = null; if ($exception instanceof WindActionException) $errorMessage = $exception->getError(); if (!$errorMessage) { $errorMessage = $this->windFactory->getInstance('errorMessage'); $errorMessage->addError($exception->getMessage()); } if (!$_errorAction = $errorMessage->getErrorAction()) { $module = $this->getModules($moduleName); if (empty($module)) $module = $this->setModules('default'); preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); } public function setModules($name, $config = array()) { if (!isset($this->_config['modules'][$name])) { $this->_config['modules'][$name] = (array) $config; } } public function getModules($name = '') { if ($name === '') return $this->getConfig('modules', $this->handlerAdapter->getModule()); return $this->getConfig('modules', $name, array()); } public function setConfig($config) { if (!$config) return; $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; $this->_config = $config; } public function registeComponent($componentName, $componentInstance, $scope) { return $this->windFactory->registInstance($componentInstance, $componentName); } public function getComponent($componentName) { $component = null; switch ($componentName) { case 'windCache': if ($this->getConfig('iscache', '', true)) $component = $this->windFactory->getInstance($componentName); break; default: $component = $this->windFactory->getInstance($componentName); break; } return $component; } public function getRequest() { return $this->request; } public function getResponse() { return $this->response; } public function getWindFactory() { return $this->windFactory; } } class WindEnableValidateModule extends WindModule { protected $_validatorClass = 'WIND:component.utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; private $_errors = array(); private $_defaultMessage = 'the field validate fail.'; public function getErrors() { return $this->_errors; } public function getErrorControllerAndAction() { return array($this->errorController, $this->errorAction); } protected function validateRules() { return array(); } public function validate(&$input) { if (is_array($input)) $this->validateArray($input); elseif (is_object($input)) $this->validateObject($input); } private function validateArray(&$input) { $rules = $this->validateRules(); foreach ((array) $rules as $rule) { $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $input[$rule['field']] = $rule['default']; } } private function validateObject(&$input) { $rules = $this->validateRules(); $methods = get_class_methods($input); foreach ((array) $rules as $rule) { $getMethod = 'get' . ucfirst($rule['field']); $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; $arg = (array) $rule['args']; array_unshift($arg, $_input); if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; if ($rule['default'] === null) { $this->_errors[$rule['field']] = $rule['message']; continue; } $setMethod = 'set' . ucfirst($rule['field']); in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), array($rule['default'])); } } protected function setValidator($validator) { $this->_validator = $validator; } protected function getValidator() { if ($this->_validator === null) { $_className = Wind::import($this->_validatorClass); $this->_validator = WindFactory::createInstance($_className); if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); } return $this->_validator; } } class WindErrorMessage extends WindModule implements IWindErrorMessage { private $error = array(); private $errorAction; public function __construct($message = '', $errorAction = '') { $message !== '' && $this->addError($message); $errorAction !== '' && $this->setErrorAction($errorAction); } public function sendError() { if (empty($this->error)) return; throw new WindActionException($this); } public function clearError() { $this->error = array(); } public function getError($key = '') { if ($key === '') return $this->error; return isset($this->error[$key]) ? $this->error[$key] : ''; } public function addError($error, $key = '') { if ($key === '') { if (is_string($error)) $this->error[] = $error; elseif (is_object($error)) $error = get_object_vars($error); if (is_array($error)) $this->error += $error; } else $this->error[$key] = $error; } public function getErrorAction() { return $this->errorAction; } public function setErrorAction($errorAction) { $this->errorAction = $errorAction; } } interface IWindErrorMessage { public function addError($message, $key = ''); public function getError($key = ''); public function clearError(); public function sendError(); } class WindHelper { const INTERNAL_LOCATION = "~Internal Location~"; protected static $errorDir = 'WIND:core.web.view'; protected static $errorPage = 'error.htm'; public static function errorHandle($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { restore_error_handler(); restore_exception_handler(); $trace = debug_backtrace(); unset($trace[0]["function"], $trace[0]["args"]); self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); } } public static function exceptionHandle($exception) { restore_error_handler(); restore_exception_handler(); $trace = $exception->getTrace(); if (@$trace[0]['file'] == '') { unset($trace[0]); $trace = array_values($trace); } $file = @$trace[0]['file']; $line = @$trace[0]['line']; self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); } protected static function crash($message, $file, $line, $trace, $status = 0) { $errmessage = substr($message, 0, 8000); $_headers = Wind::getApp()->getResponse()->getHeaders(); $_errhtml = false; foreach ($_headers as $_header) { if (strtolower($_header['name']) == strtolower('Content-type')) { $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; break; } } $msg = ''; if (WIND_DEBUG) { $_errorPage = 'error.htm'; $count = count($trace); $padLen = strlen($count); foreach ($trace as $key => $call) { if (!isset($call['file']) || $call['file'] == '') { $call['file'] = self::INTERNAL_LOCATION; $call['line'] = 'N/A'; } $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( $call); $trace[$key] = $traceLine; } $fileLines = array(); if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); $topLine = $currentLine - 5; $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); if (($count = count($fileLines)) > 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( "\t", " ", rtrim($fileLine)), null, "UTF-8"); } } $msg .= "$file\n" . implode("\n", $fileLines) . "\n" . implode("\n", $trace); } else $_errorPage = '404.htm'; if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; } else $topic = "Wind Framework - Error Caught"; $msg = "$topic\n$errmessage\n" . $msg . "\n\n" . self::errorInfo(); if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', true); if ($_errhtml) { ob_start(); $errDir = Wind::getApp()->getConfig('errorpage'); !$errDir && $errDir = self::$errorDir; if (isset($_statusMsg)) { header('HTTP/1.x ' . $status . ' ' . $_statusMsg); header('Status: ' . $status . ' ' . $_statusMsg); is_file(Wind::getRealPath($errDir) . '.' . $status . '.htm') && $_errorPage = $status . '.htm'; } require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, true); $msg = ob_get_clean(); } $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~/', $msg); die($msg); } private static function getCallLine($call) { $call_signature = ""; if (isset($call['file'])) $call_signature .= $call['file'] . " "; if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") "; if (isset($call['function'])) { $call_signature .= $call['function'] . "("; if (isset($call['args'])) { foreach ($call['args'] as $arg) { if (is_string($arg)) $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; else if (is_object($arg)) $arg = "[Instance of '" . get_class($arg) . "']"; else if ($arg === true) $arg = "true"; else if ($arg === false) $arg = "false"; else if ($arg === null) $arg = "null"; else $arg = strval($arg); $call_signature .= $arg . ','; } } $call_signature = trim($call_signature, ',') . ")"; } return $call_signature; } protected static function getErrorName($errorNumber) { $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } public static function errorInfo() { $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; return $info; } public static function resolveController($controllerPath) { $_m = $_c = ''; if (!$controllerPath) return array($_c, $_m); if (false !== ($pos = strrpos($controllerPath, '.'))) { $_m = substr($controllerPath, 0, $pos); $_c = substr($controllerPath, $pos + 1); } else { $_c = $controllerPath; } return array($_c, $_m); } } interface IWindConfigParser { public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); } Wind::import('COM:parser.IWindConfigParser'); class WindConfigParser implements IWindConfigParser { const CONFIG_XML = '.XML'; const CONFIG_PHP = '.PHP'; const CONFIG_INI = '.INI'; const CONFIG_PROPERTIES = '.PROPERTIES'; private $configParsers = array(); public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { if ($config = $this->getCache($alias, $append, $cache)) return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; } private function setCache($alias, $append, $cache, $data) { if (!$alias || !$cache) return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; $cache->set($append, $_config); } else { $cache->set($alias, $data); } } private function getCache($alias, $append, $cache) { if (!$alias || !$cache) return array(); if (!$append) return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); } private function createParser($type) { switch ($type) { case self::CONFIG_XML: Wind::import("WIND:component.parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: Wind::import("WIND:component.parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: Wind::import("WIND:component.parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: throw new WindException('\'ConfigParser\' failed to initialize.'); break; } } private function doParser($configFile) { if (!is_file($configFile)) throw new WindException( '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); if ($ext == self::CONFIG_PHP) return @include ($configFile); if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } class WindIniParser { protected $separator = '.'; public function parse($filename, $process = true, $build = true) { if (!is_file($filename)) { return array(); } $data = parse_ini_file($filename, $process); return $build ? $this->buildData($data) : $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } } class WindPropertiesParser { const COMMENT = '#'; const LPROCESS = '['; const RPROCESS = ']'; private $separator = '.'; public function __construct() { } public function parse($filename, $process = true, $build = true) { $data = $this->parse_properties_file($filename, $process); return $build ? $this->buildData($data) : $data; } private function delComment($filename, $process) { } public function parse_properties_file($filename, $process = true) { if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { return array(); } $fp = fopen($filename, 'r'); $content = fread($fp, filesize($filename)); fclose($fp); $content = explode("\n", $content); $data = array(); $last_process = $current_process = ''; foreach ($content as $key => $value) { $value = str_replace(array("\n", "\r"), '', trim($value)); if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { continue; } $tmp = explode('=', $value, 2); if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { if ($process) { $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); $data[$current_process] = array(); $last_process = $current_process; } continue; } $tmp[0] = trim($tmp[0]); $tmp[1] = trim($tmp[1], '\'"'); if ($last_process) { count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; } else { count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; } } return $data; } public function buildData(&$data) { foreach ((array)$data as $key => $value) { if (is_array($value)) { $data[$key] = $this->formatDataArray($value); } else { $this->formatDataFromString($key, $value, $data); } } return $data; } public function toArray($key, $value, &$data = array()) { if (empty($key) && empty($value)) return array(); if (strpos($key, $this->separator)) { $start = substr($key, 0, strpos($key, $this->separator)); $end = substr($key, strpos($key, $this->separator) + 1); $data[$start] = array(); $this->toArray($end, $value, $data[$start]); } else { $data[$key] = $value; } return $data; } public function formatDataArray(&$original, &$data = array()) { foreach ((array)$original as $key => $value) { $tmp = $this->toArray($key, $value); foreach ($tmp as $tkey => $tValue) { if (is_array($tValue)) { if (!isset($data[$tkey])) { $data[$tkey] = array(); } $this->formatDataArray($tValue, $data[$tkey]); } else { $data[$tkey] = $tValue; } } } return $data; } public function formatDataFromString($key, $value, &$data) { $tmp = $this->toArray($key, $value); if(false == strpos($key, $this->separator)){ return $tmp; } $start = substr($key, 0, strpos($key, $this->separator)); if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { $data[$start] = $tmp[$start]; } else { foreach ($data as $d_key => $d_value) { if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { continue; } foreach ($tmp[$d_key] as $a => $b) { $this->merge($a, $b, $data[$start]); } } } unset($data[$key]); return $data; } private function merge($key, $value, &$data = array()) { if (is_array($value)) { $v_key = array_keys($value); $c_key = $v_key[0]; if (is_array($value[$c_key])) { $this->merge($c_key, $value[$c_key], $data[$key]); } else { $data[$key][$c_key] = $value[$c_key]; } } else { $data[$key] = $value; } return $data; } private function trimChar($str, $char = ' ') { $char = is_array($char) ? $char : array($char); foreach ($char as $value) { $str = trim($str, $value); } return $str; } } class WindXmlParser { const NAME = 'name'; private $dom = null; public function __construct($version = '1.0', $encode = 'utf-8') { if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); $this->dom = new DOMDocument($version, $encode); } public function parse($filename, $option = null) { if (!is_file($filename)) return array(); $this->dom->load($filename, $option); return $this->getChilds($this->dom->documentElement); } public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); foreach ($node->childNodes as $node) { $tempChilds = $attributes = array(); ($node->hasAttributes()) && $attributes = $this->getAttributes($node); if (3 == $node->nodeType) { $value = trim($node->nodeValue); (is_numeric($value) || $value) && $childs[0] = $value; } if (1 !== $node->nodeType) continue; $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; if (!isset($childs[$nodeName])) { $childs[$nodeName] = $tempChilds; continue; } else { $element = $childs[$nodeName]; $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); continue; } } return $childs; } public function getAttributes($node) { if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); $attributes = array(); foreach ($node->attributes as $attribute) { if (self::NAME != $attribute->nodeName) { $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; } } return $attributes; } } abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; protected $module; protected $controller = 'index'; protected $action = 'run'; protected $currentRoute = null; abstract public function route(); abstract public function assemble(); public function setConfig($config) { parent::setConfig($config); if ($this->_config) { $this->module = $this->getConfig('module', 'default-value', $this->module); $this->controller = $this->getConfig('controller', 'default-value', $this->controller); $this->action = $this->getConfig('action', 'default-value', $this->action); $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); } } protected function setParams($params) { foreach ($params as $key => $value) { if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); else { $this->getRequest()->setAttribute($value, $key); } } } public function addRoute($routeInstance, $current = false) { if ($current) $this->currentRoute = $routeInstance; $this->addInterceptors($routeInstance); } public function getAction() { return $this->action; } public function getController() { return $this->controller; } public function setAction($action) { $this->action = $action; } public function setController($controller) { $this->controller = $controller; } public function getModule() { return $this->module; } public function setModule($module) { $this->module = $module; } public function getModuleKey() { return $this->moduleKey; } public function getControllerKey() { return $this->controllerKey; } public function getActionKey() { return $this->actionKey; } public function setModuleKey($moduleKey) { $this->moduleKey = $moduleKey; } public function setControllerKey($controllerKey) { $this->controllerKey = $controllerKey; } public function setActionKey($actionKey) { $this->actionKey = $actionKey; } } abstract class AbstractWindRoute extends WindModule { abstract public function build(); abstract public function match(); public function handle() { $args = func_get_args(); $this->result = call_user_func_array(array($this, 'match'), $args); if ($this->result !== null) { return $this->result; } if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { $this->result = $this->interceptorChain->execute(); } return $this->result; } } Wind::import('COM:router.route.AbstractWindRoute'); class WindRewriteRoute extends AbstractWindRoute { public function build() { } public function match() { } } class WindRoute extends AbstractWindRoute { protected $params = array(); protected $pattern; protected $reverse; public function match() { } public function build() { } public function setConfig($config) { parent::setConfig($config); $this->setParams($this->getConfig('params')); $this->setPattern($this->getConfig('pattern')); $this->setReverse($this->getConfig('reverse')); } } Wind::import('COM:router.AbstractWindRouter'); class WindRouter extends AbstractWindRouter { public function route() { $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } public function assemble() { } public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } } Wind::import('COM:router.AbstractWindRouter'); class WindUrlRewriteRouter extends AbstractWindRouter { private $urlPatttern = ''; private $keyValueSep = ''; private $separator = ''; private $suffix = ''; private $isRewrite = 0; private $keyPrefix = ''; private $baseUrl = ''; private $patterns = array(); public function isRewrite() { return $this->isRewrite == '1' || $this->isRewrite == 'true'; } public function parse() { $this->isRewrite() && $this->parseUrl(); $this->setModule($this->getUrlParamValue('module', $this->getModule())); $this->setController($this->getUrlParamValue('controller', $this->getController())); $this->setAction($this->getUrlParamValue('action', $this->getAction())); } public function parseUrl() { if (!$this->isRewrite()) return; $url = array(); if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { $pathInfo = $this->getRequest()->getServer('PATH_INFO'); if ($pathInfo && !empty($pathInfo)) { $url = rtrim($pathInfo, $this->suffix); } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { $scriptName = $this->getRequest()->getScriptUrl(); if (0 === strpos($url, $scriptName)) { $url = substr($url, strlen($scriptName)); } $url = rtrim($url, $this->suffix); } $url = trim($url, '?/'); $url && $params = $this->doParserUrl($url); } else { $i = 0; $args = $this->getRequest()->getServer('argv', array()); while (isset($args[$i]) && isset($args[$i + 1])) { $params[$args[$i]] = $args[$i + 1]; $i += 2; } } foreach ($params as $k => $v) { !isset($_GET[$k]) && $_GET[$k] = $v; } } public function buildUrl($action = '', $controller = '', $params = array()) { list($module, $controller, $action) = $this->resolveMvc($action, $controller); $m = $this->getConfig('module', 'url-param'); $c = $this->getConfig('controller', 'url-param'); $a = $this->getConfig('action', 'url-param'); $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( $params, '', '&'); } private function resolveMvc($action, $controller) { list($controller, $module) = WindHelper::resolveController($controller); !$module && $module = $this->getConfig('module', 'default-value'); !$controller && $controller = $this->getConfig('controller', 'default-value'); !$action && $action = $this->getConfig('action', 'default-value'); return array($module, $controller, $action); } private function buildRewriteUrl($params) { $url = $this->urlPatttern; foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) { $url = str_replace($value, $this->buildNomalKeys($params), $url); } else { $url = $this->buildVars($value, $params, $url); } } return $this->baseUrl . '/' . $url . $this->suffix; } private function buildVars($value, &$params, $url) { $keys = explode($this->keyValueSep, $value); $values = array(); foreach ($keys as $v) { if (!isset($params[$v])) continue; $values[] = $params[$v]; unset($params[$v]); } return str_replace($keys, $values, $url); } private function buildNomalKeys($params, $parentKey = '', $first = true) { $tmp = array(); foreach ($params as $k => $v) { if (is_int($k) && $this->keyPrefix != null && $first) { $k = urlencode($this->keyPrefix . $k); } if (!empty($parentKey)) $k = $parentKey . '[' . $k . ']'; if (is_array($v)) { array_push($tmp, $this->buildNomalKeys($v, $k, false)); } else { array_push($tmp, $k . $this->keyValueSep . urlencode($v)); } } return implode($this->separator, $tmp); } private function doParserUrl($url) { if (!$url) return array(); if (is_string($url)) { $url = explode($this->separator, trim($url, $this->separator)); } $vars = array(); foreach ($this->patterns as $key => $value) { if ('*' == $value[0]) $this->parseNomalKeys($key, $url, $vars); else { if (!isset($url[$key])) continue; if (false === strrpos($value, $this->keyValueSep)) { $vars[$value] = $url[$key]; continue; } $keys = explode($this->keyValueSep, $value); $values = explode($this->keyValueSep, $url[$key]); foreach ($keys as $pos => $key) { isset($values[$pos]) && $vars[$key] = $values[$pos]; } } } return $vars; } private function parseNomalKeys($key, $urlParams, &$params) { $pos = 0; while (isset($urlParams[$key])) { if ($this->separator == $this->keyValueSep) { if (isset($urlParams[$key + 1])) { $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); $key += 2; } continue; } if (false === strrpos($urlParams[$key], $this->keyValueSep)) { $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); $pos++; } else { list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); $this->parseKey($params, $k, urldecode($v)); } $key += 1; } } private function parseKey(&$params, $key, $value) { if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { $params[$key] = $value; return; } $name = substr($key, 0, $pos); if ($pos2 === $pos + 1) { $params[$name][] = $value; return; } else { $key = substr($key, $pos + 1, $pos2 - $pos - 1); $params[$name][$key] = $value; return; } } public function setConfig($config) { $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); $usrConfig && $config = array_merge($config, $usrConfig); parent::setConfig($config); $this->urlPatttern = $this->getConfig('url-pattern'); $this->separator = $this->getConfig('separator'); $this->keyValueSep = $this->getConfig('key-value-sep'); $this->keyValueSep == "" && $this->keyValueSep = $this->separator; $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); $this->isRewrite = $this->getConfig('is-rewrite'); $this->keyPrefix = $this->getConfig('key-prefix'); $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); if (!$this->isRewrite()) $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); } private function getUrlParamValue($type, $defaultValue = '') { if ($_param = $this->getConfig($type, 'url-param')) { $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); $tmp = $this->getRequest()->getRequest($_param, $defaultValue); return !$tmp ? $defaultValue : $tmp; } return $defaultValue; } public function route() { } public function assemble() { } } class WindCookie{ public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ if(empty($name)){ return false; } $name = $prefix ? $prefix.$name : $name; $value = $serialize ? serialize($value) : $value; $value = $encode ? base64_encode($value) : $value; $path = $path ? $path : '/'; $expires = is_int($expires) ? time()+$expires : strtotime($expires); setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); return true; } public static function remove($name,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ self::set($name,'',time()-3600); unset($_COOKIE[$name]); } return true; } public static function get($name,$encode = false,$serialize = false,$prefix=null){ $name = $prefix ? $prefix.$name : $name; if(self::exist($name)){ $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; $value = $encode ? base64_decode($value):$value; return $serialize ? unserialize($value) : $value; } return false; } public static function removeAll(){ $_COOKIE = array(); } public static function exist($name,$prefix=null){ return isset($_COOKIE[$prefix ? $prefix.$name : $name]); } } class WindCookieObject{ public $prefix; protected $name; protected $value; protected $expires; protected $domain; protected $path; protected $secure; protected $encode; protected $httponly; public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ $this->name = (string) $name; $this->value = (string) $value; $this->domain = (string) $domain; $this->expires = (null === $expires ? null : (int) $expires); $this->path = ($path ? $path : '/'); $this->secure = $secure; $this->httponly = $httponly; $this->prefix = (string)$prefix; $this->encode = $encode; } public function getName(){ return $this->prefix ? $this->prefix.$this->name : $this->prefix; } public function getValue(){ return $this->value; } public function getDomain(){ return $this->domain; } public function getPath(){ return $this->path; } public function getExpirs(){ return $this->expires; } public function isSecure(){ return $this->secure; } public function isExpired($now = null){ return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; } public function isSessionCookie(){ return null === $this->expires; } public function __toString(){ return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; } public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ $cookie = explode(';',$cookiestr); list($name,$value) = explode('=',array_shift($cookie)); if(empty($name)){ return null; } $domain=$expires =$path = null; $httponly = $secure = false; foreach($cookie as $_cookie){ list($key,$_value) = explode('=',$_cookie); switch($key){ case 'domain':$domain=$_value;break; case 'path':$path=$_value;break; case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; case 'httponly':$httponly=(bool)$_value;break; case 'secure':$secure=(bool)$_value;break; } } return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); } } interface IWindRequest { const INPUT_TYPE_GET = 'get'; const INPUT_TYPE_POST = 'post'; const INPUT_TYPE_COOKIE = 'cookie'; } Wind::import('COM:http.request.IWindRequest'); class WindHttpRequest implements IWindRequest { private $_port = null; private $_clientIp = null; private $_language = null; private $_pathInfo = null; private $_scriptUrl = null; private $_requestUri = null; private $_baseUrl = null; private $_hostInfo = null; private $_attribute = array(); private $_response = null; public function __construct() { $this->normalizeRequest(); } protected function normalizeRequest() { if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { if (isset($_GET)) $_GET = $this->stripSlashes($_GET); if (isset($_POST)) $_POST = $this->stripSlashes($_POST); if (isset($_REQUEST)) $_REQUEST = $this->stripSlashes($_REQUEST); if (isset($_COOKIE)) $_COOKIE = $this->stripSlashes($_COOKIE); } } public function stripSlashes(&$data) { return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( $data); } public function setAttribute($data, $key = '') { if ($key) { $this->_attribute[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data); } public function getAttribute($key, $defaultValue = '') { if (isset($this->_attribute[$key])) return $this->_attribute[$key]; else if (isset($_GET[$key])) return $_GET[$key]; else if (isset($_POST[$key])) return $_POST[$key]; else if (isset($_COOKIE[$key])) return $_COOKIE[$key]; else if (isset($_REQUEST[$key])) return $_REQUEST[$key]; else if (isset($_ENV[$key])) return $_ENV[$key]; else if (isset($_SERVER[$key])) return $_SERVER[$key]; else return $defaultValue; } public function getRequest($key = null, $defaultValue = null) { if (!$key) return array_merge($_POST, $_GET); if (isset($_GET[$key])) return $_GET[$key]; if (isset($_POST[$key])) return $_POST[$key]; return $defaultValue; } public function getQuery($name = null, $defaultValue = null) { return $this->getGet($name, $defaultValue); } public function getPost($name = null, $defaultValue = null) { if ($name == null) return $_POST; return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; } public function getGet($name = '', $defaultValue = null) { if ($name == null) return $_GET; return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; } public function getCookie($name = null, $defaultValue = null) { if ($name == null) return $_COOKIE; return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; } public function getSession($name = null, $defaultValue = null) { if ($name == null) return $_SESSION; return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; } public function getServer($name = null, $defaultValue = null) { if ($name == null) return $_SERVER; return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; } public function getEnv($name = null, $defaultValue = null) { if ($name == null) return $_ENV; return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; } public function getScheme() { return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; } public function getProtocol() { return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); } public function getClientIp() { if (!$this->_clientIp) $this->_getClientIp(); return $this->_clientIp; } public function getRequestMethod() { return strtoupper($this->getServer('REQUEST_METHOD')); } public function getRequestType() { return IWindRequest::REQUEST_TYPE_WEB; } public function getIsAjaxRequest() { return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); } public function isSecure() { return !strcasecmp($this->getServer('HTTPS'), 'on'); } public function isGet() { return !strcasecmp($this->getRequestMethod(), 'GET'); } public function isPost() { return !strcasecmp($this->getRequestMethod(), 'POST'); } public function isPut() { return !strcasecmp($this->getRequestMethod(), 'PUT'); } public function isDelete() { return !strcasecmp($this->getRequestMethod(), 'Delete'); } public function getRequestUri() { if (!$this->_requestUri) $this->_initRequestUri(); return $this->_requestUri; } public function getScriptUrl() { if (!$this->_scriptUrl) $this->_initScriptUrl(); return $this->_scriptUrl; } public function getScript() { if (($pos = strrpos($this->getScriptUrl(), '/')) === false) $pos = -1; return substr($this->getScriptUrl(), $pos + 1); } public function getHeader($header, $default = null) { $temp = strtoupper(str_replace('-', '_', $header)); if (substr($temp, 0, 5) != 'HTTP_') $temp = 'HTTP_' . $temp; if (($header = $this->getServer($temp)) != null) return $header; if (function_exists('apache_request_headers')) { $headers = apache_request_headers(); if ($headers[$header]) return $headers[$header]; } return $default; } public function getPathInfo() { if (!$this->_pathInfo) $this->_initPathInfo(); return $this->_pathInfo; } public function getBaseUrl($absolute = false) { if ($this->_baseUrl === null) $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; } public function getHostInfo() { if ($this->_hostInfo === null) $this->_initHostInfo(); return $this->_hostInfo; } public function getServerName() { return $this->getServer('SERVER_NAME', ''); } public function getServerPort() { if (!$this->_port) { $_default = $this->isSecure() ? 443 : 80; $this->setServerPort($this->getServer('SERVER_PORT', $_default)); } return $this->_port; } public function setServerPort($port) { $this->_port = (int) $port; } public function getRemoteHost() { return $this->getServer('REMOTE_HOST'); } public function getUrlReferer() { return $this->getServer('HTTP_REFERER'); } public function getRemotePort() { return $this->getServer('REMOTE_PORT'); } public function getUserAgent() { return $this->getServer('HTTP_USER_AGENT', ''); } public function getAcceptTypes() { return $this->getServer('HTTP_ACCEPT', ''); } public function getAcceptCharset() { return $this->getServer('HTTP_ACCEPT_ENCODING', ''); } public function getAcceptLanguage() { if (!$this->_language) { $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; } return $this->_language; } public function getResponse($charset) { $response = new WindHttpResponse(); !$charset && $charset = 'utf-8'; $response->setHeader('Content-type', 'text/html;charset=' . $charset); $response->setCharset($charset); return $response; } private function _getClientIp() { if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { $this->_clientIp = $ip; } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { $ip = strtok($_ip, ','); do { $ip = ip2long($ip); if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { $this->_clientIp = long2ip($ip); return; } } while (($ip = strtok(','))); } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { $this->_clientIp = $ip; } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { $this->_clientIp = $ip; } else { $this->_clientIp = "0.0.0.0"; } } private function _initRequestUri() { if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { $this->_requestUri = $requestUri; } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { $this->_requestUri = $requestUri; if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { $this->_requestUri = $requestUri; if (($query = $this->getServer('QUERY_STRING')) != null) $this->_requestUri .= '?' . $query; } else throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); } private function _initScriptUrl() { if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); $scriptName = basename($scriptName); if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( $_scriptName) === $scriptName) { $this->_scriptUrl = $_scriptName; } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { $this->_scriptUrl = str_replace('\\', '/', str_replace($_documentRoot, '', $_scriptName)); } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initHostInfo() { $http = $this->isSecure() ? 'https' : 'http'; if (($httpHost = $this->getServer('HTTP_HOST')) != null) $this->_hostInfo = $http . '://' . $httpHost; elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { $this->_hostInfo = $http . '://' . $httpHost; if (($port = $this->getServerPort()) != null) $this->_hostInfo .= ':' . $port; } else throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); } private function _initPathInfo() { $requestUri = urldecode($this->getRequestUri()); $scriptUrl = $this->getScriptUrl(); $baseUrl = $this->getBaseUrl(); if (strpos($requestUri, $scriptUrl) === 0) $pathInfo = substr($requestUri, strlen($scriptUrl)); elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) $pathInfo = substr($requestUri, strlen($baseUrl)); elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); else throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); if (($pos = strpos($pathInfo, '?')) !== false) $pathInfo = substr($pathInfo, $pos + 1); $this->_pathInfo = trim($pathInfo, '/'); } } interface IWindResponse { } Wind::import('COM:http.response.IWindResponse'); class WindHttpResponse implements IWindResponse { private $_body = array(); private $_bodyIndex = array(); private $_charset = 'utf-8'; private $_headers = array(); private $_isRedirect = false; private $_status = ''; private $_data = array('G' => array()); const W_CONTINUE = 100; const W_SWITCHING_PROTOCOLS = 101; const W_OK = 200; const W_CREATED = 201; const W_ACCEPTED = 202; const W_NON_AUTHORITATIVE_INFORMATION = 203; const W_NO_CONTENT = 204; const W_RESET_CONTENT = 205; const W_PARTIAL_CONTENT = 206; const W_MULTIPLE_CHOICES = 300; const W_MOVED_PERMANENTLY = 301; const W_MOVED_TEMPORARILY = 302; const W_FOUND = 302; const W_SEE_OTHER = 303; const W_NOT_MODIFIED = 304; const W_USE_PROXY = 305; const W_TEMPORARY_REDIRECT = 307; const W_BAD_REQUEST = 400; const W_UNAUTHORIZED = 401; const W_PAYMENT_REQUIRED = 402; const W_FORBIDDEN = 403; const W_NOT_FOUND = 404; const W_METHOD_NOT_ALLOWED = 405; const W_NOT_ACCEPTABLE = 406; const W_PROXY_AUTHENTICATION_REQUIRED = 407; const W_REQUEST_TIMEOUT = 408; const W_CONFLICT = 409; const W_GONE = 410; const W_LENGTH_REQUIRED = 411; const W_PRECONDITION_FAILED = 412; const W_REQUEST_ENTITY_TOO_LARGE = 413; const W_REQUEST_URI_TOO_LONG = 414; const W_UNSUPPORTED_MEDIA_TYPE = 415; const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; const W_EXPECTATION_FAILED = 417; const W_INTERNAL_SERVER_ERROR = 500; const W_NOT_IMPLEMENTED = 501; const W_BAD_GATEWAY = 502; const W_SERVICE_UNAVAILABLE = 503; const W_GATEWAY_TIMEOUT = 504; const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; } public function setHeader($name, $value, $replace = false) { if (!$name || !$value) return; $name = $this->_normalizeHeader($name); $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } } if ($setted === false) $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function addHeader($name, $value, $replace = false) { if ($name == '' || $value == '') return; $name = $this->_normalizeHeader($name); $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); } public function getCharset() { return $this->_charset; } public function setCharset($_charset) { $this->_charset = $_charset; } public function setStatus($status, $message = '') { $status = intval($status); if ($status < 100 || $status > 505) return; $this->_status = (int) $status; } public function setBody($content, $name = null) { if (!$content) return; !$name && $name = 'default'; array_push($this->_bodyIndex, $name); $this->_body[$name] = $content; } public function addCookie(Cookie $cookie) { } public function sendError($status = self::W_NOT_FOUND, $message = '') { if (!is_int($status) || $status < 400 || $status > 505) return; $this->setBody($message, 'error'); $this->setStatus($status); $this->sendResponse(); } public function sendRedirect($location, $status = 302) { if (!is_int($status) || $status < 300 || $status > 399) return; $this->addHeader('Location', $location, true); $this->setStatus($status); $this->_isRedirect = true; $this->sendHeaders(); exit(); } public function sendResponse() { $this->sendHeaders(); $this->sendBody(); } public function sendHeaders() { if ($this->isSendedHeader()) return; foreach ($this->_headers as $header) { header($header['name'] . ': ' . $header['value'], $header['replace']); } if ($this->_status) { header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); } } public function sendBody() { foreach ($this->_bodyIndex as $key) echo $this->_body[$key]; } public function getBody($name = false) { if ($name === false) { ob_start(); $this->sendBody(); return ob_get_clean(); } elseif ($name === true) { return $this->_body; } elseif (is_string($name) && isset($this->_body[$name])) return $this->_body[$name]; return null; } public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) throw new WindException( __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } public function getHeaders() { return $this->_headers; } public function clearBody() { $this->_body = array(); } public function clearHeaders() { $this->_headers = array(); } private function _normalizeHeader($name) { $filtered = str_replace(array('-', '_'), ' ', (string) $name); $filtered = ucwords(strtolower($filtered)); $filtered = str_replace(' ', '-', $filtered); return $filtered; } public function getData($key1 = '', $key2 = '') { if (!$key1) return $this->_data; if (!$key2) return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; } public function setData($data, $key = '', $isG = false) { if ($key) { if ($isG) $this->_data['G'][$key] = $data; else $this->_data[$key] = $data; return; } if (is_object($data)) $data = get_object_vars($data); if (is_array($data)) { if ($isG) $this->_data['G'] += $data; else $this->_data += $data; } } } abstract class AbstractWindUserSession { public static abstract function open($savePath, $sessionName); public static abstract function close(); public static abstract function write($name,$value); public static abstract function read($name); public static abstract function gc($maxlifetime); public static abstract function destroy($name); public static function callUserSessionHandler(){ $className = get_class($this); session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); } } Wind::import('WIND:component.http.session.AbstractWindUserSession'); class WindDbSession extends AbstractWindUserSession { public static function open($savePath, $sessionName){ return true; } public static function close(){ return true; } public static function write($name,$value){ } public static function read($name){ } public static function gc($maxlifetime){ } public static function destroy($name){ } } class WindSession implements IteratorAggregate, ArrayAccess, Countable { public $autostart = false; const COOKIE_MODE_NONE = 1; const COOKIE_MODE_ONLY = 2; const COOKIE_MODE_ALLOW = 3; const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_USER = 'user'; public static $read = array(); public static $write = array(); public function __construct($autostart = false) { $this->autostart = $autostart; } public function start() { if (!$this->isStart() && !$this->getAutoStart()) { $this->autostart ? $this->setAutoStart(1) : session_start(); } } public function isStart() { return '' !== $this->getSessionId(); } public function close() { if ($this->isStart()) { session_write_close(); } } public function get($name) { return isset($_SESSION[$name]) ? $_SESSION[$name] : null; } public function set($name, $value) { if (empty($name) && empty($value)) { return false; } $_SESSION[$name] = $value; return true; } public function remove($name) { if (isset($_SESSION[$name])) { $sessionValue = $_SESSION[$name]; unset($_SESSION[$name]); return $sessionValue; } return null; } public function exist($name) { return isset($_SESSION[$name]); } public function destroy() { if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { setcookie($name, '', time() - 3600); } session_unset(); session_destroy(); return true; } public function getSessionName() { return session_name(); } public function setSessionName($name) { return session_name($name); } public function getSessionId() { return session_id(); } public function setSessionId($id) { return session_id($id); } public function getSavePath() { return session_save_path(); } public function setSavePath($path) { if (is_dir($path)) { session_save_path($path); return true; } return false; } public function getSessionSaveMode() { return session_module_name(); } public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { return session_module_name($mode); } public function getCookieParams() { return session_get_cookie_params(); } public function setCookieParams($cookie = array()) { extract($this->getCookieParams()); extract($cookie); if (isset($httponly)) { session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); } else { session_set_cookie_params($lifetime, $path, $domain, $secure); } return true; } public function getCookieMode() { if ('0' === ini_get('session.use_cookies')) { self::COOKIE_MODE_NONE; } else if ('0' === ini_get('session.use_only_cookies')) { return self::COOKIE_MODE_ALLOW; } else { return self::COOKIE_MODE_ONLY; } return false; } public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { if (self::COOKIE_MODE_NONE === $mode) { ini_set('session.use_cookies', '0'); } else if (self::COOKIE_MODE_ALLOW === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '0'); } else if (self::COOKIE_MODE_ONLY === $mode) { ini_set('session.use_cookies', '1'); ini_set('session.use_only_cookies', '1'); } else { return false; } return true; } public function getGCProbability() { return (int) ini_get('session.gc_probability'); } public function setGCProbability($probability) { if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { return false; } ini_set('session.gc_probability', $probability); ini_set('session.gc_divisor', '100'); return true; } public function getTransSessionID() { return '1' === ini_get('session.use_trans_sid'); } public function setTransSessionID($ifTrans = 0) { return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); } public function getSessionLifeTime() { return (int) ini_get('session.gc_maxlifetime'); } public function setSessionLifeTime($time = 0) { return (int) ini_set('session.gc_maxlifetime', (int) $time); } public function getAutoStart() { return '1' === ini_get('session.auto_start'); } public function setAutoStart($autostart) { return ini_set('session.auto_start', $autostart ? '1' : '0'); } public function getCurrentSessionFileName(){ return $this->getSavePath().'/sess_'.$this->getSessionId(); } public function offsetExists($offset) { $this->exist($offset); } public function offsetSet($offset, $value) { $this->set($offset, $value); } public function offsetGet($offset) { $this->get($offset); } public function offsetUnset($offset) { $this->remove($offset); } public function getIterator($name = null) { return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); } public function count() { return count($_SESSION); } } abstract class AbstractWindHttp { protected static $instance = null; protected $httpResource = null; protected $cookie = array(); protected $header = array(); protected $url = ''; protected $data = array(); protected $err = ''; protected $eno = 0; protected $timeout = 0; const _COOKIE = 'cookie'; const _HEADER = 'header'; const _DATA = 'data'; const GET = 'GET'; const POST = 'POST'; protected function __construct($url = '', $timeout = 5) { $this->url = $url; $this->timeout = $timeout; } public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); public abstract function send($method = self::GET, $options = array()); public abstract function open(); public abstract function request($key, $value = null); public abstract function requestByArray($request = array()); public abstract function response(); public abstract function resonseLine(); public abstract function close(); public abstract function getError(); public static abstract function getInstance($url = ''); protected function __clone() {} public function setUrl($url) { $url && $this->url = $url; } public function setHeader($key, $value) { $this->header[$key] = $value; } public function setHeaders($headers = array()) { return $this->setPropertityValue(self::_HEADER, $headers); } public function setCookie($key, $value) { $this->cookie[$key] = $value; } public function setCookies($cookies = array()) { return $this->setPropertityValue(self::_COOKIE, $cookies); } public function setData($key, $value) { $this->data[$key] = $value; } public function setDatas($datas = array()) { return $this->setPropertityValue(self::_DATA, $datas); } public function clear() { $this->url = array(); $this->header = array(); $this->cookie = array(); $this->data = array(); } public static function buildQuery($query, $sep = '&') { if (!is_array($query)) { return ''; } $_query = ''; foreach ($query as $key => $value) { $tmp = rawurlencode($key) . '=' . rawurlencode($value); $_query .= $_query ? $sep . $tmp : $tmp; } return $_query; } public static function buildArray($array, $sep = ':') { if (!is_array($array)) { return array(); } $_array = array(); foreach ($array as $key => $value) { $_array[] = $key . $sep . $value; } return $_array; } private function setPropertityValue($propertity, $value = array()) { if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { return false; } if (!is_array($value)) { return false; } if (empty($this->$propertity)) { $this->$propertity = $value; } else { foreach ($value as $key => $_value) { $this->$propertity[$key] = $_value; } } return true; } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpCurl extends AbstractWindHttp { protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $this->httpResource = curl_init(); } return $this->httpResource; } public function request($name, $value = null) { return curl_setopt($this->httpResource, $name, $value); } public function requestByArray($opt = array()) { return curl_setopt_array($this->httpResource, $opt); } public function response() { return curl_exec($this->httpResource); } public function resonseLine(){ return ''; } public function close() { if ($this->httpResource) { curl_close($this->httpResource); $this->httpResource = null; } } public function getError() { $this->err = curl_error($this->httpResource); $this->eno = curl_errno($this->httpResource); return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (null === $this->httpResource) { $this->open(); } $this->request(CURLOPT_HEADER, 0); $this->request(CURLOPT_FOLLOWLOCATION, 1); $this->request(CURLOPT_RETURNTRANSFER, 1); $this->request(CURLOPT_TIMEOUT, $this->timeout); if ($options && is_array($options)) { $this->requestByArray($options); } if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $url = parse_url($this->url); $sep = isset($url['query']) ? '&' : '?'; $this->url .= $sep . $get; } if (self::POST === $method && $this->data) { $this->request(CURLOPT_POST, 1); $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); } if ($this->cookie && $this->cookie) { $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); } if (empty($this->header)) { $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); } $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); $this->request(CURLOPT_URL, $this->url); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpSocket extends AbstractWindHttp { private $host = ''; private $port = 0; private $path = ''; private $query = ''; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); } public function open() { if (null === $this->httpResource) { $url = parse_url($this->url); $this->host = $url['host']; $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; $this->path .= $url['query'] ? '?' . $url['query'] : ''; $this->query = $url['query']; $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); } return $this->httpResource; } public function request($name, $value = null) { return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); } public function requestByArray($request = array()) { $_request = ''; foreach ($request as $key => $value) { if (is_string($key)) { $_request .= $key . ': ' . $value; } if (is_int($key)) { $_request .= $value; } $_request .= "\n"; } fputs($this->httpResource, $_request); } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { if (self::GET === $method && $this->data) { $url = parse_url($this->url); $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } $this->open(); $this->setHeader("Host", $this->host); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie && $this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } if ($options) { $this->setHeaders($options); } $this->setHeader('Connection', 'Close'); $this->request($method . " " . $this->path . " HTTP/1.1"); $this->requestByArray($this->header); if ($data) { $this->request("\n" . $data); } $this->request("\n"); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } Wind::import('WIND:component.http.transfer.AbstractWindHttp'); final class WindHttpStream extends AbstractWindHttp { const HTTP = 'http'; const HTTPS = 'https'; const FTP = 'ftp'; const FTPS = 'ftp'; const SOCKET = 'socket'; private $context = null; private $wrapper = self::HTTP; protected function __construct($url = '', $timeout = 5) { parent::__construct($url, $timeout); $this->context = stream_context_create(); } public function setWrapper($wrapper = self::HTTP) { $this->wrapper = $wrapper; } public function open() { if (null === $this->httpResource) { $this->httpResource = fopen($this->url, 'r', false, $this->context); } return $this->httpResource; } public function request($name, $value = null) { return stream_context_set_option($this->context, $this->wrapper, $name, $value); } public function requestByArray($opt = array()) { foreach ($opt as $key => $value) { if (false === $this->request($key, $value)) { return false; } } return true; } public function response() { $response = ''; while (!feof($this->httpResource)) { $response .= fgets($this->httpResource); } return $response; } public function resonseLine(){ return feof($this->httpResource) ? '' : fgets($this->httpResource); } public function close() { if ($this->httpResource) { fclose($this->httpResource); $this->httpResource = null; $this->context = null; } } public function getError() { return $this->err ? $this->eno . ':' . $this->err : ''; } public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::POST, $option); } public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { $url && $this->setUrl($url); $header && is_array($header) && $this->setHeaders($header); $cookie && is_array($cookie) && $this->setCookies($cookie); $data && is_array($data) && $this->setDatas($data); return $this->send(self::GET, $option); } public function send($method = self::GET, $options = array()) { $url = parse_url($this->url); if (self::GET === $method && $this->data) { $get = self::buildQuery($this->data, '&'); $this->url .= ($url['query'] ? '&' : '?') . $get; } if (self::POST === $method && $this->data) { $data = self::buildQuery($this->data, '&'); $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); $this->setHeader('Content-Length', strlen($data)); } $this->setHeader("Host", $url['host']); $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); if ($this->cookie) { $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); } $this->setHeader('Connection', 'Close'); $this->request('method', $method); $this->request('timeout', $this->timeout); if ($this->header) { $header = ''; foreach ($this->header as $key => $value) { $header .= $key . ': ' . $value . "\n"; } $this->request('header', $header); } $data && $this->request('content', $data); $options && is_array($options) && $this->requestByArray($options); $this->open(); return $this->response(); } public static function getInstance($url = '') { if (null === self::$instance || false === (self::$instance instanceof self)) { self::$instance = new self($url); } return self::$instance; } public function __destruct() { $this->close(); } } class WindDate { public static function getTimeZone() { return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); } public static function setTimezone($timezone) { function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); } public static function format($format = null, $dateTime = null) { return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); } public static function datePart($interval, $dateTime = null) { return date($interval, self::getTimeStamp($dateTime)); } public static function dateDiff($interval, $startDateTime, $endDateTime) { $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); $retval = 0; switch ($interval) { case "y": $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; case "m": $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; case "w": $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; case "d": $retval = bcdiv($diff, (60 * 60 * 24));break; case "h": $retval = bcdiv($diff, (60 * 60));break; case "n": $retval = bcdiv($diff, 60);break; case "s": default:$retval = $diff;break; } return $retval; } public static function dateAdd($interval, $value, $dateTime, $format = null) { $date = getdate(self::getTimeStamp($dateTime)); switch ($interval) { case "y": $date["year"] += $value;break; case "q": $date["mon"] += ($value * 3);break; case "m": $date["mon"] += $value;break; case "w": $date["mday"] += ($value * 7);break; case "d": $date["mday"] += $value;break; case "h": $date["hours"] += $value;break; case "n": $date["minutes"] += $value;break; case "s": default:$date["seconds"] += $value;break; } return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); } public static function getRealDaysInMonthsOfYear($year) { $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); if (self::isLeapYear($year)) { $months[1] = 29; } return $months; } public static function getDaysInMonth($month, $year) { if (1 > $month || 12 < $month) { return 0; } if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { return 0; } return $daysInmonths[$month - 1]; } public static function getDaysInYear($year) { return self::isLeapYear($year) ? 366 : 365; } public static function getRFCDate($date = null) { $time = $date ? is_int($date) ? $date : strtotime($date) : time(); $tz = date('Z', $time); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); } public static function getChinaDate($time = null) { list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); } public static function getChinaWeek($week = null) { $week = $week ? $week : (int) date('w', time()); $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); return $weekMap[$week]; } public static function getPeriodOfTime($hour = null) { $hour = $hour ? $hour : (int) date('G', time()); $period = ''; if (0 <= $hour && 6 > $hour) { $period = '凌晨'; } elseif (6 <= $hour && 8 > $hour) { $period = '早上'; } elseif (8 <= $hour && 11 > $hour) { $period = '上午'; } elseif (11 <= $hour && 13 > $hour) { $period = '中午'; } elseif (13 <= $hour && 15 > $hour) { $period = '响午'; } elseif (15 <= $hour && 18 > $hour) { $period = '下午'; } elseif (18 <= $hour && 20 > $hour) { $period = '傍晚'; } elseif (20 <= $hour && 22 > $hour) { $period = '晚上'; } elseif (22 <= $hour && 23 >= $hour) { $period = '深夜'; } return $period; } public static function getUTCDate($dateTime = null) { $oldTimezone = self::getTimezone(); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone('UTC'); } $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); if ('UTC' !== strtoupper($oldTimezone)) { self::setTimezone($oldTimezone); } return $date; } public static function getMicroTime($get_as_float = null,$mircrotime = null) { return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); } public static function isLeapYear($year) { if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { return true; } return false; } public static function getTimeStamp($dateTime = null){ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); } public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); $timestamp = $timestamp ? $timestamp : time(); $compareTime = strtotime(self::format('Y-m-d',$timestamp)); $currentTime = strtotime(self::format('Y-m-d',$time)); $decrease = $timestamp - $time; $result = self::format($format,$time); if (0 >= $decrease) { return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } if ($currentTime == $compareTime) { if (1 == $type) { if (60 >= $decrease) { return array($decrease . $timelang['second'], $result); } return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); } return array(self::format('H:i',$time), $result); } elseif ($currentTime == $compareTime - 86400) { return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); } elseif ($currentTime == $compareTime - 172800) { return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); } return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); } } class WindGeneralDate { const FILL = 0; const DIGIT = 1; const TEXT = 2; const DEFAULT_FORMAT = 'Y-m-d H:i:s'; private $time = 0; public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { $time = time(); !$month && ((!$year) ? $month = date('m', $time) : $month = 1); !$day && ((!$year) ? $day = date('d', $time) : $day = 1); !$hours && !$year && $hours = date('H', $time); !$minutes && !$year && $minutes = date('i', $time); !$second && !$year && $second = date('s', $time); !$year && $year = date('Y', $time); $this->time = mktime($hours, $minutes, $second, $month, $day, $year); } public function getDaysInMonth() { return date('t', $this->time); } public function getDaysInYear() { return $this->isLeapYear() ? 366 : 365; } public function getDayOfYear() { return date('z', $this->time) + 1; } public function getDayOfMonth() { return date('j', $this->time); } public function getDayOfWeek() { return date('w', $this->time) + 1; } public function getWeekOfYear() { return date('W', $this->time); } public function getYear($format = true) { return date($format ? 'Y' : 'y', $this->time); } public function getMonth($display = self::FILL) { if(self::FILL == $display){ return date('m', $this->time); }elseif(self::DIGIT == $display){ return date('n', $this->time); }elseif(self::TEXT == $display){ return date('M', $this->time); } return date('n', $this->time); } public function getDay($display = self::FILL) { if(self::FILL == $display){ return date('d', $this->time); }elseif(self::DIGIT == $display){ return date('j', $this->time); }elseif(self::TEXT == $display){ return date('jS', $this->time); } return date('j', $this->time); } public function getWeek($display = self::FILL) { if(self::FILL == $display || self::DIGIT == $display){ return date('w', $this->time); }elseif(self::TEXT == $display){ return date('D', $this->time); } return date('N', $this->time); } public function get12Hours($display = self::FILL){ if(self::FILL == $display){ return date('h', $this->time); }elseif(self::DIGIT == $display){ return date('g', $this->time);; } return date('h', $this->time); } public function get24Hours($display = self::FILL){ if(self::FILL == $display){ return date('H', $this->time); }elseif(self::DIGIT == $display){ return date('G', $this->time);; } return date('H', $this->time); } public function getMinutes() { return date('i', $this->time); } public function getSeconds() { return date('s', $this->time); } public function getLocalTimeZone() { return date('T', $this->time); } public function setTime($time) { if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { $this->time = $time; } } public function getNow() { $date = getdate($this->time); return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); } public function __toString() { return $this->toString(); } public function toString($format = null) { return date($format ? $format : self::DEFAULT_FORMAT, $this->time); } public function isLeapYear() { return date('L', $this->time); } } class WindDecoder { const JSON_SLICE = 1; const JSON_IN_STR = 2; const JSON_IN_ARR = 4; const JSON_IN_OBJ = 8; const JSON_IN_CMT = 16; public static function decode($str, $useArray = true) { $str = strtolower(self::reduceString($str)); if ('true' == $str) { return true; } elseif ('false' == $str) { return false; } elseif ('null' == $str) { return null; } elseif (is_numeric($str)) { return (float)$str == (integer)$str ? (integer) $str : (float) $str; }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ return self::jsonToString($str); }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); } return false; } protected static function jsonToString($string) { $delim = substr($string, 0, 1); $chrs = substr($string, 1, -1); $decodeStr = ''; for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { $compare = substr($chrs, $c, 2); $ordCode = ord($chrs{$c}); if('\b' == $compare){ $decodeStr .= chr(0x08); ++$c; }elseif('\t' == $compare){ $decodeStr .= chr(0x09); ++$c; }elseif('\n' == $compare){ $decodeStr .= chr(0x0A); ++$c; }elseif('\f' == $compare){ $decodeStr .= chr(0x0C); ++$c; }elseif('\r' == $compare){ $decodeStr .= chr(0x0D); ++$c; }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { $decodeStr .= $chrs{++$c}; } }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $decodeStr .= self::utf16beToUTF8($utf16); $c += 5; }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ $decodeStr .= $chrs{$c}; }elseif(0xC0 == ($ordCode & 0xE0)){ $decodeStr .= substr($chrs, $c, 2); ++$c; }elseif(0xE0 == ($ordCode & 0xF0)){ $decodeStr .= substr($chrs, $c, 3); $c += 2; }elseif(0xF0 == ($ordCode & 0xF8)){ $decodeStr .= substr($chrs, $c, 4); $c += 3; }elseif(0xF8 == ($ordCode & 0xFC)){ $decodeStr .= substr($chrs, $c, 5); $c += 4; }elseif(0xFC == ($ordCode & 0xFE)){ $decodeStr .= substr($chrs, $c, 6); $c += 5; } } return $decodeStr; } protected static function jsonToArray($str) { return self::complexConvert($str,true); } protected static function jsonToObject($str) { return self::complexConvert($str,false); } protected static function complexConvert($str,$useArray = true){ if ('[' == $str{0}) { $stk = array(self::JSON_IN_ARR); $arr = array(); } else { $obj = $useArray ? array() : new stdClass(); $stk = array(self::JSON_IN_OBJ); } array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = self::reduceString($chrs); if ('' == $chrs) { return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; } for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); if (reset($stk) == self::JSON_IN_ARR) { array_push($arr, self::decode($slice, $useArray)); } elseif (reset($stk) == self::JSON_IN_OBJ) { if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $key = self::decode($parts[1], $useArray); $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { array_pop($stk); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { array_pop($stk); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { array_pop($stk); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) { array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { array_pop($stk); for ($i = $top['where']; $i <= ++$c; ++$i){ $chrs = substr_replace($chrs, ' ', $i, 1); } } } if (self::JSON_IN_ARR == reset($stk)) { return $arr; } elseif (self::JSON_IN_OBJ == reset($stk)) { return $obj; } return false; } protected static function unicodeToUTF8(&$str) { $utf8 = ''; foreach ($str as $unicode) { if ($unicode < 128) { $utf8 .= chr($unicode); } elseif ($unicode < 2048) { $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } else { $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); $utf8 .= chr(128 + ($unicode % 64)); } } return $utf8; } protected static function reduceString($str) { return trim(preg_replace(array( '#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str)); } protected static function utf16beToUTF8(&$str) { return self::unicodeToUTF8(unpack('n*', $str)); } } class WindEncoder { public static $charset = 'utf-8'; public static function encode($value) { switch (gettype($value)) { case 'boolean': return $value ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $value; case 'double': case 'float': return (float) $value; case 'string': return self::stringToJson($value); case 'array': return self::arrayToJson($value); case 'object': return self::objectToJson($value); default: return ''; } return ''; } protected static function stringToJson($string) { if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { $string = iconv($enc, 'UTF-8', $string); } $ascii = ''; $strlen = strlen($string); for ($c = 0; $c < $strlen; ++$c) { $ordVar = ord($string{$c}); if (0x08 == $ordVar) { $ascii .= '\b'; } elseif (0x09 == $ordVar) { $ascii .= '\t'; } elseif (0x0A == $ordVar) { $ascii .= '\n'; } elseif (0x0C == $ordVar) { $ascii .= '\f'; } elseif (0x0D == $ordVar) { $ascii .= '\r'; } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { $ascii .= '\\' . $string{$c}; } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { $ascii .= $string{$c}; } elseif (0xC0 == ($ordVar & 0xE0)) { $char = pack('C*', $ordVar, ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xE0 == ($ordVar & 0xF0)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF0 == ($ordVar & 0xF8)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xF8 == ($ordVar & 0xFC)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } elseif (0xFC == ($ordVar & 0xFE)) { $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); } } return '"' . $ascii . '"'; } protected static function arrayToJson(array $array) { if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; } return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; } protected static function objectToJson($object) { if ($object instanceof Traversable) { $vars = array(); foreach ($object as $k => $v) { $vars[$k] = $v; } } else { $vars = get_object_vars($object); } return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; } protected static function nameValue($name, $value) { return self::encode(strval($name)) . ':' . self::encode($value); } protected static function utf8ToUTF16BE(&$string, $bom = false) { $out = $bom ? "\xFE\xFF" : ''; if (function_exists('mb_convert_encoding')) { return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); } $uni = self::utf8ToUnicode($string); foreach ($uni as $cp) { $out .= pack('n', $cp); } return $out; } protected static function utf8ToUnicode(&$string) { $unicode = $values = array(); $lookingFor = 1; for ($i = 0, $length = strlen($string); $i < $length; $i++) { $thisValue = ord($string[$i]); if ($thisValue < 128) { $unicode[] = $thisValue; } else { if (count($values) == 0) { $lookingFor = ($thisValue < 224) ? 2 : 3; } $values[] = $thisValue; if (count($values) == $lookingFor) { $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; $values = array(); $lookingFor = 1; } } } return $unicode; } } class WindArray { public static function mergeArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); unset($array2[$key]); } else { $tmp[$key] = $array; } } return array_merge($tmp, (array) $array2); } public static function filterArrayWithKey($key, array $array1, array $array2) { if (!$key || !$array1 || !$array2) { return array(); } $array1 = self::rebuildArrayWithKey($key, $array1); $array2 = self::rebuildArrayWithKey($key, $array2); $tmp = array(); foreach ($array1 as $key => $array) { if (isset($array2[$key])) { $tmp[$key] = array_merge($array, $array2[$key]); } } return $tmp; } public static function rebuildArrayWithKey($key, array $array) { if (!$key || !$array) { return array(); } $tmp = array(); foreach ($array as $_array) { if (isset($_array[$key])) { $tmp[$_array[$key]] = $_array; } } return $tmp; } } Wind::import("COM:utility.WindSecurity"); Wind::import("COM:utility.WindString"); class WindFile { const READ = 'rb'; const READWRITE = 'rb+'; const WRITE = 'wb'; const WRITEREAD = 'wb+'; const APPEND_WRITE = 'ab'; const APPEND_WRITEREAD = 'ab+'; public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { $temp = "\r\n "; if (!$isBuildReturn && is_array($data)) { foreach ($data as $key => $value) { if (!preg_match('/^\w+$/', $key)) continue; $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; } $temp .= "\r\n"; } else { ($isBuildReturn) && $temp .= " return "; $temp .= WindString::varToString($data) . ";\r\n"; } return self::write($fileName, $temp, $method, $ifLock); } public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { $fileName = WindSecurity::escapePath($fileName); touch($fileName); if (!$handle = fopen($fileName, $method)) return false; $ifLock && flock($handle, LOCK_EX); $writeCheck = fwrite($handle, $data); $method == self::READWRITE && ftruncate($handle, strlen($data)); fclose($handle); $ifChmod && chmod($fileName, 0777); return $writeCheck; } public static function read($fileName, $method = self::READ) { $fileName = WindSecurity::escapePath($fileName); $data = ''; if (false !== ($handle = fopen($fileName, $method))) { flock($handle, LOCK_SH); $data = fread($handle, filesize($fileName)); fclose($handle); } return $data; } public static function clearDir($dir, $ifexpiled = false) { if (!$handle = @opendir($dir)) return false; while (false !== ($file = readdir($handle))) { if ('.' === $file[0] || '..' === $file[0]) continue; $fullPath = $dir . DIRECTORY_SEPARATOR . $file; if (is_dir($fullPath)) { self::clearDir($fullPath, $ifexpiled); } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { self::delFile($fullPath); } } closedir($handle); false === $ifexpiled && rmdir($dir); return true; } public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); if (!$handler = opendir($path)) { return false; } while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { if (substr($filename, 0, 1) != '.') { self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); } } else { self::delFile($path . DIRECTORY_SEPARATOR . $filename); } } } closedir($handler); true == $delDir && $level > 0 && rmdir($path); return true; } public static function getMimeType($fileName) { $suffix = self::getFileSuffix($fileName); $mimes = require WIND_PATH . '/component/utility/WindMimeTypes.php'; if (isset($mimes[$suffix])) { return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; } else { throw new WindException('Sorry, can not find the corresponding mime type of the file'); } return false; } public static function getDirectoryIterator($dir) { return new DirectoryIterator($dir); } public static function getFileInfo($fileName) { if (false === is_file($fileName)) { return array(); } $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); $fileInfo['ctime'] = filectime($fileName); $fileInfo['atime'] = fileatime($fileName); $fileInfo['mtime'] = filemtime($fileName); $fileInfo['readable'] = is_readable($fileName); $fileInfo['writable'] = is_writable($fileName); $fileInfo['executable'] = is_executable($fileName); $fileInfo['right'] = fileperms($fileName); $fileInfo['group'] = filegroup($fileName); $fileInfo['owner'] = fileowner($fileName); $fileInfo['mime'] = self::getMimeType($fileName); return $fileInfo; } public static function getDirectoryInfo($dir) { if (false !== is_dir($dir)) { return array(); } return stat($dir); } public static function delFile($filename) { return @unlink($filename); } public static function getFileSuffix($filename) { $filename = explode($filename, '.'); return $filename[count($filename) - 1]; } public static function appendSlashesToDir($path) { return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; } } class WindHtmlHelper { public static function encode($text) { return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function encodeArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::encodeArray($value); $_tmp[$key] = $value; } return $_tmp; } } class WindImage { public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); if (!$imagecreate) return false; $imgwidth = $minitemp['width']; $imgheight = $minitemp['height']; $srcX = $srcY = $dstX = $dstY =0; if (!$isProportion) { $dsDivision = $imgheight / $imgwidth; $fixDivision = $dstH / $dstW; if ($dsDivision > $fixDivision) { $tmp = $imgwidth * $fixDivision; $srcY = round(($imgheight - $tmp) / 2); $imgheight = $tmp; } else { $tmp = $imgheight / $fixDivision; $srcX = round(($imgwidth - $tmp) / 2); $imgwidth = $tmp; } } $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { $black = imagecolorallocate($thumb, 0, 0, 0); imagecolortransparent($thumb, $black); } $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); self::makeImg($minitemp['type'], $thumb, $dstFile); imagedestroy($thumb); return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); } public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { $sourcedb = $waterdb = array(); if (false === ($sourcedb = self::getImgInfo($source))) return false; if (!$waterImg && !$waterText) return false; imagealphablending($sourcedb['source'], true); if ($waterImg) { $waterdb = self::getImgInfo($waterImg); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); if ($waterdb['type'] == 'png') { $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); $sourcedb['source'] = $tmp; } else { imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); } } elseif ($waterText) { list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); empty($waterFont) && $waterFont = 12; $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); $waterdb['width'] = $temp[2] - $temp[6]; $waterdb['height'] = $temp[3] - $temp[7]; unset($temp); list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); if (strlen($color) != 7) return false; $R = hexdec(substr($color, 1, 2)); $G = hexdec(substr($color, 3, 2)); $B = hexdec(substr($color, 5)); self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); } $dstsrc && $source = $dstsrc; self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); isset($waterdb['source']) && imagedestroy($waterdb['source']); imagedestroy($sourcedb['source']); return true; } private static function checkAttribute($attribute) { $attribute = is_string($attribute) ? array($attribute) : $attribute; if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; return $attribute; } private static function changeCharset($charset) { $charset = strtolower($charset); return !in_array($charset, array('utf8', 'utf-8')); } private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { if (is_array($waterPos)) return $waterPos; $wX = $wY = 0; switch (intval($waterPos)) { case 0 : $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); break; case 1 : $wX = 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 2: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 3: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? 5 : $waterdb['height']; break; case 4: $wX = 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 5: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; case 6: $wX = $sourcedb['width'] - $waterdb['width'] - 5; $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; break; default: $wX = ($sourcedb['width'] - $waterdb['width']) / 2; $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; break; } return array($wX, $wY); } private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { if (false === ($imgdata = self::getImgInfo($srcFile))) return false; if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; $imgdata['dstW'] = $dstW; $imgdata['dstH'] = $dstH; if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); } elseif ($dstW > 0 && $dstH > 0) { if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); } if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); } } else { $imgdata = false; } return $imgdata; } public static function getImgInfo($srcFile) { if (false === ($imgdata = self::getImgSize($srcFile))) return false; $imgdata['type'] = self::getTypes($imgdata['type']); if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; $imgdata['source'] = $imagecreatefromtype($srcFile); !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); return $imgdata; } private static function getImgSize($srcFile, $srcExt = null) { empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); $srcdata = array(); $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); in_array($srcExt, $exts) && $srcdata['type'] = 2; if (false === ($info = getimagesize($srcFile))) return false; list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; return $srcdata; } private static function getImgcreate($imagetype) { if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { return array('imagecreatetruecolor', 'imagecopyresampled'); } if (function_exists('imagecreate') && function_exists('imagecopyresized')) { return array('imagecreate', 'imagecopyresized'); } return array('', ''); } private static function makeImg($type, $image, $filename, $quality = '75') { $makeimage = 'image' . $type; if (!function_exists($makeimage)) return false; if ($type == 'jpeg') { $makeimage($image, $filename, $quality); } else { $makeimage($image, $filename); } return true; } private static function getTypes($id) { $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; } } Wind::import('WIND:component.utility.WindFile'); class WindPack { const STRIP_SELF = 'stripWhiteSpaceBySelf'; const STRIP_PHP = 'stripWhiteSpaceByPhp'; const STRIP_TOKEN = 'stripWhiteSpaceByToken'; private $packList = array(); private $contentInjectionPosition; private $contentInjectionCallBack = ''; public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { if (empty($dst) || empty($dir)) { return false; } $suffix = is_array($suffix) ? $suffix : array( $suffix); if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { return false; } $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->stripImport($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { if (empty($dst) || empty($fileList)) { return false; } $content = array(); $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); $fileSuffix = WindFile::getFileSuffix($dst); $replace = $compress ? ' ' : "\n"; $content = implode($replace, $content); $content = $this->callBack($content, $replace); $content = $this->stripNR($content, $replace); $content = $this->stripPhpIdentify($content, ''); $content = $this->getContentBySuffix($content, $fileSuffix, $replace); WindFile::write($dst, $content); return true; } public function stripWhiteSpaceByPhp($filename) { return php_strip_whitespace($filename); } public function stripWhiteSpaceBySelf($filename, $compress = true) { $content = $this->getContentFromFile($filename); $content = $this->stripComment($content, ''); return $this->stripSpace($content, ' '); } public function stripWhiteSpaceByToken($filename) { $content = $this->getContentFromFile($filename); $compressContent = ''; $lastToken = 0; foreach (token_get_all($content) as $key => $token) { if (is_array($token)) { if (in_array($token[0], array( T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) { continue; } $compressContent .= ' ' . $token[1]; } else { $compressContent .= $token; } $lastToken = $token[0]; } return $compressContent; } public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { static $content = array(); if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { return false; } $dir = is_array($dir) ? $dir : array( $dir); foreach ($dir as $_dir) { $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; if (is_dir($_dir)) { $handle = dir($_dir); while (false != ($tmp = $handle->read())) { $name = WindFile::appendSlashesToDir($_dir) . $tmp; if (is_dir($name) && !in_array($tmp, $ndir)) { $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); } if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { $content[] = $this->$packMethod($name); $this->setPackList($file, $name); } } $handle->close(); } } return $content; } public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { return array(); } $fileList = is_array($fileList) ? $fileList : array( $fileList); foreach ($fileList as $key => $value) { if (is_array($value) && isset($value[1])) { $parents = class_parents($value[1]); $_fileList = $this->buildFileList($parents, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); $implements = class_implements($value[1]); $_fileList = $this->buildFileList($implements, $fileList); $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); if (key_exists($key, $this->getPackList())) continue; $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; if (is_file($file)) { $content[] = $this->$packMethod($file); $this->setPackList($key, $value); } } } } public function stripComment($content, $replace = '') { return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); } public function stripNR($content, $replace = array('\n','\r\n','\r')) { return preg_replace('/[\n\r]+/', $replace, $content); } public function stripSpace($content, $replace = ' ') { return preg_replace('/[ ]+/', $replace, $content); } public function stripPhpIdentify($content, $replace = '') { return preg_replace('/(?:<\?(?:php)*)|(\)/i', $replace, $content); } public function stripStrByRule($content, $rule, $replace = '') { return preg_replace("/$rule/", $replace, $content); } public function stripImport($content, $replace = '') { $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); if ($matchs[1]) { foreach ($matchs[1] as $key => $value) { $name = substr($value, strrpos($value, '.') + 1); if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { $strip = str_replace(array( '(', ')'), array( '\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; $content = $this->stripStrByRule($content, $strip, $replace); } } } return $content; } public function getPackList() { return $this->packList; } public function getContentFromFile($filename) { if (is_file($filename)) { $content = ''; $fp = fopen($filename, "r"); while (!feof($fp)) { $line = fgets($fp); if (in_array(strlen($line), array( 2, 3)) && in_array(ord($line), array( 9, 10, 13))) continue; $content .= $line; } fclose($fp); return $content; } return false; } public function getContentBySuffix($content, $suffix, $replace = ' ') { switch ($suffix) { case 'php': $content = '' . $replace . $content . ''; break; default: $content = '' . $replace . $content . ''; break; } return $content; } private function buildFileList($list, $fileList) { $_temp = array(); foreach ($list as $fileName) { foreach ($fileList as $key => $value) { if ($value[1] == $fileName) { $_temp[$key] = $value; break; } } } return $_temp; } public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { if (!in_array($position, array( 'before', 'after'))) $position = 'before'; $this->contentInjectionPosition = $position; $this->contentInjectionCallBack = $contentInjectionCallBack; } public function callBack($content, $replace = '') { if ($this->contentInjectionCallBack !== '') { $_content = call_user_func_array($this->contentInjectionCallBack, array( $this->getPackList())); if ($this->contentInjectionPosition == 'before') { $content = $replace . $_content . $content; } elseif ($this->contentInjectionPosition == 'after') { $content .= $replace . $_content . $replace; } } return $content; } private function isValidatePackMethod($packMethod) { return method_exists($this, $packMethod) && in_array($packMethod, array( WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN)); } private function setPackList($key, $value) { if (isset($this->packList[$key])) { if (is_array($this->packList[$key])) { array_push($this->packList[$key], $value); } else { $tmp_name = $this->packList[$key]; $this->packList[$key] = array( $tmp_name, $value); } } else { $this->packList[$key] = $value; } } } class WindSecurity { public static function escapeHTMLForArray($data) { $_tmp = array(); $_charset = Wind::getApp()->getRequest()->getCharset(); foreach ($data as $key => $value) { if (is_string($key)) $key = htmlspecialchars($key, ENT_QUOTES, $_charset); if (is_string($value)) $value = htmlspecialchars($value, ENT_QUOTES, $_charset); elseif (is_array($value)) $value = self::escapeHTMLForArray($value); $_tmp[$key] = $value; } return $_tmp; } public static function escapeHTML($str) { if (is_array($str)) return self::escapeHTMLForArray($str); return htmlspecialchars($str, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); } public static function stripTags($str, $allowTags = "") { return strip_tags($str, $allowTags); } public static function escapePath($fileName, $ifCheck = true) { if (!self::_escapePath($fileName, $ifCheck)) { throw new WindException('file name is illegal'); } return $fileName; } public static function escapeDir($dir) { $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } public static function escapeChar($value) { if (is_array($value)) { foreach ($value as $key => $sub) { $value[$key] = self::escapeChar($sub); } } elseif (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = self::escapeString($value); } return $value; } public static function escapeString($string) { $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); return preg_replace( array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } public static function quotemeta($string) { return quotemeta($string); } public function checkInputValue($value, $key = '') { if (is_int($value)) { $value = (int) $value; } elseif (is_string($value)) { $value = "'" . addslashes($value) . "'"; } elseif (is_float($value)) { $value = (float) $value; } elseif (is_object($value) || is_array($value)) { $value = "'" . addslashes(serialize($value)) . "'"; } return $value; } public static function addSlashesForInput($str) { if (!get_magic_quotes_gpc()) { $str = addslashes($str); } return $str; } public static function addSlashesForOutput($str) { if (!get_magic_quotes_runtime()) { $str = addslashes($str); } return $str; } public static function addSlashes($value, $gpc = false, $df = false) { if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable))) { return $value; } if (is_string($value)) { if (false === $gpc && true === $df) { return self::addSlashesForOutput($value); } if (false === $df && true === $gpc) { return self::addSlashesForInput($value); } return addslashes($value); } foreach ($value as $key => $_value) { $value[$key] = self::addSlashes($_value, $gpc, $df); } return $value; } public static function stripSlashes($value) { if (!$value) return $value; if (is_string($value)) return stripslashes($value); if (!is_array($value) && !($value instanceof Traversable)) return $value; foreach ($value as $key => $_value) { $value[$key] = self::stripSlashes($_value); } return $value; } public static function sqlEscape($var, $strip = true, $isArray = false) { if (is_array($var)) { if (!$isArray) return " '' "; foreach ($var as $key => $value) { $var[$key] = trim(self::sqlEscape($value, $strip)); } return $var; } elseif (is_numeric($var)) { return " '" . $var . "' "; } else { return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; } } public static function sqlImplode($array, $strip = true) { return implode(',', self::sqlEscape($array, $strip, true)); } public static function sqlSingle($array, $strip = true) { if (!is_array($array)) return ''; $array = self::sqlEscape($array, $strip, true); $str = ''; foreach ($array as $key => $val) { $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; } return $str; } public static function sqlMulti($array, $strip = true) { if (!is_array($array)) { return ''; } $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; } } return $str; } public static function sqlMetadata($data, $tlists = array()) { if (empty($tlists) || !in_array($data, $tlists)) { $data = str_replace(array('`', ' '), '', $data); } return ' `' . $data . '` '; } private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; if (strtr($tmpname, $tmparray) != $tmpname) { return false; } return true; } } class WindString { const UTF8 = 'utf8'; const GBK = 'gbk'; public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( $string, $start, $length, $dot); } public static function strlen($string, $charset = self::UTF8) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; $count++; } return $count; } public static function varToString($input, $indent = '') { switch (gettype($input)) { case 'string': return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; case 'array': $output = "array(\r\n"; foreach ($input as $key => $value) { $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( $value, $indent . "\t"); $output .= ",\r\n"; } $output .= $indent . ')'; return $output; case 'boolean': return $input ? 'true' : 'false'; case 'NULL': return 'NULL'; case 'integer': case 'double': case 'float': return "'" . (string) $input . "'"; } return 'NULL'; } public static function jsonEncode($value) { if (!function_exists('json_encode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); } public static function jsonDecode($value) { if (!function_exists('json_decode')) { Wind::import('Wind:component.utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); } public static function jsonSimpleEncode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': return '"' . addslashes( str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; case 'array': if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array(); foreach ($var as $name => $value) { $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( $value); } return '{' . join(',', $properties) . '}'; } $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); return '[' . join(',', $elements) . ']'; } return false; } public static function utf8_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j += 2; } else { $word++; } $j++; } $start = $word + 3 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 3); $j += 2; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function utf8_strlen($str) { $i = $count = 0; $len = strlen($str); while ($i < $len) { $chr = ord($str[$i]); $count++; $i++; if ($i >= $len) break; if ($chr & 0x80) { $chr <<= 1; while ($chr & 0x80) { $i++; $chr <<= 1; } } } return $count; } public static function gbk_substr($string, $start, $length = null, $dot = false) { if (empty($string) || !is_int($start) || ($length && !is_int($length))) { return ''; } $strlen = strlen($string); $length = $length ? $length : $strlen; $substr = ''; $chinese = $word = 0; for ($i = 0, $j = 0; $i < $start; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $chinese++; $j++; } else { $word++; } $j++; } $start = $word + 2 * $chinese; for ($i = $start, $j = $start; $i < $start + $length; $i++) { if (0xa0 < ord(substr($string, $j, 1))) { $substr .= substr($string, $j, 2); $j++; } else { $substr .= substr($string, $j, 1); } $j++; } (strlen($substr) < $strlen) && $dot && $substr .= "..."; return $substr; } public static function gbk_strlen($string) { $len = strlen($string); $i = $count = 0; while ($i < $len) { ord($string[$i]) > 129 ? $i += 2 : $i++; $count++; } return $count; } } class WindUtility { public static function mergeArray($array1, $array2) { foreach ($array2 as $key => $value) { if (!isset($array1[$key]) || !is_array($array1[$key])) { $array1[$key] = $value; continue; } $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); } return $array1; } public static function lcfirst($str) { if (function_exists('lcfirst')) return lcfirst($str); $str[0] = strtolower($str[0]); return $str; } public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { $randnum = rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { $randstr .= chr($randnum + 55); } else { $randstr .= chr($randnum + 61); } } return $randstr; } public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } class WindValidator { public static function isTelPhone($phone) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); } public static function isTelNumber($number) { return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); } public static function isQQ($qq) { return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); } public static function isZipcode($zipcode) { return 0 < preg_match('/^\d{4,8}$/', $zipcode); } public static function hasEmail($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); } public static function isEmail($string) { return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); } public static function hasIdCard($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); } public static function isIdCard($string) { return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); } public static function hasUrl($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); } public static function isUrl($string) { return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); } public static function hasChinese($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); } public static function isChinese($string) { return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); } public static function hasHtml($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); } public static function isHtml($string) { return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); } public static function hasIpv4($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); } public static function isIpv4($string) { return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); } public static function hasIpv6($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| ::([a-f0-9]{1,4}:){5}| ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )([a-f0-9]{1,4}:[a-f0-9]{1,4}| (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string, $matches, $ifAll); } public static function isIpv6($string) { return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| ::(?:[a-f0-9]{1,4}:){5}| (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: ) )\Z/ix', $string); } public static function hasScript($string, &$matches = array(), $ifAll = false) { return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); } public static function isScript($string) { return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); } public static function isEmpty($value) { return empty($value); } public static function isNonNegative($number) { return 0 <= (int) $number; } public static function isPositive($number) { return 0 < (int) $number; } public static function isNegative($number) { return 0 > (int) $number; } public static function isArray($array) { return is_array($array); } public static function isRequired($value) { return !self::isEmpty($value); } public static function inArray($needle, array $array, $strict = true) { return in_array($needle, $array, $strict); } public static function isLegalLength($string, $length, $charset = 'utf8') { Wind::import('WIND:component.utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { if (true === $ifAll) { return preg_match_all($regExp, $string, $matches); } return preg_match($regExp, $string, $matches); } }?> \ No newline at end of file From 2b754448261e3439c03f840c3540c279abdfcf95 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 03:27:31 +0000 Subject: [PATCH 0412/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9Ahtml=E8=BE=93=E5=87=BA=E5=AE=89=E5=85=A8=E8=BF=87?= =?UTF-8?q?=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2484 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/utility/WindSecurity.php | 390 +++++++++++++----------- 1 file changed, 214 insertions(+), 176 deletions(-) diff --git a/wind/component/utility/WindSecurity.php b/wind/component/utility/WindSecurity.php index 6f046699..2048283f 100644 --- a/wind/component/utility/WindSecurity.php +++ b/wind/component/utility/WindSecurity.php @@ -1,262 +1,300 @@ - 2010-12-21 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - + * @author Qian Su * @version $Id$ * @package - */ -class WindSecurity { + */ +class WindSecurity { + /** - * html转换输出 - * @param $param + * Convert special characters to HTML entities + * @param array $data + * @return array + */ + public static function escapeHTMLForArray($data) { + $_tmp = array(); + $_charset = Wind::getApp()->getRequest()->getCharset(); + foreach ($data as $key => $value) { + if (is_string($key)) + $key = htmlspecialchars($key, ENT_QUOTES, $_charset); + if (is_string($value)) + $value = htmlspecialchars($value, ENT_QUOTES, $_charset); + elseif (is_array($value)) + $value = self::escapeHTMLForArray($value); + $_tmp[$key] = $value; + } + return $_tmp; + } + + /** + * Convert special characters to HTML entities + * @param string $str * @return string - */ - public static function escapeHTML($str) { - return htmlspecialchars($str, ENT_QUOTES); - } + */ + public static function escapeHTML($str) { + if (is_array($str)) + return self::escapeHTMLForArray($str); + return htmlspecialchars($str, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); + } + /** * 过滤标签 * @param $param * @return string - */ - public static function stripTags($str, $allowTags = "") { - return strip_tags($str, $allowTags); - } + */ + public static function stripTags($str, $allowTags = "") { + return strip_tags($str, $allowTags); + } + /** * 路径转换 * @param $fileName * @param $ifCheck * @return string - */ - public static function escapePath($fileName, $ifCheck = true) { - if (!self::_escapePath($fileName, $ifCheck)) { - throw new WindException('file name is illegal'); - } - return $fileName; - } + */ + public static function escapePath($fileName, $ifCheck = true) { + if (!self::_escapePath($fileName, $ifCheck)) { + throw new WindException('file name is illegal'); + } + return $fileName; + } + /** * 目录转换 * @param string $dir * @return string - */ - public static function escapeDir($dir) { - $dir = strtr($dir, array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); - return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); - } + */ + public static function escapeDir($dir) { + $dir = strtr($dir, + array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', + ';' => '')); + return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); + } + /** * 通用多类型转换 * @param mixed $value * @return mixed - */ - public static function escapeChar($value) { - if (is_array($value)) { - foreach ($value as $key => $sub) { - $value[$key] = self::escapeChar($sub); - } - } elseif (is_int($value)) { - $value = (int) $value; - } elseif (is_string($value)) { - $value = self::escapeString($value); - } - return $value; - } + */ + public static function escapeChar($value) { + if (is_array($value)) { + foreach ($value as $key => $sub) { + $value[$key] = self::escapeChar($sub); + } + } elseif (is_int($value)) { + $value = (int) $value; + } elseif (is_string($value)) { + $value = self::escapeString($value); + } + return $value; + } + /** * 字符转换 * @param string $string * @return string - */ - public static function escapeString($string) { - $string = strtr($string, array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', - "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', - "'" => ''')); - return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', - '&'), $string); - } - + */ + public static function escapeString($string) { + $string = strtr($string, + array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', + "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', + '>' => '>', '"' => '"', "'" => ''')); + return preg_replace( + array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), + array('', '&'), $string); + } + /** * 该函数可用于转义拥有特殊意义的字符,比如 SQL 中的 ( )、[ ] 以及 *。 * @param string $string * @return string - */ - public static function quotemeta($string) { - return quotemeta($string); - } + */ + public static function quotemeta($string) { + return quotemeta($string); + } + /** * 对字符串转义 * @param string $value * @return string - */ - public function checkInputValue($value, $key = '') { - if (is_int($value)) { - $value = (int) $value; - } elseif (is_string($value)) { - $value = "'" . addslashes($value) . "'"; - } elseif (is_float($value)) { - $value = (float) $value; - } elseif (is_object($value) || is_array($value)) { - $value = "'" . addslashes(serialize($value)). "'"; - } - return $value; - } + */ + public function checkInputValue($value, $key = '') { + if (is_int($value)) { + $value = (int) $value; + } elseif (is_string($value)) { + $value = "'" . addslashes($value) . "'"; + } elseif (is_float($value)) { + $value = (float) $value; + } elseif (is_object($value) || is_array($value)) { + $value = "'" . addslashes(serialize($value)) . "'"; + } + return $value; + } + /** * 对cookie/post/get方式的值添加反斜线 * @param string $str * @return string - */ - public static function addSlashesForInput($str) { - if (!get_magic_quotes_gpc()) { - $str = addslashes($str); - } - return $str; - } - + */ + public static function addSlashesForInput($str) { + if (!get_magic_quotes_gpc()) { + $str = addslashes($str); + } + return $str; + } + /** * 对从db或者file里面读取的内容添加反斜线 * @return string - */ - public static function addSlashesForOutput($str) { - if (!get_magic_quotes_runtime()) { - $str = addslashes($str); - } - return $str; - } - + */ + public static function addSlashesForOutput($str) { + if (!get_magic_quotes_runtime()) { + $str = addslashes($str); + } + return $str; + } + /** * 添加反斜线,转义字符 * @param mixed $value 要处理的数组 * @param boolean $gpc 是否是get/cookie/post传递过来的值 * @param boolean $df 是否是database/file传递过来的值 * @return string - */ - public static function addSlashes($value, $gpc = false, $df = false) { - if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable) )) { - return $value; - } - if(is_string($value)){ - if (false === $gpc && true === $df) { - return self::addSlashesForOutput($value); - } - if (false === $df && true === $gpc) { - return self::addSlashesForInput($value); - } - return addslashes($value); - } - foreach($value as $key=>$_value){ - $value[$key] = self::addSlashes($_value,$gpc,$df); - } - return $value; - } + */ + public static function addSlashes($value, $gpc = false, $df = false) { + if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable))) { + return $value; + } + if (is_string($value)) { + if (false === $gpc && true === $df) { + return self::addSlashesForOutput($value); + } + if (false === $df && true === $gpc) { + return self::addSlashesForInput($value); + } + return addslashes($value); + } + foreach ($value as $key => $_value) { + $value[$key] = self::addSlashes($_value, $gpc, $df); + } + return $value; + } + /** * 去除反 斜线 * @param mixed $array * @return string - */ - public static function stripSlashes($value) { - if (!$value) return $value; - if (is_string($value)) return stripslashes($value); - if (!is_array($value) && !($value instanceof Traversable)) return $value; - foreach ($value as $key => $_value) { - $value[$key] = self::stripSlashes($_value); - } - return $value; - } - + */ + public static function stripSlashes($value) { + if (!$value) + return $value; + if (is_string($value)) + return stripslashes($value); + if (!is_array($value) && !($value instanceof Traversable)) + return $value; + foreach ($value as $key => $_value) { + $value[$key] = self::stripSlashes($_value); + } + return $value; + } + /** * 通用多类型混合转义函数 * @param $var * @param $strip * @param $isArray * @return mixture - */ - public static function sqlEscape($var, $strip = true, $isArray = false) { - if (is_array($var)) { - if (!$isArray) return " '' "; - foreach ($var as $key => $value) { - $var[$key] = trim(self::sqlEscape($value, $strip)); - } - return $var; - } elseif (is_numeric($var)) { - return " '" . $var . "' "; - } else { - return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; - } - } + */ + public static function sqlEscape($var, $strip = true, $isArray = false) { + if (is_array($var)) { + if (!$isArray) + return " '' "; + foreach ($var as $key => $value) { + $var[$key] = trim(self::sqlEscape($value, $strip)); + } + return $var; + } elseif (is_numeric($var)) { + return " '" . $var . "' "; + } else { + return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; + } + } + /** * 通过","字符连接数组转换的字符 * @param $array * @param $strip * @return string - */ - public static function sqlImplode($array, $strip = true) { - return implode(',', self::sqlEscape($array, $strip, true)); - } + */ + public static function sqlImplode($array, $strip = true) { + return implode(',', self::sqlEscape($array, $strip, true)); + } + /** * 组装单条 key=value 形式的SQL查询语句值 insert/update * @param $array * @param $strip * @return string - */ - public static function sqlSingle($array, $strip = true) { - if (!is_array($array)) return ''; - $array = self::sqlEscape($array, $strip, true); - $str = ''; - foreach ($array as $key => $val) { - $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; - } - return $str; - } + */ + public static function sqlSingle($array, $strip = true) { + if (!is_array($array)) + return ''; + $array = self::sqlEscape($array, $strip, true); + $str = ''; + foreach ($array as $key => $val) { + $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; + } + return $str; + } + /** * 组装多条 key=value 形式的SQL查询语句 insert * @param $array * @param $strip * @return string - */ - public static function sqlMulti($array, $strip = true) { - if (!is_array($array)) { - return ''; - } - $str = ''; - foreach ($array as $val) { - if (!empty($val) && is_array($val)) { - $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; - } - } - return $str; - } + */ + public static function sqlMulti($array, $strip = true) { + if (!is_array($array)) { + return ''; + } + $str = ''; + foreach ($array as $val) { + if (!empty($val) && is_array($val)) { + $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; + } + } + return $str; + } + /** * 过滤SQL元数据,数据库对象(如表名字,字段等) * @param $data 元数据 * @param $tlists 白名单 * @return string 经过转义的元数据字符串 - */ - public static function sqlMetadata($data ,$tlists=array()) { - if (empty($tlists) || !in_array($data , $tlists)) { - $data = str_replace(array('`', ' '), '',$data); - } - return ' `'.$data.'` '; - } + */ + public static function sqlMetadata($data, $tlists = array()) { + if (empty($tlists) || !in_array($data, $tlists)) { + $data = str_replace(array('`', ' '), '', $data); + } + return ' `' . $data . '` '; + } + /** * 私用路径转换 * @param string $fileName * @param boolean $ifCheck * @return boolean - */ - private static function _escapePath($fileName, $ifCheck = true) { - $tmpname = strtolower($fileName); - $tmparray = array('://' => '', "\0" => ''); - $ifCheck && $tmparray['..'] = ''; - if (strtr($tmpname, $tmparray) != $tmpname) { - return false; - } - return true; - } - + */ + private static function _escapePath($fileName, $ifCheck = true) { + $tmpname = strtolower($fileName); + $tmparray = array('://' => '', "\0" => ''); + $ifCheck && $tmparray['..'] = ''; + if (strtr($tmpname, $tmparray) != $tmpname) { + return false; + } + return true; + } + } \ No newline at end of file From 6bd441e4c9809963599d39243dbfb48f0511bcd8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 03:28:14 +0000 Subject: [PATCH 0413/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2485 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/router/route/AbstractWindRoute.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wind/component/router/route/AbstractWindRoute.php b/wind/component/router/route/AbstractWindRoute.php index 2ee3e8c4..a01947a9 100644 --- a/wind/component/router/route/AbstractWindRoute.php +++ b/wind/component/router/route/AbstractWindRoute.php @@ -5,7 +5,7 @@ * @version $Id$ * @package */ -abstract class AbstractWindRoute extends WindHandlerInterceptor { +abstract class AbstractWindRoute extends WindModule { /** * 根据匹配的路由规则,构建Url @@ -35,10 +35,8 @@ public function handle() { } else { $this->result = $this->interceptorChain->execute(); } - call_user_func_array(array($this, 'postHandle'), $args); return $this->result; } - } ?> \ No newline at end of file From 17057b02eec7979e37f652e2e30a6d2a07bbf3dd Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 03:29:41 +0000 Subject: [PATCH 0414/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E4=B8=BB=E9=A2=98=E6=94=AF=E6=8C=81=EF=BC=8C=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E7=AE=A1=E7=90=86=EF=BC=8Cjs=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2486 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/viewer/WindLayout.php | 119 +++++++++++++----- wind/component/viewer/WindView.php | 31 ++--- wind/component/viewer/WindViewerResolver.php | 114 ++++++++++++----- .../compiler/WindTemplateCompilerCss.php | 23 ++++ .../compiler/WindTemplateCompilerEcho.php | 4 +- .../compiler/WindTemplateCompilerScript.php | 20 +-- .../viewer/compiler/WindViewTemplate.php | 34 +++-- 7 files changed, 238 insertions(+), 107 deletions(-) create mode 100644 wind/component/viewer/compiler/WindTemplateCompilerCss.php diff --git a/wind/component/viewer/WindLayout.php b/wind/component/viewer/WindLayout.php index e243090a..543e4ebc 100644 --- a/wind/component/viewer/WindLayout.php +++ b/wind/component/viewer/WindLayout.php @@ -1,11 +1,4 @@ 2010-11-15 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - /** * 布局对象, * 通过加载一个布局对象,或者布局配置文件,或者设置布局变量来实现页面布局 @@ -15,9 +8,37 @@ * @version $Id$ * @package */ -class WindLayout { - - private $layoutFile = ''; +class WindLayout extends WindModule { + /* 编译结果缓存 */ + protected $blockKey = ""; + /** + * 定义主题包的位置 + * @var string + */ + private $theme; + /** + * javascript集合 + * @var string + */ + private $script; + /** + * css 集合 + * @var string + */ + private $css; + /** + * 布局文件的位置 + * @var string + */ + private $layout; + /** + * @var array + */ + private $segments = array(); + /** + * @var WindViewerResolver + */ + private $viewer = null; /** * @param string $layoutFile @@ -26,42 +47,76 @@ public function __construct($layoutFile = '') { $this->setLayoutFile($layoutFile); } - /** - * 解析layout布局文件 - * @param WindViewerResolver $windViewerResolver + /** + * 解析布局文件 + * @param WindViewerResolver $viewer */ - public function parse($windViewerResolver) { - if (!$windViewerResolver) return ''; - $this->viewer = $windViewerResolver; - if (!$this->layoutFile) throw new WindException('layout file is required.'); - $layoutFile = $windViewerResolver->compile($this->layoutFile); + public function parser($viewer) { + $this->viewer = $viewer; + $content = ''; ob_start(); - if (!include $layoutFile) throw new WindException('Incorrect layout file ' . $layoutFile); - return ob_get_clean(); + if ($this->layout) { + list($tpl) = $this->viewer->compile($this->layout); + if (!@include ($tpl)) { + throw new WindViewException('[component.viewer.WindLayout.parser] layout file ' . $tpl, + WindViewException::VIEW_NOT_EXIST); + } + } else + $this->content(); + $content = ob_get_clean(); + foreach ($this->segments as $key => $value) { + if ($key) + $content = str_replace("", $value[1], $content); + } + $content = preg_replace('/(<\/body>)/i', $this->script . '\\1', $content); + //$content = preg_replace('/<\/head>/i', $this->css . '', $content); + return $content; + } + + /** + * 设置切片内容 + * @param string $template + */ + public function segment($template) { + $this->segments[$template] = $this->viewer->compile($template, '', true); + echo ""; + } + + /** + * 当前模板内容 + * @param string $template + */ + public function content() { + $template = $this->viewer->getWindView()->templateName; + $this->segment($template); } - private function setSegments($segment = '') { - $this->getContent($segment); + /** + * @param string $theme + */ + public function setTheme($theme) { + $this->theme = $theme; } - private function getContent($template = '') { - if (!isset($this->viewer)) return; - if (!$template) $template = $this->viewer->getWindView()->getTemplateName(); - if ($template) $this->viewer->displayWindFetch($template); + /** + * @param string $layout + */ + public function setLayout($layout) { + $this->layout = $layout; } /** - * @return the $layoutFile + * @param string $script */ - protected function getLayoutFile() { - return $this->layoutFile; + public function setScript($script) { + $this->script .= $script; } /** - * @param field_type $layoutFile + * @param string $css */ - protected function setLayoutFile($layoutFile) { - $this->layoutFile = $layoutFile; + public function setCss($css) { + $this->css .= $css; } } \ No newline at end of file diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php index 7ee64661..bd0dcd89 100644 --- a/wind/component/viewer/WindView.php +++ b/wind/component/viewer/WindView.php @@ -58,17 +58,22 @@ class WindView extends WindModule implements IWindView { * @var string */ public $compileExt = 'tpl'; + /** + * 布局文件 + * @var string + */ + public $layout; + /** + * 主题包目录 + * @var string + */ + public $theme; /** * 视图解析引擎 * @var WindViewerResolver */ protected $viewResolver = null; - /** - * 布局文件 - * @var string - */ - protected $layout; /** * 视图渲染 @@ -160,20 +165,4 @@ public function getViewResolver() { $this->viewResolver->registerEventListener('windFetch', new $listener($this)); return $this->viewResolver; } - - /** - * @return the $layout - */ - public function getLayout() { - return $this->layout; - } - - /** - * @param string $layout - * @return string - */ - public function setLayout($layout) { - return $this->layout = $layout; - } - } \ No newline at end of file diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php index eeecb92e..8916f304 100644 --- a/wind/component/viewer/WindViewerResolver.php +++ b/wind/component/viewer/WindViewerResolver.php @@ -16,7 +16,7 @@ * @version $Id$ * @package */ -class WindViewerResolver implements IWindViewerResolver { +class WindViewerResolver extends WindModule implements IWindViewerResolver { /** * @var array */ @@ -25,6 +25,11 @@ class WindViewerResolver implements IWindViewerResolver { * @var WindView */ protected $windView = null; + + /** + * @var WindLayout + */ + protected $windLayout = null; /** * @param WindView $windView @@ -37,12 +42,20 @@ public function __construct($windView = null) { * @see IWindViewerResolver::windFetch() */ public function windFetch($template = '') { - if (!$template) { - $layout = $this->windView->getLayout(); - $template = $layout ? $layout : $this->windView->templateName; - } ob_start(); - $this->render($template); + if (!$template) { + $template = $this->windView->templateName; + $_tpl = $this->windView->getCompileFile($template); + if ($this->checkReCompile()) { + $layout = $this->getWindLayout(); + $layout->setLayout($this->windView->layout); + $layout->setTheme($this->windView->theme); + WindFile::write($_tpl, $layout->parser($this)); + } + } else + list($_tpl) = $this->compile($template); + + WindRender::render($_tpl, Wind::getApp()->getResponse()->getData($template), $this); return ob_get_clean(); } @@ -50,9 +63,9 @@ public function windFetch($template = '') { * @see IWindViewerResolver::windAssign() */ public function windAssign($vars, $key = '') { - if ($key === '') + /*if ($key === '') $key = $this->windView->templateName; - $this->vars[$key] = $vars; + $this->vars[$key] = $vars;*/ } /** @@ -72,7 +85,7 @@ public function compile($template, $suffix = '', $output = false) { WindViewException::VIEW_NOT_EXIST); $compileFile = $this->windView->getCompileFile($template); - if (!$this->checkReCompile($templateFile, $compileFile)) + if (!$this->checkReCompile()) return array($compileFile, ''); /* @var $_windTemplate WindViewTemplate */ $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); @@ -84,30 +97,11 @@ public function compile($template, $suffix = '', $output = false) { return array($compileFile, $_output); } - /** - * 加载视图模板文件 - * @param template - */ - protected function render($template) { - list($_tmp) = $this->compile($template); - /*$_var = Wind::getApp()->getResponse()->getData('G'); - if (isset($this->vars[$template])) - $_var += $this->vars[$template];*/ - @extract(@$this->vars[$template], EXTR_REFS); - if (!@include ($_tmp)) { - throw new WindViewException( - '[component.viewer.ViewerResolver.render] template name ' . $template, - WindViewException::VIEW_NOT_EXIST); - } - } - /** * 检查是否需要重新编译,需要编译返回false,不需要编译返回true - * @param string $templateFile - * @param string $compileFile * @return boolean */ - private function checkReCompile($templateFile, $compileFile) { + private function checkReCompile() { return WIND_DEBUG || $this->getWindView()->isCompile; } @@ -128,4 +122,66 @@ public function getWindView() { return $this->windView; } + /** + * @return WindLayout + */ + public function getWindLayout() { + return $this->_getWindLayout('', $this); + } + +} + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindRender { + + /** + * Convert special characters to HTML entities + * + * @param string $text | + * @return string | string The converted string + */ + public static function encode($text) { + return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); + } + + /** + * Convert special characters to HTML entities + * + * @param array $data + * @return array + */ + public static function encodeArray($data) { + $_tmp = array(); + $_charset = Wind::getApp()->getRequest()->getCharset(); + foreach ($data as $key => $value) { + if (is_string($key)) + $key = htmlspecialchars($key, ENT_QUOTES, $_charset); + if (is_string($value)) + $value = htmlspecialchars($value, ENT_QUOTES, $_charset); + elseif (is_array($value)) + $value = self::encodeArray($value); + $_tmp[$key] = $value; + } + return $_tmp; + } + + /** + * @param string $tpl + * @param array $vars + * @param WindViewerResolver $viewer + * @throws WindViewException + */ + public static function render($tpl, $vars, $viewer) { + @extract($vars, EXTR_REFS); + if (!@include ($tpl)) { + throw new WindViewException( + '[component.viewer.ViewerResolver.render] template name ' . $tpl, + WindViewException::VIEW_NOT_EXIST); + } + } } \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerCss.php b/wind/component/viewer/compiler/WindTemplateCompilerCss.php new file mode 100644 index 00000000..e541f9c9 --- /dev/null +++ b/wind/component/viewer/compiler/WindTemplateCompilerCss.php @@ -0,0 +1,23 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerCss extends AbstractWindTemplateCompiler { + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + foreach ($this->windViewTemplate->getCompiledBlockData() as $key => $value) { + $content = str_replace('#' . $key . '#', ($value ? $value : ' '), $content); + } + $this->windViewerResolver->getWindLayout()->setcss($content); + return ''; + } +} + +?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php index 35d1d114..d6cfa107 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php @@ -1,6 +1,6 @@ '; else - return ''; + return ''; } } ?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerScript.php b/wind/component/viewer/compiler/WindTemplateCompilerScript.php index 9e5a074c..3894f182 100644 --- a/wind/component/viewer/compiler/WindTemplateCompilerScript.php +++ b/wind/component/viewer/compiler/WindTemplateCompilerScript.php @@ -7,25 +7,25 @@ * @package */ class WindTemplateCompilerScript extends AbstractWindTemplateCompiler { + protected $compile = 'true'; /* (non-PHPdoc) * @see AbstractWindTemplateCompiler::compile() */ public function compile($key, $content) { - $content = preg_replace_callback('/{\s*\$(\w)+((\-\>\w+)*(\(.*\))*(\[.*\])*)*?[;\s]*}/i', array($this, - 'doCompile'), $content); - return $content; + if ($this->compile === 'false') return $content; + foreach ($this->windViewTemplate->getCompiledBlockData() as $key => $value) { + $content = str_replace('#' . $key . '#', ($value ? $value : ' '), $content); + } + $this->windViewerResolver->getWindLayout()->setScript($content); + return ''; } /** - * 编译匹配到的结果 - * @param string $content + * 返回该标签支持的属性信息 */ - public function doCompile($content) { - if (empty($content)) - return ''; - $_output = preg_replace(array('/^[\n\s{]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content[0]); - return ''; + protected function getProperties() { + return array('compile'); } } diff --git a/wind/component/viewer/compiler/WindViewTemplate.php b/wind/component/viewer/compiler/WindViewTemplate.php index 25049e7f..35c5ce06 100644 --- a/wind/component/viewer/compiler/WindViewTemplate.php +++ b/wind/component/viewer/compiler/WindViewTemplate.php @@ -14,9 +14,6 @@ class WindViewTemplate extends AbstractWindViewTemplate { const COMPILER_ECHO = 'COM:viewer.compiler.WindTemplateCompilerEcho'; - /* 编译结果缓存 */ - protected $blockKey = ""; - protected $compiledBlockData = array(); /** @@ -38,7 +35,8 @@ protected function doCompile($content, $windViewerResolver = null) { $this->windHandlerInterceptorChain->getHandler()->handle(); } foreach (array_reverse($this->compiledBlockData) as $key => $value) { - if (!$key) continue; + if (!$key) + continue; $content = str_replace($this->getBlockTag($key), ($value ? $value : ' '), $content); } $content = preg_replace('/\?>(\s|\n)*?<\?php/i', "\r\n", $content); @@ -60,8 +58,10 @@ private function registerTags($content, $windViewerResolver = null) { $compiler = isset($value[self::COMPILER]) ? $value[self::COMPILER] : ''; $regex = isset($value[self::PATTERN]) ? $value[self::PATTERN] : ''; $tag = isset($value[self::TAG]) ? $value[self::TAG] : ''; - if (!$compiler || !$tag) continue; - if ($regex === '') $regex = '/<(' . preg_quote($tag) . ')[^<>\n]*(\/>|>[^<>]*<\/\1>)/i'; + if (!$compiler || !$tag) + continue; + if ($regex === '') + $regex = '/<(' . preg_quote($tag) . ')[^<>\n]*(\/>|>[^<>]*<\/\1>)/i'; $content = $this->creatTagCompiler($content, $compiler, $regex, $windViewerResolver); } return $content; @@ -93,16 +93,23 @@ private function creatTagCompiler($content, $compiler, $regex, $windViewerResolv protected function getTags() { $_tags['internal'] = $this->createTag('internal', 'COM:viewer.compiler.WindTemplateCompilerInternal', '/<\?php(.|\n)*?\?>/i'); - /*标签体增加在该位置*/ $_tags['template'] = $this->createTag('template', 'COM:viewer.compiler.WindTemplateCompilerTemplate'); + $_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', + '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); + $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); + /*标签体增加在该位置*/ $_tags['page'] = $this->createTag('page', 'COM:viewer.compiler.WindTemplateCompilerPage'); $_tags['action'] = $this->createTag('action', 'COM:viewer.compiler.WindTemplateCompilerAction'); + $_tags['script'] = $this->createTag('script', 'COM:viewer.compiler.WindTemplateCompilerScript', + '/()*/i'); + //$_tags['link'] = $this->createTag('link', 'COM:viewer.compiler.WindTemplateCompilerCss'); + //$_tags['style'] = $this->createTag('style', 'COM:viewer.compiler.WindTemplateCompilerCss'); $_tags['component'] = $this->createTag('component', 'COM:viewer.compiler.WindTemplateCompilerComponent'); /*标签解析结束*/ $_tags += (array) parent::getTags(); - $_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', + /*$_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); - $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); + $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i');*/ return $_tags; } @@ -122,7 +129,8 @@ private function createTag($tag, $class, $pattern = '') { */ private function _creatTagCompiler($content) { $_content = $content[0]; - if (!$_content) return ''; + if (!$_content) + return ''; $key = $this->getCompiledBlockKey(); $this->_compilerCache[] = array($key, $_content); @@ -139,8 +147,7 @@ private function _creatTagCompiler($content) { * @return string|mixed | 处理后结果 */ private function getBlockTag($key) { - if (!$this->blockKey) return ''; - return str_replace('$', $key, $this->blockKey); + return '#' . $key . '#'; } /** @@ -174,7 +181,8 @@ public function getCompiledBlockData($key = '') { * @param boolean $isTag | 再结果处理时是否添加php脚本定界符 true 添加 ,flase 不添加 */ public function setCompiledBlockData($key, $compiledBlockData) { - if ($key) $this->compiledBlockData[$key] = $compiledBlockData; + if ($key) + $this->compiledBlockData[$key] = $compiledBlockData; } } From 8cace25e9de50855d79dda320ff60b9e4972ad35 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 03:30:38 +0000 Subject: [PATCH 0415/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2487 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindSimpleController.php | 14 +++++++++++--- wind/core/web/WindWebApplication.php | 3 ++- wind/core/web/listener/WindFormListener.php | 12 ++++++++---- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index ab65c6de..16f1f9ad 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -143,14 +143,22 @@ protected function setTemplateExt($templateExt) { $this->getForward()->getWindView()->templateExt = $templateExt; } + /** + * 设置主题包位置 + * @param string $theme + * @return + */ + protected function setTheme($theme) { + $this->getForward()->getWindView()->thems = $theme; + } + /** * 设置页面布局 - * 可以是一个布局对象或者一个布局文件 - * @param WindLayout|string $layout + * @param string $layout * @return */ protected function setLayout($layout) { - $this->getForward()->getWindView()->setLayout($layout); + $this->getForward()->getWindView()->layout = $layout; } /* 错误处理 */ diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index e20bef93..576ed665 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -125,7 +125,8 @@ protected function resolveActionChain($__handler) { $__filters = $__handler->resolveActionFilter($this->handlerAdapter->getAction()); foreach ((array) $__filters as $__filter) { if (isset($__filter['expression']) && !empty($__filter['expression'])) { - var_dump(@eval('return ' . addcslashes($__filter['expression'], '"') . ';')); + if (!@eval('return ' . $__filter['expression'] . ';')) + continue; /*list($p, $v) = explode('=', $__filter['expression'] . '='); if ($this->getRequest()->getRequest($p) != $v) continue;*/ diff --git a/wind/core/web/listener/WindFormListener.php b/wind/core/web/listener/WindFormListener.php index ad18cda3..edc54f20 100644 --- a/wind/core/web/listener/WindFormListener.php +++ b/wind/core/web/listener/WindFormListener.php @@ -35,16 +35,14 @@ public function preHandle() { if (!class_exists($className)) throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); if ('WindEnableValidateModule' != get_parent_class($className)) - throw new WindException( - 'the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); + throw new WindException('the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); $form = new $className(); $methods = get_class_methods($form); foreach ($methods as $method) { if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) continue; $_tmp[0] = strtolower($_tmp[0]); - $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet( - $_tmp); + $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet($_tmp); if (null === $value) continue; call_user_func_array(array($form, $method), array($value)); @@ -64,6 +62,12 @@ private function sendError($errorController, $errorAction, $errors) { $this->errorMessage->sendError(); } + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + // TODO Auto-generated method stub + } } ?> \ No newline at end of file From 1963744888e9c6514e2e08cb8da72f867331c547 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 03:31:13 +0000 Subject: [PATCH 0416/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2488 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/WindHelper.php | 1 + wind/core/WindModule.php | 13 ------------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php index e8425bee..5d310429 100644 --- a/wind/core/WindHelper.php +++ b/wind/core/WindHelper.php @@ -79,6 +79,7 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { $trace[$key] = $traceLine; } /* format error code */ + $fileLines = array(); if (is_file($file)) { $currentLine = $line - 1; $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php index 3c80a0da..6f9de695 100644 --- a/wind/core/WindModule.php +++ b/wind/core/WindModule.php @@ -132,19 +132,6 @@ public function getConfig($configName = '', $subConfigName = '', $default = '', return $config[$configName][$subConfigName]; } - /** - * @return string|array - */ - public function _getConfig() { - $args = func_get_args(); - $_tmp = ''; - foreach ($args as $value) { - if (!isset($this->_config[$value])) - continue; - $_tmp = $this->_config[$value]; - } - } - /** * Config配置,如果配置信息已经存在,则会合并配置 * From 59b409bf0d29666f4f06a150c3299ee5575d6d17 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 03:31:28 +0000 Subject: [PATCH 0417/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2489 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wind/components_config.php b/wind/components_config.php index 43994a13..9778e06b 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -66,6 +66,15 @@ 'viewResolver' => array( 'path' => 'COM:viewer.WindViewerResolver', 'scope' => 'prototype', + 'properties' => array( + 'windLayout' => array( + 'ref' => 'layout', + ), + ), + ), + 'layout' => array( + 'path' => 'COM:viewer.WindLayout', + 'scope' => 'prototype', ), 'template' => array( 'path' => 'COM:viewer.compiler.WindViewTemplate', From 92be0f71a3b2c0423d81bd806407c9e3ef209d97 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 04:50:44 +0000 Subject: [PATCH 0418/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2490 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/web/WindSimpleController.php | 28 +++++++++------- wind/core/web/WindWebApplication.php | 45 ++++---------------------- 2 files changed, 23 insertions(+), 50 deletions(-) diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php index 16f1f9ad..c73ab5af 100644 --- a/wind/core/web/WindSimpleController.php +++ b/wind/core/web/WindSimpleController.php @@ -41,8 +41,23 @@ public function doAction($handlerAdapter) { /* (non-PHPdoc) * @see IWindController::resolveActionFilter($action) */ - public function resolveActionFilter($action) { - return array(); + protected function resolveActionFilter($__filters) { + @extract(@$this->getRequest()->getRequest(), EXTR_REFS); + $chain = WindFactory::createInstance('WindHandlerInterceptorChain'); + foreach ((array) $__filters as $__filter) { + if (isset($__filter['expression']) && !empty($__filter['expression'])) { + if (!@eval('return ' . $__filter['expression'] . ';')) + continue; + /*list($p, $v) = explode('=', $__filter['expression'] . '='); + if ($this->getRequest()->getRequest($p) != $v) + continue;*/ + } + $__args = array($this->getForward(), $this->getErrorMessage()); + if (isset($__filter['args'])) + $__args = $__args + (array) $__filter['args']; + $chain->addInterceptors(WindFactory::createInstance(Wind::import(@$__filter['class']), $__args)); + } + $chain->getHandler()->handle(); } /** @@ -287,14 +302,5 @@ interface IWindController { */ public function doAction($handlerAdapter); - /** - * 返回当前Action处理过滤连配置信息 - * - * - * - * @param string $action - * @return array - */ - public function resolveActionFilter($action); } ?> \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php index 576ed665..1f43ce92 100644 --- a/wind/core/web/WindWebApplication.php +++ b/wind/core/web/WindWebApplication.php @@ -28,8 +28,8 @@ class WindWebApplication extends WindModule implements IWindApplication { * @var WindRouter */ protected $handlerAdapter = null; - protected $defaultModule = array('controller-path' => 'controller', - 'controller-suffix' => 'Controller', 'error-handler' => 'WIND:core.web.WindErrorHandler'); + protected $defaultModule = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', + 'error-handler' => 'WIND:core.web.WindErrorHandler'); /** * 应用初始化操作 @@ -83,26 +83,22 @@ public function processRequest() { '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', 404); $module = WindUtility::mergeArray($this->defaultModule, $module); - $handlerPath = @$module['controller-path'] . '.' . ucfirst( - $this->handlerAdapter->getController()) . @$module['controller-suffix']; + $handlerPath = @$module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . @$module['controller-suffix']; if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( - '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, - 'wind.core'); + '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); $this->getSystemFactory()->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'prototype', 'proxy' => true, 'config' => $this->getConfig('actionmap'), 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), - 'forward' => array('ref' => 'forward'), - 'urlHelper' => array('ref' => 'urlHelper')))); + 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); if (!$handler) throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); - $this->resolveActionChain($handler); $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { $this->sendErrorMessage($e); @@ -111,34 +107,6 @@ public function processRequest() { } } - /** - * @param WindSimpleController $handler - * @throws WindActionException - */ - protected function resolveActionChain($__handler) { - /*if ($formClassPath = $handler->getConfig($_alias, 'form')) { - $handler->registerEventListener('doAction', - new WindFormListener($this->getRequest(), $formClassPath, - $this->getComponent('errorMessage'))); - }*/ - @extract(@$this->getRequest()->getRequest(), EXTR_REFS); - $__filters = $__handler->resolveActionFilter($this->handlerAdapter->getAction()); - foreach ((array) $__filters as $__filter) { - if (isset($__filter['expression']) && !empty($__filter['expression'])) { - if (!@eval('return ' . $__filter['expression'] . ';')) - continue; - /*list($p, $v) = explode('=', $__filter['expression'] . '='); - if ($this->getRequest()->getRequest($p) != $v) - continue;*/ - } - $__args = array($__handler->getForward(), $__handler->getErrorMessage()); - if (isset($__filter['args'])) - $__args = $__args + (array) $__filter['args']; - $__handler->registerEventListener('doAction', - WindFactory::createInstance(Wind::import(@$__filter['class']), $__args)); - } - } - /** * 异常处理请求 * @param WindActionException actionException @@ -164,8 +132,7 @@ protected function sendErrorMessage($exception) { $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', - array('controller-path' => $_errorHandler, 'controller-suffix' => '', - 'error-handler' => '')); + array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); From f3ee16855381e1111200428c69bf646465202168 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 05:54:36 +0000 Subject: [PATCH 0419/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2491 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/base/IWindApplication.php | 30 +++ wind/base/IWindFactory.php | 40 ++++ wind/base/WindActionException.php | 49 +++++ wind/base/WindClassProxy.php | 199 +++++++++++++++++++ wind/base/WindEnableValidateModule.php | 115 +++++++++++ wind/base/WindException.php | 95 +++++++++ wind/base/WindFactory.php | 258 +++++++++++++++++++++++++ wind/base/WindFinalException.php | 15 ++ wind/base/WindHelper.php | 203 +++++++++++++++++++ 9 files changed, 1004 insertions(+) create mode 100644 wind/base/IWindApplication.php create mode 100644 wind/base/IWindFactory.php create mode 100644 wind/base/WindActionException.php create mode 100644 wind/base/WindClassProxy.php create mode 100644 wind/base/WindEnableValidateModule.php create mode 100644 wind/base/WindException.php create mode 100644 wind/base/WindFactory.php create mode 100644 wind/base/WindFinalException.php create mode 100644 wind/base/WindHelper.php diff --git a/wind/base/IWindApplication.php b/wind/base/IWindApplication.php new file mode 100644 index 00000000..76691622 --- /dev/null +++ b/wind/base/IWindApplication.php @@ -0,0 +1,30 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindApplication { + + /** + * @return + */ + public function run(); + + /** + * @return WindHttpRequest $request + */ + public function getRequest(); + + /** + * @return WindHttpResponse $response + */ + public function getResponse(); + + /** + * @return WindFactory $windFactory + */ + public function getWindFactory(); +} +?> \ No newline at end of file diff --git a/wind/base/IWindFactory.php b/wind/base/IWindFactory.php new file mode 100644 index 00000000..5a208bca --- /dev/null +++ b/wind/base/IWindFactory.php @@ -0,0 +1,40 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindFactory { + + /** + * 描述:根据类的别名获得一个类实例变量 + * 返回:类的实例对象 + * + * 该方法首先通过类的别名到类的配置文件中找到类的相关配置信息, + * 加载类的路径并创建类的依赖 + * + * @param string $classAlias + * @return instance + */ + public function getInstance($classAlias); + + /** + * 根据类的别名返回一个类的实例变量的clone + * + * @param string $classAlias + * @return clone of instance + */ + public function getPrototype($classAlias); + + /** + * 根据类名称创建类对象 + * 返回一个类类型的实例对象,通过此方法创建类实例,并不能自动获取类路径信息 + * + * @param string $className | 类名称 + * @param array $args | 类参数信息 + * @return Object | 返回的类类型的实例对象 + */ + static public function createInstance($className, $args = array()); +} \ No newline at end of file diff --git a/wind/base/WindActionException.php b/wind/base/WindActionException.php new file mode 100644 index 00000000..44ed6575 --- /dev/null +++ b/wind/base/WindActionException.php @@ -0,0 +1,49 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindActionException extends WindException { + private $error; + + /** + * @param WindErrorMessage $error + */ + public function __construct($error, $code = 0) { + if ($error instanceof WindErrorMessage) { + $this->setError($error); + parent::__construct($error->getError(0), $code); + } else + parent::__construct($error, $code); + } + + /** + * 自定义异常号的对应异常信息 + * + * @param int $code 异常号 + * @return string 返回异常号对应的异常组装信息原型 + */ + protected function messageMapper($code) { + $messages = array(); + return isset($messages[$code]) ? $messages[$code] : '$message'; + } + + /** + * @return WindErrorMessage $error + */ + public function getError() { + return $this->error; + } + + /** + * @param WindErrorMessage $error + */ + public function setError($error) { + $this->error = $error; + } +} +?> \ No newline at end of file diff --git a/wind/base/WindClassProxy.php b/wind/base/WindClassProxy.php new file mode 100644 index 00000000..7c255c14 --- /dev/null +++ b/wind/base/WindClassProxy.php @@ -0,0 +1,199 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindClassProxy { + const EVENT_TYPE_METHOD = 'method'; + const EVENT_TYPE_SETTER = 'setter'; + const EVENT_TYPE_GETTER = 'getter'; + + private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; + private $_interceptorChainObj = null; + protected $_attributes = array(); + protected $_className = ''; + protected $_classPath = ''; + protected $_reflection = null; + protected $_instance = null; + protected $_listener = array(); + + /** + * @param object $targetObj + */ + public function __construct($targetObject = null) { + $targetObject && $this->registerTargetObject($targetObject); + } + + /* (non-PHPdoc) + * @see IWindClassProxy::registerAspect() + */ + public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { + if (!in_array($type, + array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { + throw new WindException( + '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, + WindException::ERROR_PARAMETER_TYPE_ERROR); + } + !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); + array_push($this->_listener[$type][$event], $listener); + } + + /** + * 注册目标对象,如果已经注册了不重复注册 + * @param object $targetObject + */ + public function registerTargetObject($targetObject) { + if ($this->_instance !== null || !is_object($targetObject)) + return; + $this->_setClassName(get_class($targetObject)); + $this->_instance = $targetObject; + $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); + foreach ($types as $type) + $this->_listener[$type] = array(); + return $this; + } + + /** + * @param string $propertyName + * @param $value + * @throws WindException + * @deprecated + */ + public function __set($propertyName, $value) { + $property = $this->_getReflection()->getProperty($propertyName); + if (!$property || !$property->isPublic()) { + throw new WindException('undefined property name. '); + } + $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); + if (empty($listeners)) + return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); + $interceptorChain = $this->_getInterceptorChain($propertyName); + $interceptorChain->addInterceptors($listeners); + $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); + return $interceptorChain->getHandler()->handle($value); + } + + /** + * @param unknown_type $propertyName + * @deprecated + */ + public function __get($propertyName) { + $property = $this->_getReflection()->getProperty($propertyName); + if (!$property || !$property->isPublic()) { + throw new WindException('undefined property name. '); + } + $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); + if (empty($listeners)) + return call_user_func_array(array($this, '_getProperty'), array($propertyName)); + $interceptorChain = $this->_getInterceptorChain($propertyName); + $interceptorChain->addInterceptors($listeners); + $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); + return $interceptorChain->getHandler()->handle($propertyName); + } + + /** + * @param string $methodName + * @param array $args + * @throws WindException + */ + public function __call($methodName, $args) { + $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); + if (empty($listeners)) + return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); + $interceptorChain = $this->_getInterceptorChain($methodName); + $interceptorChain->addInterceptors($listeners); + $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); + return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); + } + + /** + * @param string $event + * @return + */ + private function _getInterceptorChain($event = '') { + if (null === $this->_interceptorChainObj) { + $chain = Wind::import($this->_interceptorChain); + $interceptorChain = WindFactory::createInstance($chain); + if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { + $this->_interceptorChainObj = $interceptorChain; + } else + throw new WindException( + '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); + } + $this->_interceptorChainObj->reset(); + return $this->_interceptorChainObj; + } + + /** + * 根据监听器类型,返回对象的监听器对象 + * + * @param string $type + * @param string $subType + */ + private function _getListenerByType($type, $subType) { + $listener = array(); + if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { + $listener = $this->_listener[$type][$subType]; + } + return $listener; + } + + /* (non-PHPdoc) + * @see IWindClassProxy::_getInstance() + */ + public function _getInstance() { + return $this->_instance; + } + + /** + * @return string + */ + public function _getClassName() { + return $this->_className; + } + + /** + * @return string + */ + public function _getClassPath() { + return $this->_classPath; + } + + /** + * @param string $className + * @return + */ + public function _setClassName($className) { + $this->_className = $className; + } + + /** + * @param string $classPath + * @return + */ + public function _setClassPath($classPath) { + $this->_setClassName(Wind::import($classPath)); + $this->_classPath = $classPath; + } + + /** + * @param string $propertyName + * @param $value + */ + public function _setProperty($propertyName, $value) { + $this->_getInstance()->$propertyName = $value; + } + + /** + * @param string $propertyName + */ + public function _getProperty($propertyName) { + return $this->_getInstance()->$propertyName; + } +} +?> \ No newline at end of file diff --git a/wind/base/WindEnableValidateModule.php b/wind/base/WindEnableValidateModule.php new file mode 100644 index 00000000..d9086908 --- /dev/null +++ b/wind/base/WindEnableValidateModule.php @@ -0,0 +1,115 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindEnableValidateModule extends WindModule { + protected $_validatorClass = 'WIND:component.utility.WindValidator'; + protected $errorController = ''; + protected $errorAction = ''; + private $_validator = null; + private $_errors = array(); + private $_defaultMessage = 'the field validate fail.'; + + /** + * @return the $_errors + */ + public function getErrors() { + return $this->_errors; + } + + public function getErrorControllerAndAction() { + return array($this->errorController, $this->errorAction); + } + + /** + * 返回验证规则 + * + * validator : required/not-required + * @return multitype:multitype:string + */ + protected function validateRules() { + return array(); + } + + /** + * 验证方法 + * + * @param array|WindModule $input + */ + public function validate(&$input) { + if (is_array($input)) + $this->validateArray($input); + elseif (is_object($input)) + $this->validateObject($input); + } + + /** + * 验证数组类型的输入 + * @param array $input + */ + private function validateArray(&$input) { + $rules = $this->validateRules(); + foreach ((array) $rules as $rule) { + $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; + $arg = (array) $rule['args']; + array_unshift($arg, $_input); + if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; + if ($rule['default'] === null) { + $this->_errors[$rule['field']] = $rule['message']; + continue; + } + $input[$rule['field']] = $rule['default']; + } + } + + /** + * 验证对象类型的输入 + * 需要设置set和get方式 + * + * @param object $input 传入需要验证的数据 + * + */ + private function validateObject(&$input) { + $rules = $this->validateRules(); + $methods = get_class_methods($input); + foreach ((array) $rules as $rule) { + $getMethod = 'get' . ucfirst($rule['field']); + $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; + $arg = (array) $rule['args']; + array_unshift($arg, $_input); + if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; + if ($rule['default'] === null) { + $this->_errors[$rule['field']] = $rule['message']; + continue; + } + $setMethod = 'set' . ucfirst($rule['field']); + in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), + array($rule['default'])); + } + } + + /** + * @param WindValidator $validator + */ + protected function setValidator($validator) { + $this->_validator = $validator; + } + + /** + * 返回验证器 + * @return WindValidator + */ + protected function getValidator() { + if ($this->_validator === null) { + $_className = Wind::import($this->_validatorClass); + $this->_validator = WindFactory::createInstance($_className); + if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); + } + return $this->_validator; + } +} \ No newline at end of file diff --git a/wind/base/WindException.php b/wind/base/WindException.php new file mode 100644 index 00000000..afbd8103 --- /dev/null +++ b/wind/base/WindException.php @@ -0,0 +1,95 @@ + + * @author Qian Su + * @version $Id: WindException.php 37 2010-11-08 12:57:04Z weihu $ + * @package + */ +class WindException extends Exception { + /* 系统错误 */ + const ERROR_SYSTEM_ERROR = '0'; + /* 类错误 */ + const ERROR_CLASS_NOT_EXIST = '100'; + const ERROR_CLASS_TYPE_ERROR = '101'; + const ERROR_CLASS_METHOD_NOT_EXIST = '102'; + const ERROR_OBJECT_NOT_EXIST = '103'; + /* 参数错误 */ + const ERROR_PARAMETER_TYPE_ERROR = '110'; + /* 配置错误 */ + const ERROR_CONFIG_ERROR = '120'; + /* 返回值类型错误 */ + const ERROR_RETURN_TYPE_ERROR = '130'; + + private $innerException = null; + + /** + * 异常构造函数 + * @param $message 异常信息 + * @param $code 异常代号 + * @param $innerException 内部异常 + */ + public function __construct($message = '', $code = 0, Exception $innerException = null) { + $message = $this->buildMessage($message, $code); + parent::__construct($message, $code); + $this->innerException = $innerException; + } + + /** + * 取得内部异常 + */ + public function getInnerException() { + return $this->innerException; + } + + /** + * 取得异常堆栈信息 + */ + public function getStackTrace() { + if ($this->innerException) { + $thisTrace = $this->getTrace(); + $class = __CLASS__; + $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); + foreach ($innerTrace as $trace) + $thisTrace[] = $trace; + return $thisTrace; + } else { + return $this->getTrace(); + } + return array(); + } + + /** + * 组装异常信息 + * + * 根据输入的异常号组装相对应的异常信息 + * + * @param string $message 用户自定义的信息 + * @param int $code 异常号 + * @return string 组装后的异常信息 + */ + public function buildMessage($message, $code) { + $message = str_replace(array("
", "
", "\r\n"), '', $message); + eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); + return $message; + } + + /** + * 自定义异常号的对应异常信息 + * + * @param int $code 异常号 + * @return string 返回异常号对应的异常组装信息原型 + */ + protected function messageMapper($code) { + $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', + self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', + self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', + self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', + self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', + self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', + self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', + self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); + return isset($messages[$code]) ? $messages[$code] : '$message'; + } +} \ No newline at end of file diff --git a/wind/base/WindFactory.php b/wind/base/WindFactory.php new file mode 100644 index 00000000..eca4656f --- /dev/null +++ b/wind/base/WindFactory.php @@ -0,0 +1,258 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFactory implements IWindFactory { + protected $proxyType = 'WIND:core.factory.WindClassProxy'; + protected $classDefinitions = array(); + protected $instances = array(); + protected $prototype = array(); + + /** + * 初始化抽象工厂类 + * 可以通过两种方式初始化该工厂 + * 1. 直接传递一个解析好的类配置信息 + * @param string $configFile + */ + public function __construct($classDefinitions = array()) { + if (is_array($classDefinitions)) { + $this->classDefinitions = $classDefinitions; + } + } + + /* (non-PHPdoc) + * @see AbstractWindFactory::getInstance() + */ + public function getInstance($alias, $args = array()) { + $instance = null; + $definition = isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : array(); + if (isset($this->prototype[$alias])) { + $instance = clone $this->prototype[$alias]; + } elseif (isset($this->instances[$alias])) { + $instance = $this->instances[$alias]; + } else { + if (!$definition) + throw new WindException( + '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); + + if (isset($definition['constructor-arg'])) + foreach ((array) $definition['constructor-arg'] as $_var) { + if (isset($_var['value'])) { + $args[] = $_var['value']; + } elseif (isset($_var['ref'])) + $args[] = $this->getInstance($_var['ref']); + } + if (!isset($definition['className'])) + $definition['className'] = Wind::import(@$definition['path']); + $instance = $this->createInstance($definition['className'], $args); + if (isset($definition['config'])) + $this->resolveConfig($definition['config'], $alias, $instance); + if (isset($definition['properties'])) + $this->buildProperties($definition['properties'], $instance); + if (isset($definition['initMethod'])) + $this->executeInitMethod($definition['initMethod'], $instance); + !isset($definition['scope']) && $definition['scope'] = 'application'; + $this->setScope($alias, $definition['scope'], $instance); + } + + if (isset($definition['proxy'])) + $instance = $this->setProxyForClass($definition['proxy'], $instance); + return $instance; + } + + /** + * 对象组件对象到应用工厂中 + * @param object $instance + * @param string $alias + * @param string $scope + * @return boolean + */ + public function registInstance($instance, $alias, $scope = 'singleton') { + if (!is_object($instance) || !$alias) + return false; + return $this->setScope($alias, $scope, $instance); + } + + /* (non-PHPdoc) + * @see AbstractWindFactory::createInstance() + */ + static public function createInstance($className, $args = array()) { + try { + if (!$className || !class_exists($className)) + throw new WindException('class is not exist.'); + if (empty($args)) { + return new $className(); + } else { + $reflection = new ReflectionClass($className); + return call_user_func_array(array($reflection, 'newInstance'), (array) $args); + } + } catch (Exception $e) { + throw new WindException( + '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), + WindException::ERROR_CLASS_NOT_EXIST); + } + } + + /* (non-PHPdoc) + * @see IWindFactory::getPrototype() + */ + public function getPrototype($alias) { + return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; + } + + /** + * 动态添加类定义对象 + * @param string $alias + * @param array $classDefinition + * @return + */ + public function addClassDefinitions($alias, $classDefinition) { + if (is_string($alias) && !empty($alias)) { + if (!isset($this->classDefinitions[$alias])) + $this->classDefinitions[$alias] = $classDefinition; + } else + throw new WindException( + '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', + WindException::ERROR_PARAMETER_TYPE_ERROR); + } + + /** + * 加载类定义,如果merge为true,则覆盖原有配置信息 + * @param array $classDefinitions + * @param boolean $merge + * @return + */ + public function loadClassDefinitions($classDefinitions, $merge = true) { + foreach ((array) $classDefinitions as $alias => $definition) { + if (!is_array($definition)) + continue; + if (!isset($this->classDefinitions[$alias]) || $merge === false) { + $this->classDefinitions[$alias] = $definition; + continue; + } + $this->classDefinitions[$alias] = WindUtility::mergeArray( + $this->classDefinitions[$alias], $definition); + unset($this->instances[$alias], $this->prototype[$alias]); + } + } + + /** + * 类定义检查,检查类型以是否已经存在 + * @param array $definition + * @return boolean + */ + public function checkAlias($alias) { + if (isset($this->prototype[$alias])) + return true; + elseif (isset($this->instances[$alias])) + return true; + return false; + } + + /** + * @param string $alias + * @param string $scope + * @param object $instance + */ + protected function setScope($alias, $scope, $instance) { + switch ($scope) { + case 'prototype': + $this->prototype[$alias] = clone $instance; + break; + case 'application': + $this->instances[$alias] = $instance; + break; + default: + $this->instances[$alias] = $instance; + break; + + } + return true; + } + + /** + * 为类对象设置配置 + * @param array|string $config + * @param string $alias + * @param WindModule $instance + * @return + */ + protected function resolveConfig($config, $alias, $instance) { + if (isset($config['resource'])) { + $_configPath = Wind::getRealPath($config['resource'], true); + $configParser = $this->getInstance('configParser'); + $config = $configParser->parse($_configPath, $alias, true, + Wind::getApp()->getComponent('windCache')); + } + if ($config && method_exists($instance, 'setConfig')) + $instance->setConfig($config); + } + + /** + * 执行用户配置的初始化操作 + * @param string $initMethod + * @param object $instance + * @return + */ + protected function executeInitMethod($initMethod, $instance) { + try { + return call_user_func_array(array($instance, $initMethod), array()); + } catch (Exception $e) { + throw new WindException( + '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); + } + } + + /** + * 为类设置代理 + * @param string $definition + * @param WindModule $instance + * @return WindClassProxy + */ + protected function setProxyForClass($proxy, $instance) { + if ($proxy === 'false' || $proxy === false) + return $instance; + + if ($proxy === 'true' || $proxy === true) + $proxy = $this->proxyType; + $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); + return $this->getInstance($proxy)->registerTargetObject($instance); + } + + /** + * 将类实例的依赖注入到类实例中 + * @param string $properties + * @param WindModule $instance + */ + protected function buildProperties($properties, $instance) { + if (!isset($properties['delay'])) { + $instance->setDelayAttributes($properties); + } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { + foreach ($properties as $key => $subDefinition) { + $_value = ''; + if (isset($subDefinition['value'])) + $_value = $subDefinition['value']; + elseif (isset($subDefinition['ref'])) + $_value = $this->getInstance($subDefinition['ref']); + elseif (isset($subDefinition['path'])) { + $_className = Wind::import($subDefinition['path']); + $_value = $this->createInstance($_className); + } + $_setter = 'set' . ucfirst(trim($key, '_')); + if (method_exists($instance, $_setter)) + call_user_func_array(array($instance, $_setter), array($_value)); + } + } else + $instance->setDelayAttributes($properties); + } +} \ No newline at end of file diff --git a/wind/base/WindFinalException.php b/wind/base/WindFinalException.php new file mode 100644 index 00000000..74e2f050 --- /dev/null +++ b/wind/base/WindFinalException.php @@ -0,0 +1,15 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFinalException extends Exception{ + + +} + +?> \ No newline at end of file diff --git a/wind/base/WindHelper.php b/wind/base/WindHelper.php new file mode 100644 index 00000000..5d310429 --- /dev/null +++ b/wind/base/WindHelper.php @@ -0,0 +1,203 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHelper { + const INTERNAL_LOCATION = "~Internal Location~"; + protected static $errorDir = 'WIND:core.web.view'; + protected static $errorPage = 'error.htm'; + + /** + * 错误处理句柄 + * @param string $errno + * @param string $errstr + * @param string $errfile + * @param string $errline + */ + public static function errorHandle($errno, $errstr, $errfile, $errline) { + if ($errno & error_reporting()) { + restore_error_handler(); + restore_exception_handler(); + $trace = debug_backtrace(); + unset($trace[0]["function"], $trace[0]["args"]); + self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); + } + } + + /** + * 异常处理句柄 + * @param Exception $exception + */ + public static function exceptionHandle($exception) { + restore_error_handler(); + restore_exception_handler(); + $trace = $exception->getTrace(); + if (@$trace[0]['file'] == '') { + unset($trace[0]); + $trace = array_values($trace); + } + $file = @$trace[0]['file']; + $line = @$trace[0]['line']; + self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); + } + + /** + * @param string $message + * @param string $file + * @param string $line + * @param array $trace + */ + protected static function crash($message, $file, $line, $trace, $status = 0) { + $errmessage = substr($message, 0, 8000); + $_headers = Wind::getApp()->getResponse()->getHeaders(); + $_errhtml = false; + foreach ($_headers as $_header) { + if (strtolower($_header['name']) == strtolower('Content-type')) { + $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; + break; + } + } + $msg = ''; + if (WIND_DEBUG) { + $_errorPage = 'error.htm'; + /* format error trace */ + $count = count($trace); + $padLen = strlen($count); + foreach ($trace as $key => $call) { + if (!isset($call['file']) || $call['file'] == '') { + $call['file'] = self::INTERNAL_LOCATION; + $call['line'] = 'N/A'; + } + $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( + $call); + $trace[$key] = $traceLine; + } + /* format error code */ + $fileLines = array(); + if (is_file($file)) { + $currentLine = $line - 1; + $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); + $topLine = $currentLine - 5; + $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); + if (($count = count($fileLines)) > 0) { + $padLen = strlen($count); + foreach ($fileLines as $line => &$fileLine) + $fileLine = " " . htmlspecialchars( + str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( + "\t", " ", rtrim($fileLine)), null, "UTF-8"); + } + } + $msg .= "$file\n" . implode("\n", $fileLines) . "\n" . implode("\n", $trace); + } else + $_errorPage = '404.htm'; + + if ($status >= 400 && $status <= 505) { + $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); + $topic = "$status - " . $_statusMsg . "\n"; + } else + $topic = "Wind Framework - Error Caught"; + + $msg = "$topic\n$errmessage\n" . $msg . "\n\n" . self::errorInfo(); + + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', + true); + + if ($_errhtml) { + ob_start(); + $errDir = Wind::getApp()->getConfig('errorpage'); + !$errDir && $errDir = self::$errorDir; + if (isset($_statusMsg)) { + header('HTTP/1.x ' . $status . ' ' . $_statusMsg); + header('Status: ' . $status . ' ' . $_statusMsg); + is_file(Wind::getRealPath($errDir) . '.' . $status . '.htm') && $_errorPage = $status . '.htm'; + } + require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, + true); + $msg = ob_get_clean(); + } + $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~/', $msg); + die($msg); + } + + /** + * @param array $call + * @return string + */ + private static function getCallLine($call) { + $call_signature = ""; + if (isset($call['file'])) + $call_signature .= $call['file'] . " "; + if (isset($call['line'])) + $call_signature .= "(" . $call['line'] . ") "; + if (isset($call['function'])) { + $call_signature .= $call['function'] . "("; + if (isset($call['args'])) { + foreach ($call['args'] as $arg) { + if (is_string($arg)) + $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; + else if (is_object($arg)) + $arg = "[Instance of '" . get_class($arg) . "']"; + else if ($arg === true) + $arg = "true"; + else if ($arg === false) + $arg = "false"; + else if ($arg === null) + $arg = "null"; + else + $arg = strval($arg); + $call_signature .= $arg . ','; + } + } + $call_signature = trim($call_signature, ',') . ")"; + } + return $call_signature; + } + + /** + * @param int $errorNumber + * @return string + */ + protected static function getErrorName($errorNumber) { + $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", + E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", + E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", + E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", + E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", + E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); + return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; + } + + public static function errorInfo() { + $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; + $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; + return $info; + } + + /** + * 解析ControllerPath + * 返回解析后的controller信息,controller,module,app + * + * @param string $controllerPath + * @return array + */ + public static function resolveController($controllerPath) { + $_m = $_c = ''; + if (!$controllerPath) + return array($_c, $_m); + if (false !== ($pos = strrpos($controllerPath, '.'))) { + $_m = substr($controllerPath, 0, $pos); + $_c = substr($controllerPath, $pos + 1); + } else { + $_c = $controllerPath; + } + return array($_c, $_m); + } +} +?> \ No newline at end of file From 95efc46760c78b9f18b80deec86858d6f3673f60 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 06:01:18 +0000 Subject: [PATCH 0420/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2492 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindController.php | 35 +++ wind/web/WindDispatcher.php | 117 ++++++++ wind/web/WindErrorHandler.php | 44 +++ wind/web/WindForward.php | 205 ++++++++++++++ wind/web/WindSimpleController.php | 306 +++++++++++++++++++++ wind/web/WindSystemConfig.php | 243 ++++++++++++++++ wind/web/WindUrlHelper.php | 25 ++ wind/web/WindWebApplication.php | 247 +++++++++++++++++ wind/web/filter/WindUrlFilter.php | 26 ++ wind/web/listener/WindFormListener.php | 73 +++++ wind/web/listener/WindValidateListener.php | 96 +++++++ wind/web/view/404.htm | 140 ++++++++++ wind/web/view/error.htm | 155 +++++++++++ wind/web/view/erroraction.htm | 45 +++ 14 files changed, 1757 insertions(+) create mode 100644 wind/web/WindController.php create mode 100644 wind/web/WindDispatcher.php create mode 100644 wind/web/WindErrorHandler.php create mode 100644 wind/web/WindForward.php create mode 100644 wind/web/WindSimpleController.php create mode 100644 wind/web/WindSystemConfig.php create mode 100644 wind/web/WindUrlHelper.php create mode 100644 wind/web/WindWebApplication.php create mode 100644 wind/web/filter/WindUrlFilter.php create mode 100644 wind/web/listener/WindFormListener.php create mode 100644 wind/web/listener/WindValidateListener.php create mode 100644 wind/web/view/404.htm create mode 100644 wind/web/view/error.htm create mode 100644 wind/web/view/erroraction.htm diff --git a/wind/web/WindController.php b/wind/web/WindController.php new file mode 100644 index 00000000..8c70fea6 --- /dev/null +++ b/wind/web/WindController.php @@ -0,0 +1,35 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class WindController extends WindSimpleController { + + /* (non-PHPdoc) + * @see WindAction::resolvedActionMethod() + */ + protected function resolvedActionMethod($handlerAdapter) { + $action = $handlerAdapter->getAction(); + if ($action !== 'run') + $action = $this->resolvedActionName($action); + if ($action == 'doAction') + throw new WindException('[core.web.WindController.resolvedActionMethod]', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); + $method = new ReflectionMethod($this, $action); + if ($method->isAbstract() || !$method->isPublic()) { + throw new WindException('[core.web.WindController.resolvedActionMethod]', + WindException::ERROR_CLASS_METHOD_NOT_EXIST); + } + return $action; + } + + /** + * @param string $action + * @throws WindException + */ + protected function resolvedActionName($action) { + return $action . 'Action'; + } +} \ No newline at end of file diff --git a/wind/web/WindDispatcher.php b/wind/web/WindDispatcher.php new file mode 100644 index 00000000..29039784 --- /dev/null +++ b/wind/web/WindDispatcher.php @@ -0,0 +1,117 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindDispatcher extends WindModule { + /** + * 将上一次请求信息缓存在这个变量中 + * @var array + */ + protected $token; + /** + * @var boolean + */ + protected $display = false; + + /** + * 请求分发处理 + * + * @param WindForward $forward + * @param WindRouter $router + * @param boolean $display + * @return + */ + public function dispatch($forward, $router, $display) { + $this->checkToken($router, false); + if ($forward->getIsRedirect()) + $this->dispatchWithRedirect($forward, $router); + elseif ($forward->getIsReAction()) + $this->dispatchWithAction($forward, $router, $display); + else { + $view = $forward->getWindView(); + if ($view->templateName) { + $vars = $forward->getVars(); + Wind::getApp()->getResponse()->setData($vars, $view->templateName); + Wind::getApp()->getResponse()->setData($vars['G'], true); + $view->render($forward, $router, $this->display); + } + $this->display = false; + } + } + + /** + * 请求分发一个重定向请求 + * @param WindForward $forward + * @param WindUrlBasedRouter $router + * @return + */ + protected function dispatchWithRedirect($forward, $router) { + $_url = $forward->getUrl(); + if (!$_url && $forward->getIsReAction()) { + $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), + $forward->getController(), $forward->getArgs()); + if ($this->checkToken($router)) + throw new WindFinalException( + '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, + WindException::ERROR_SYSTEM_ERROR); + + } else + $_url = $this->_getUrlHelper()->checkUrl($_url); + $this->getResponse()->sendRedirect($_url); + } + + /** + * 请求分发一个操作请求 + * module/controller/action/?param + * @param WindForward $forward + * @param WindRouter $router + * @param boolean $display + * @return + */ + protected function dispatchWithAction($forward, $router, $display) { + if (!$action = $forward->getAction()) + throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', + WindException::ERROR_PARAMETER_TYPE_ERROR); + + $args = $forward->getArgs(); + $this->display = $display; + list($action, $_args) = explode('?', $action . '?'); + $action = trim($action, '/') . '/'; + $action = explode('/', $action); + end($action); + if ($_tmp = prev($action)) + $router->setAction($_tmp); + if ($_tmp = prev($action)) + $router->setController($_tmp); + if ($_tmp = prev($action)) + $router->setModule($_tmp); + if ($this->checkToken($router)) + throw new WindFinalException( + '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, + WindException::ERROR_SYSTEM_ERROR); + + Wind::getApp()->processRequest(); + } + + /** + * 检查请求是否是重复请求 + * @param WindUrlBasedRouter $router + * @param boolean $check + * @return boolean + */ + protected function checkToken($router, $check = true) { + $token = $router->getModule() . '/' . $router->getController() . '/' . $router->getAction(); + if ($check === false) { + $this->token = $token; + } else + return !strcasecmp($token, $this->token); + } + +} diff --git a/wind/web/WindErrorHandler.php b/wind/web/WindErrorHandler.php new file mode 100644 index 00000000..e5a08652 --- /dev/null +++ b/wind/web/WindErrorHandler.php @@ -0,0 +1,44 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindErrorHandler extends WindController { + protected $error = array(); + protected $errorCode = 0; + protected $urlReferer = ''; + protected $errorDir = 'WIND:core.web.view'; + + /* (non-PHPdoc) + * @see WindAction::beforeAction() + */ + public function beforeAction($handlerAdapter) { + $this->error = $this->getInput('error'); + $this->errorCode = (int) $this->getInput('errorCode'); + if ($this->request->getUrlReferer()) + $this->urlReferer = $this->getRequest()->getUrlReferer(); + else + $this->urlReferer = $this->getRequest()->getBaseUrl(); + } + + /* (non-PHPdoc) + * @see WindAction::run() + */ + public function run() { + if ($this->errorCode >= 400 && $this->errorCode <= 505) { + $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); + $topic = "$this->errorCode - " . $_statusMsg; + $this->getResponse()->setStatus($this->errorCode); + } else + $topic = "Error message"; + $this->setOutput($topic, "errorHeader"); + $this->setOutput($this->urlReferer, "baseUrl"); + $this->setOutput($this->error, "errors"); + $errDir = Wind::getApp()->getConfig('errorpage'); + !$errDir && $errDir = $this->errorDir; + $this->setTemplatePath($errDir); + $this->setTemplate('erroraction'); + } +} \ No newline at end of file diff --git a/wind/web/WindForward.php b/wind/web/WindForward.php new file mode 100644 index 00000000..4ad03521 --- /dev/null +++ b/wind/web/WindForward.php @@ -0,0 +1,205 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindForward extends WindModule { + /** + * 定义视图处理器 + * @var WindView + */ + protected $windView = null; + /** + * 模板变量信息 + * @var array + */ + private $vars = array('G' => array()); + /** + * 是否为Action请求 + * @var boolean + */ + private $isReAction = false; + /** + * 是否是重定向请求 + * @var boolean + */ + private $isRedirect = false; + /** + * 跳转链接 + * @var string + */ + private $url; + private $action; + private $controller; + private $args; + + /** + * 将请求重定向到另外一个Action操作 + * @param string $action | $action 操作 + * @param string $controller | controller 路径 , controller 为空是则指向当前的控制器 + * @param array $args | 参数 + * @param boolean $isRedirect | 是否重定向 + * + * @return + */ + public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { + $this->setIsReAction(true); + $this->setAction($action); + $this->setController($controller); + $this->setArgs($args); + $this->setIsRedirect($isRedirect); + } + + /** + * 将请求重定向到另外一个Action操作 + * $action参数支持: + * module/controller/action/?a=&b=&c= + * + * @param string $action | $action 操作 + * @param array $args | 参数 + * @param boolean $isRedirect | 是否重定向 + * @return + */ + public function forwardAction($action, $args = array(), $isRedirect = false) { + $this->setIsReAction(true); + $this->setAction($action); + $this->setArgs($args); + $this->setIsRedirect($isRedirect); + } + + /** + * 设置页面模板变量 + * + * @param string|array|object $vars + * @param string $key + */ + public function setVars($vars, $key = '', $isG = false) { + if (!$key) { + if (is_object($vars)) + $vars = get_object_vars($vars); + if (is_array($vars)) + if ($isG) + $this->vars['G'] = $vars; + else + $this->vars += $vars; + } else { + if ($isG) + $this->vars['G'][$key] = $vars; + else + $this->vars[$key] = $vars; + } + } + + /** + * @return the $isRedirect + */ + public function getIsRedirect() { + return $this->isRedirect; + } + + /** + * @param boolean $isRedirect + */ + public function setIsRedirect($isRedirect) { + $this->isRedirect = $isRedirect; + } + + /** + * @return the $isReAction + */ + public function getIsReAction() { + return $this->isReAction; + } + + /** + * @param boolean $isReAction + */ + public function setIsReAction($isReAction) { + $this->isReAction = $isReAction; + } + + /** + * @return the $vars + */ + public function getVars() { + return $this->vars; + } + + /** + * @return the $url + */ + public function getUrl() { + return $this->url; + } + + /** + * @param string $url + */ + public function setUrl($url) { + $this->url = $url; + } + + /** + * @return the $action + */ + public function getAction() { + return $this->action; + } + + /** + * @return the $controller + */ + public function getController() { + return $this->controller; + } + + /** + * @return the $args + */ + public function getArgs() { + return $this->args; + } + + /** + * @param field_type $action + */ + public function setAction($action) { + $this->action = $action; + } + + /** + * @param field_type $controller + */ + public function setController($controller) { + $this->controller = $controller; + } + + /** + * @param field_type $args + */ + public function setArgs($args) { + $this->args = $args; + } + + /** + * @return WindView + */ + public function getWindView() { + if ($this->windView === null) + $this->_getWindView(); + $module = Wind::getApp()->getModules(); + isset($module['template-dir']) && $this->windView->templateDir = $module['template-dir']; + isset($module['compile-dir']) && $this->windView->compileDir = $module['compile-dir']; + return $this->windView; + } + + /** + * @param WindView $windView + */ + public function setWindView($windView) { + $this->windView = $windView; + } +} \ No newline at end of file diff --git a/wind/web/WindSimpleController.php b/wind/web/WindSimpleController.php new file mode 100644 index 00000000..c73ab5af --- /dev/null +++ b/wind/web/WindSimpleController.php @@ -0,0 +1,306 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class WindSimpleController extends WindModule implements IWindController { + protected $_vars = array(); + /** + * @var WindForward + */ + protected $forward = null; + /** + * @var WindErrorMessage + */ + protected $errorMessage = null; + + /** + * 默认的操作处理方法 + */ + abstract public function run(); + + /* (non-PHPdoc) + * @see IWindController::doAction() + */ + public function doAction($handlerAdapter) { + if ($this->forward !== null) + $this->_vars = $this->forward->getVars(); + $this->beforeAction($handlerAdapter); + $this->setDefaultTemplateName($handlerAdapter); + $method = $this->resolvedActionMethod($handlerAdapter); + call_user_func_array(array($this, $method), array()); + if ($this->errorMessage !== null) + $this->getErrorMessage()->sendError(); + $this->afterAction($handlerAdapter); + return $this->forward; + } + + /* (non-PHPdoc) + * @see IWindController::resolveActionFilter($action) + */ + protected function resolveActionFilter($__filters) { + @extract(@$this->getRequest()->getRequest(), EXTR_REFS); + $chain = WindFactory::createInstance('WindHandlerInterceptorChain'); + foreach ((array) $__filters as $__filter) { + if (isset($__filter['expression']) && !empty($__filter['expression'])) { + if (!@eval('return ' . $__filter['expression'] . ';')) + continue; + /*list($p, $v) = explode('=', $__filter['expression'] . '='); + if ($this->getRequest()->getRequest($p) != $v) + continue;*/ + } + $__args = array($this->getForward(), $this->getErrorMessage()); + if (isset($__filter['args'])) + $__args = $__args + (array) $__filter['args']; + $chain->addInterceptors(WindFactory::createInstance(Wind::import(@$__filter['class']), $__args)); + } + $chain->getHandler()->handle(); + } + + /** + * @param AbstractWindRouter $handlerAdapter + */ + protected function beforeAction($handlerAdapter) {} + + /** + * @param AbstractWindRouter $handlerAdapter + */ + protected function afterAction($handlerAdapter) {} + + /** + * 重定向一个请求到另外的Action + * @param string $action + * @param array $args + * @param boolean $isRedirect + * @return + */ + protected function forwardAction($action = 'run', $args = array(), $isRedirect = false) { + //$this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); + $this->getForward()->forwardAction($action, $args, $isRedirect); + } + + /** + * 重定向一个请求到另外的URL + * @param string $url + * @return + */ + protected function forwardRedirect($url) { + $this->getForward()->setIsRedirect(true); + $this->getForward()->setUrl($url); + } + + /* 数据处理 */ + /** + * 设置模板数据 + * @param string|array|object $data + * @param string $key + * @return + */ + protected function setOutput($data, $key = '') { + $this->getForward()->setVars($data, $key); + } + + /** + * 设置模板数据 + * @param string|array|object $data + * @param string $key + * @return + */ + protected function setGlobal($data, $key = '') { + $this->getForward()->setVars($data, $key, true); + } + + /** + * 获得输入数据 + * 如果输入了回调方法则返回数组: + * 第一个值:value + * 第二个值:验证结果 + * @param string $name input name + * @param string $type input type (GET POST COOKIE) + * @param string $callback | validation for input + * @return array | string + */ + protected function getInput($name, $type = '', $callback = null) { + if (is_array($name)) + return $this->getInputWithArray($name, $type); + else + return $this->getInputWithString($name, $type, $callback); + } + + /* 模板处理 */ + /** + * 设置页面模板 + * @param string $template + * @return + */ + protected function setTemplate($template) { + $this->getForward()->getWindView()->templateName = $template; + } + + /** + * 设置模板路径 + * @param string $templatePath + * @return + */ + protected function setTemplatePath($templatePath) { + $this->getForward()->getWindView()->templateDir = $templatePath; + } + + /** + * 设置模板文件的扩展名 + * @param string $templateExt + * @return + */ + protected function setTemplateExt($templateExt) { + $this->getForward()->getWindView()->templateExt = $templateExt; + } + + /** + * 设置主题包位置 + * @param string $theme + * @return + */ + protected function setTheme($theme) { + $this->getForward()->getWindView()->thems = $theme; + } + + /** + * 设置页面布局 + * @param string $layout + * @return + */ + protected function setLayout($layout) { + $this->getForward()->getWindView()->layout = $layout; + } + + /* 错误处理 */ + /** + * 添加错误信息 + * @param string $message + * @param string $key + * @return + */ + protected function addMessage($message, $key = '') { + $this->getErrorMessage()->addError($message, $key); + } + + /** + * 发送一个错误 + * @param string $message + * @param string $key + * @param string $errorAction + * @return + */ + protected function showMessage($message = '', $key = '', $errorAction = '') { + $this->addMessage($message, $key); + $this->getErrorMessage()->setErrorAction($errorAction); + $this->getErrorMessage()->sendError(); + } + + /** + * 设置默认的模板名称 + * @param WindUrlBasedRouter $handlerAdapter + * @return + */ + protected function setDefaultTemplateName($handlerAdapter) {} + + /** + * 定义了一种解析策略,使其通过解析请求信息来获得调用的方法。 + * + * @param WindUrlBasedRouter $handlerAdapter + * @return + */ + protected function resolvedActionMethod($handlerAdapter) { + return 'run'; + } + + /** + * @param string $name + * @param string $type + * @param array $callback + * @return Ambigous + */ + private function getInputWithString($name, $type = '', $callback = array()) { + $value = ''; + switch (strtolower($type)) { + case 'form': + $value = $this->getRequest()->getData($name); + break; + case IWindRequest::INPUT_TYPE_GET: + $value = $this->getRequest()->getGet($name); + break; + case IWindRequest::INPUT_TYPE_POST: + $value = $this->getRequest()->getPost($name); + break; + case IWindRequest::INPUT_TYPE_COOKIE: + $value = $this->getRequest()->getCookie($name); + break; + default: + $value = $this->getRequest()->getAttribute($name); + } + return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; + } + + /** + * @param array $name + * @param string $type + * @return array + */ + private function getInputWithArray($name, $type = '') { + $result = array(); + foreach ($name as $key => $value) { + $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); + } + return $result; + } + + /** + * @return WindForward + */ + public function getForward() { + return $this->_getForward(); + } + + /** + * @return WindErrorMessage + */ + public function getErrorMessage() { + return $this->_getErrorMessage(); + } + + /** + * @param WindForward $forward + */ + public function setForward($forward) { + $this->forward = $forward; + } + + /** + * @param WindErrorMessage $errorMessage + */ + public function setErrorMessage($errorMessage) { + $this->errorMessage = $errorMessage; + } + +} + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindController { + + /** + * 处理请求并返回Forward对象 + * @param WindUrlBasedRouter $handlerAdapter + * @return WindForward + */ + public function doAction($handlerAdapter); + +} +?> \ No newline at end of file diff --git a/wind/web/WindSystemConfig.php b/wind/web/WindSystemConfig.php new file mode 100644 index 00000000..54b8f800 --- /dev/null +++ b/wind/web/WindSystemConfig.php @@ -0,0 +1,243 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindSystemConfig extends WindModule { + private $appName = ''; + private $modules = array(); + + /** + * @param string $config + * @param string $appName + * @param WindFactory $factory + */ + public function __construct($config, $appName, $factory) { + $this->appName = $appName; + $this->setConfig($config, $factory); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config, $factory = null) { + if (empty($config)) + return; + if (is_string($config)) { + $configParser = $factory->getInstance('configParser'); + $config = $configParser->parse($config); + if (isset($config[$this->appName])) + $this->_config = $config[$this->appName]; + } else + $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; + } + + /** + * @return the $appName + */ + public function getAppName() { + return $this->appName; + } + + /** + * 返回当前应用的启动脚本位置 + */ + public function getAppClass($default = '') { + return $this->getConfig('class', '', $default); + } + + /** + * 返回应用编码信息 + */ + public function getCharset() { + return $this->getConfig('charset', '', 'utf-8'); + } + + /** + * 返回配置定义中定义的过滤链列表 + * 如果定义$name则返回在filters定义标签内对应的属性值 + * + * @param string $name + * @return array|string + */ + public function getFilters() { + return $this->getConfig('filters'); + } + + /** + * 返回filterChain的类型 + * + * @return array + */ + public function getFilterClass() { + return $this->getConfig('filters', 'class'); + } + + /** + * @param string $name + * @return array|string + */ + public function getRouter() { + return $this->getConfig('router'); + } + + /** + * 返回路由类型定义 + * @return string + */ + public function getRouterClass() { + return $this->getConfig('router', 'class', COMPONENT_ROUTER); + } + + /** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * @param string $name + * @return array|string + */ + public function getModules($name = '') { + return $this->getConfig('modules', $name, array()); + } + + /** + * 添加module + * controller + * + * Controller + * + * WIND:core.web.WindErrorHandler + * + * + * + * template + * + * htm + * + * @param string $name + * @param array $config + * @return + */ + public function setModules($name, $config = array()) { + if (!$_default = @$this->_config['modules']['default']) { + $_default = $this->getDefaultConfigStruct('modules'); + $this->_config['modules']['default'] = $_default; + } + if (!$config) + $this->_config['modules'][$name] = $_default; + else + $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); + return $this->_config['modules'][$name]; + } + + /** + * 返回module模板定义 + * @param unknown_type $name + * @param unknown_type $default + */ + public function getModuleTemplateDir($name, $default = '') { + return $this->getConfig('template-dir', '', $default, $this->getModules($name)); + } + + /** + * 根据module名称返回错误的处理句柄 + * @param string $name + * @param string $default + * @return string + */ + public function getModuleErrorHandler($name, $default = '') { + return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); + } + + /** + * 返回指定moduleName的controller路径信息 + * @param string $name + * @return string + */ + public function getModuleControllerPath($name, $default = '') { + return $this->getConfig('controller-path', '', $default, $this->getModules($name)); + } + + /** + * 返回指定moduleName的controller后缀 + * @param string $name + * @return string + */ + public function getModuleControllerSuffix($name, $default = '') { + return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); + } + + /** + * 返回指定ComponentName的Component配置信息 + * @param string $name + * @return string + */ + public function getComponents($name = '', $default = array()) { + return $this->getConfig('components', $name, $default); + } + + /** + * 获得DB配置,根据DB名义的别名来获取DB链接配置信息. + * 当别名为空时,返回全部DB链接配置. + * + * @param string $dbName + */ + public function getDbConfig($dbName = '') { + $config = $this->getConfig('db'); + if (isset($config['resource']) && !empty($config['resource'])) { + $_resource = Wind::getRealPath($config['resource'], true); + $this->_config['db'] = $this->parseConfig($_resource, 'db'); + } + return $this->getConfig('db', $dbName); + } + + /** + * 配置解析方法 + * @param string $config + * @param string $key + * @param string|boolean $append + * @param factory + */ + private function parseConfig($config, $key = 'config', $append = true) { + if (!$config) + return array(); + $configParser = $this->getSystemConfig()->getInstance('configParser'); + return $configParser->parse($config); + } + + /** + * 返回对应的配置结构及默认值 + * @param string $configName + * @throws WindException + * @return string + */ + public function getDefaultConfigStruct($configName) { + $_tmp = array(); + $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); + $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', + 'Controller'); + $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', + 'WIND:core.web.WindErrorHandler'); + return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); + } +} \ No newline at end of file diff --git a/wind/web/WindUrlHelper.php b/wind/web/WindUrlHelper.php new file mode 100644 index 00000000..a9bfa467 --- /dev/null +++ b/wind/web/WindUrlHelper.php @@ -0,0 +1,25 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindUrlHelper extends WindModule { + + /** + * 构造返回Url地址 + * + * 将根据是否开启url重写来分别构造相对应的url + * + * @param string $action 执行的操作 + * @param string $controller 执行的controller + * @param array $params 附带的参数 + * @return string + */ + public function createUrl($action, $controller = '', $params = array()) { + $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); + return $router->buildUrl($action, $controller, $params); + } +} +?> \ No newline at end of file diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php new file mode 100644 index 00000000..1f43ce92 --- /dev/null +++ b/wind/web/WindWebApplication.php @@ -0,0 +1,247 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindWebApplication extends WindModule implements IWindApplication { + /** + * @var WindHttpRequest + */ + private $request; + /** + * @var WindHttpResponse + */ + private $response; + /** + * @var WindFactory + */ + protected $windFactory = null; + /** + * @var WindDispatcher + */ + protected $dispatcher = null; + /** + * @var WindRouter + */ + protected $handlerAdapter = null; + protected $defaultModule = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', + 'error-handler' => 'WIND:core.web.WindErrorHandler'); + + /** + * 应用初始化操作 + * + * @param array|string $config + * @param WindFactory $factory + * @param string $runCallBack + */ + public function __construct($config, $factory) { + $this->request = new WindHttpRequest(); + $this->response = $this->request->getResponse(@$config['charset']); + $this->windFactory = $factory; + $this->setConfig($config); + } + + /* (non-PHPdoc) + * @see IWindApplication::run() + */ + public function run() { + set_error_handler('WindHelper::errorHandle'); + set_exception_handler('WindHelper::exceptionHandle'); + $this->setModules('default', $this->defaultModule); + $this->windFactory->loadClassDefinitions($this->getConfig('components')); + $this->_getHandlerAdapter()->route(); + $this->processRequest(); + restore_error_handler(); + restore_exception_handler(); + $this->response->sendResponse(); + Wind::resetApp(); + } + + /* (non-PHPdoc) + * @see IWindApplication::doDispatch() + */ + public function doDispatch($forward, $display = false) { + if ($forward === null) + return; + $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); + } + + /** + * 请求处理 + * @return + */ + public function processRequest() { + try { + if (!$this->handlerAdapter->getModule()) + $this->handlerAdapter->setModule('default'); + if (!($module = $this->getModules())) + throw new WindActionException( + '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', + 404); + $module = WindUtility::mergeArray($this->defaultModule, $module); + $handlerPath = @$module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . @$module['controller-suffix']; + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); + + $this->getSystemFactory()->addClassDefinitions($handlerPath, + array('path' => $handlerPath, 'scope' => 'prototype', 'proxy' => true, + 'config' => $this->getConfig('actionmap'), + 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), + 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); + $handler = $this->windFactory->getInstance($handlerPath); + + if (!$handler) + throw new WindActionException( + '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', + 404); + $this->doDispatch($handler->doAction($this->handlerAdapter)); + } catch (WindActionException $e) { + $this->sendErrorMessage($e); + } catch (WindException $e) { + $this->sendErrorMessage($e); + } + } + + /** + * 异常处理请求 + * @param WindActionException actionException + * @return + */ + protected function sendErrorMessage($exception) { + $moduleName = $this->handlerAdapter->getModule(); + if ($moduleName === 'error') + throw new WindFinalException($exception->getMessage()); + + $errorMessage = null; + if ($exception instanceof WindActionException) + $errorMessage = $exception->getError(); + if (!$errorMessage) { + $errorMessage = $this->windFactory->getInstance('errorMessage'); + $errorMessage->addError($exception->getMessage()); + } + if (!$_errorAction = $errorMessage->getErrorAction()) { + $module = $this->getModules($moduleName); + if (empty($module)) + $module = $this->setModules('default'); + preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); + $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); + $_errorAction = 'error/' . @$matchs[0] . '/run/'; + $this->setModules('error', + array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); + } + $forward = $this->getSystemFactory()->getInstance('forward'); + $forward->forwardAction($_errorAction); + $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); + $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); + $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); + } + + /** + * 添加module + * controller + * + * Controller + * + * WIND:core.web.WindErrorHandler + * + * + * + * template + * + * htm + * + * @param string $name + * @param array $config + * @return array + */ + public function setModules($name, $config = array()) { + if (!isset($this->_config['modules'][$name])) { + $this->_config['modules'][$name] = (array) $config; + } + + /*if (isset($this->_config['modules']['default'])) + $_default = $this->_config['modules']['default']; + else { + $this->_config['modules']['default'] = $_default; + } + if (!$config) + $this->_config['modules'][$name] = $_default; + else + $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); + return $this->_config['modules'][$name];*/ + } + + /** + * @param string $name + * @throws WindActionException + * @throws WindException + * @return array + */ + public function getModules($name = '') { + if ($name === '') + return $this->getConfig('modules', $this->handlerAdapter->getModule()); + return $this->getConfig('modules', $name, array()); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + if (!$config) + return; + $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; + $this->_config = $config; + } + + /** + * @param object $componentInstance + * @param string $componentName + */ + public function registeComponent($componentName, $componentInstance, $scope) { + return $this->windFactory->registInstance($componentInstance, $componentName); + } + + /** + * @param string $componentName + * @return object + */ + public function getComponent($componentName) { + $component = null; + switch ($componentName) { + case 'windCache': + if ($this->getConfig('iscache', '', true)) + $component = $this->windFactory->getInstance($componentName); + break; + default: + $component = $this->windFactory->getInstance($componentName); + break; + } + return $component; + } + + /** + * @return WindHttpRequest $request + */ + public function getRequest() { + return $this->request; + } + + /** + * @return WindHttpResponse $response + */ + public function getResponse() { + return $this->response; + } + + /** + * @return WindFactory $windFactory + */ + public function getWindFactory() { + return $this->windFactory; + } +} \ No newline at end of file diff --git a/wind/web/filter/WindUrlFilter.php b/wind/web/filter/WindUrlFilter.php new file mode 100644 index 00000000..201a3dc8 --- /dev/null +++ b/wind/web/filter/WindUrlFilter.php @@ -0,0 +1,26 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindUrlFilter extends WindFilter { + + /* (non-PHPdoc) + * @see WindFilter::preHandle() + */ + public function preHandle($request = null, $response = null) { + + } + + /* (non-PHPdoc) + * @see WindFilter::postHandle() + */ + public function postHandle($request = null, $response = null) { + + } + +} + +?> \ No newline at end of file diff --git a/wind/web/listener/WindFormListener.php b/wind/web/listener/WindFormListener.php new file mode 100644 index 00000000..edc54f20 --- /dev/null +++ b/wind/web/listener/WindFormListener.php @@ -0,0 +1,73 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFormListener extends WindHandlerInterceptor { + + /** + * @var WindHttpRequest + */ + private $request = null; + + private $formPath = ''; + + private $errorMessage = null; + + /** + * @param WindHttpRequest $request + * @param string $formPath + */ + public function __construct($request, $formPath, $errorMessage) { + $this->request = $request; + $this->formPath = $formPath; + $this->errorMessage = $errorMessage; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + $className = Wind::import($this->formPath); + if (!class_exists($className)) + throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); + if ('WindEnableValidateModule' != get_parent_class($className)) + throw new WindException('the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); + $form = new $className(); + $methods = get_class_methods($form); + foreach ($methods as $method) { + if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) + continue; + $_tmp[0] = strtolower($_tmp[0]); + $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet($_tmp); + if (null === $value) + continue; + call_user_func_array(array($form, $method), array($value)); + } + call_user_func_array(array($form, 'validate'), array($form)); + if (($error = $form->getErrors())) { + list($errorController, $errorAction) = $form->getErrorControllerAndAction(); + $this->sendError($errorController, $errorAction, $error); + } + $this->request->setAttribute('formData', $form); + } + + private function sendError($errorController, $errorAction, $errors) { + $this->errorMessage->setErrorController($errorController); + $this->errorMessage->setErrorAction($errorAction); + $this->errorMessage->addError($errors); + $this->errorMessage->sendError(); + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + // TODO Auto-generated method stub + } +} + +?> \ No newline at end of file diff --git a/wind/web/listener/WindValidateListener.php b/wind/web/listener/WindValidateListener.php new file mode 100644 index 00000000..71be225a --- /dev/null +++ b/wind/web/listener/WindValidateListener.php @@ -0,0 +1,96 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindValidateListener extends WindHandlerInterceptor { + + /** + * @var WindHttpRequest + */ + private $request = null; + + private $validateRules = array(); + + private $validator = null; + + private $validatorClass = ''; + + private $defaultMessage = '验证失败'; + + /** + * @param WindHttpRequest $request + * @param array $validateRules + * @param string $validatorClass + */ + public function __construct($request, $validateRules, $validatorClass) { + $this->request = $request; + $this->validateRules = (array) $validateRules; + $this->validatorClass = $validatorClass; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + if (!isset($this->validateRules['errorMessage'])) + $errorMessage = new WindErrorMessage(); + else { + $errorMessage = $this->validateRules['errorMessage']; + unset($this->validateRules['errorMessage']); + } + $_input = new stdClass(); + foreach ((array) $this->validateRules as $rule) { + if (!is_array($rule)) + continue; + $key = $rule['field']; + $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( + $key); + $args = $rule['args']; + array_unshift($args, $value); + if (call_user_func_array(array($this->getValidator(), $rule['validator']), + (array) $args) === false) { + if (null === $rule['default']) + $errorMessage->addError( + ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); + else + $value = $rule['default']; + } + $this->request->setAttribute($key, $value); + $_input->$key = $value; + } + if ($errorMessage->getError()) + $errorMessage->sendError(); + else + $this->request->setAttribute('inputData', $_input); + } + + /** + * 返回validator对象 + * @throws WindException + * @return WindValidator + */ + private function getValidator() { + if ($this->validator === null) { + $_className = Wind::import($this->validatorClass); + $this->validator = WindFactory::createInstance($_className); + if ($this->validator === null) + throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); + } + return $this->validator; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + + } + +} + +?> \ No newline at end of file diff --git a/wind/web/view/404.htm b/wind/web/view/404.htm new file mode 100644 index 00000000..e5626d85 --- /dev/null +++ b/wind/web/view/404.htm @@ -0,0 +1,140 @@ + + + + +404 Not Found + + + +
+
+

404 Not Found

+
+
+
+
+ + \ No newline at end of file diff --git a/wind/web/view/error.htm b/wind/web/view/error.htm new file mode 100644 index 00000000..ffa40483 --- /dev/null +++ b/wind/web/view/error.htm @@ -0,0 +1,155 @@ + + + + +<?php echo $topic; ?> + + + +
+

+
+

+

+
    + $value): + if($key == $currentLine):?> +
  • + +
  • + +
+ +

__Stack:

+
    + +
  • + +
+
+
+
+ + \ No newline at end of file diff --git a/wind/web/view/erroraction.htm b/wind/web/view/erroraction.htm new file mode 100644 index 00000000..97e2593f --- /dev/null +++ b/wind/web/view/erroraction.htm @@ -0,0 +1,45 @@ + + + + +{@G:title} + + + +
+ + + + +
+

{$errorHeader}:

+

+ {$key}. {$error}
+

+

You Can Get Help In:

+

{@WindHelper::errorInfo()}

+
+
+ + \ No newline at end of file From 5c57bf0164cc1ac62a3405d61183ce457c6bdb50 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 06:02:00 +0000 Subject: [PATCH 0421/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2493 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/cache/AbstractWindCache.php | 258 ++++++++++++++ wind/cache/AbstractWindCacheDependency.php | 64 ++++ .../dependency/WindDbCacheDependency.php | 51 +++ .../dependency/WindFileCacheDependency.php | 27 ++ wind/cache/exception/WindCacheException.php | 13 + wind/cache/strategy/WindApcCache.php | 45 +++ wind/cache/strategy/WindDbCache.php | 171 +++++++++ wind/cache/strategy/WindEacceleratorCache.php | 52 +++ wind/cache/strategy/WindFileCache.php | 151 ++++++++ wind/cache/strategy/WindMemCache.php | 86 +++++ wind/cache/strategy/WindWinCache.php | 46 +++ wind/cache/strategy/WindXCache.php | 71 ++++ wind/cache/strategy/WindZendCache.php | 45 +++ wind/collections/WindList.php | 280 +++++++++++++++ wind/collections/WindQueue.php | 134 +++++++ wind/collections/WindSortedList.php | 333 ++++++++++++++++++ wind/collections/WindStack.php | 125 +++++++ 17 files changed, 1952 insertions(+) create mode 100644 wind/cache/AbstractWindCache.php create mode 100644 wind/cache/AbstractWindCacheDependency.php create mode 100644 wind/cache/dependency/WindDbCacheDependency.php create mode 100644 wind/cache/dependency/WindFileCacheDependency.php create mode 100644 wind/cache/exception/WindCacheException.php create mode 100644 wind/cache/strategy/WindApcCache.php create mode 100644 wind/cache/strategy/WindDbCache.php create mode 100644 wind/cache/strategy/WindEacceleratorCache.php create mode 100644 wind/cache/strategy/WindFileCache.php create mode 100644 wind/cache/strategy/WindMemCache.php create mode 100644 wind/cache/strategy/WindWinCache.php create mode 100644 wind/cache/strategy/WindXCache.php create mode 100644 wind/cache/strategy/WindZendCache.php create mode 100644 wind/collections/WindList.php create mode 100644 wind/collections/WindQueue.php create mode 100644 wind/collections/WindSortedList.php create mode 100644 wind/collections/WindStack.php diff --git a/wind/cache/AbstractWindCache.php b/wind/cache/AbstractWindCache.php new file mode 100644 index 00000000..4b07da99 --- /dev/null +++ b/wind/cache/AbstractWindCache.php @@ -0,0 +1,258 @@ + + * @author Su Qian + * @version $Id$ + * @package + */ +abstract class AbstractWindCache extends WindModule { + /** + * key的安全码 + * @var string + */ + private $securityCode = ''; + /** + * 缓存前缀 + * @var sting + */ + private $keyPrefix = ''; + /** + * 缓存过期时间 + * @var int + */ + private $expire = ''; + /** + * 缓存依赖的类名称 + * @var string + */ + const DEPENDENCYCLASS = 'dependencyclass'; + /** + * 标志存储时间 + * @var string + */ + const STORETIME = 'store'; + /** + * 标志存储数据 + * @var string + */ + const DATA = 'data'; + /** + * 配置文件中标志缓存依赖名称的定义 + * @var string + */ + const DEPENDENCY = 'dependency'; + /* + * 配置项 + */ + /** + * 配置文件中标志过期时间名称定义(也包含缓存元数据中过期时间 的定义) + * @var string + */ + const EXPIRE = 'expires'; + + /** + * 执行添加操作 + * + * @param string $key + * @param object $value + * @param int $expires + * @throws WindException + */ + protected abstract function setValue($key, $value, $expires = 0); + + /** + * 执行获取操作 + * + * @param string $key + * @throws WindException + */ + protected abstract function getValue($key); + + /** + * 需要实现的删除操作 + * @param string $key + * @return + */ + protected abstract function deleteValue($key); + + /** + * 清空所有缓存 + * @return + */ + public abstract function clear(); + + /** + * 设置缓存,如果key不存在,设置缓存,否则,替换已有key的缓存。 + * @param string $key 保存缓存数据的键。 + * @param string $value 保存缓存数据。 + * @param int $expires 缓存数据的过期时间,0表示永不过期 + * @param IWindCacheDependency $denpendency 缓存依赖 + * @return boolean + */ + public function set($key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { + try { + $data = array(self::DATA => $value, self::EXPIRE => $expires ? $expires : $this->getExpire(), self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); + if (null != $denpendency) { + $denpendency->injectDependent(); + $data[self::DEPENDENCY] = serialize($denpendency); + $data[self::DEPENDENCYCLASS] = get_class($denpendency); + } + return $this->setValue($this->buildSecurityKey($key), serialize($data), $data[self::EXPIRE]); + } catch (Exception $e) { + throw new WindCacheException('Setting cache failed.' . $e->getMessage()); + } + } + + /** + * 获取指定缓存 + * @param string $key 获取缓存数据的标识,即键 + * @return mixed + */ + public function get($key) { + try { + return $this->formatData($key, $this->getValue($this->buildSecurityKey($key))); + } catch (Exception $e) { + throw new WindCacheException('Getting cache data failed. (' . $e->getMessage() . ')'); + } + } + + /** + * 通过key批量获取缓存数据 + * @param array $keys + * @return array + */ + public function batchGet(array $keys) { + $data = array(); + foreach ($keys as $key) { + $data[$key] = $this->get($key); + } + return $data; + } + + /** + * 删除缓存数据 + * + * @param string $key 获取缓存数据的标识,即键 + * @return string + */ + public function delete($key) { + try { + return $this->deleteValue($this->buildSecurityKey($key)); + } catch (Exception $e) { + throw new WindException('Delete cache data failed. (' . $e->getMessage() . ')'); + } + } + + /** + * 通过key批量删除缓存数据 + * @param array $keys + * @return boolean + */ + public function batchDelete(array $keys) { + foreach ($keys as $key) + $this->delete($key); + return true; + } + + /** + * 格式化输出,如果没有数据~则返回false + * + * @param string $value + * @return string|boolean + */ + protected function formatData($key, $value) { + $data = unserialize($value); + if (!is_array($data)) return false; + if ($this->hasChanged($key, $data)) return false; + return isset($data[self::DATA]) ? $data[self::DATA] : false; + } + + /** + * 如果缓存中有数据,则检查缓存依赖是否已经变更,如果变更则删除缓存 + * + * @param string $key 键 + * @param array $data 缓存中的数据 + * @return boolean true表示缓存依赖已变更,false表示缓存依赖未变改 + */ + protected function hasChanged($key, array $data) { + if (isset($data[self::DEPENDENCY]) && $data[self::DEPENDENCY]) { + $dependency = unserialize($data[self::DEPENDENCY]); + if (!$dependency->hasChanged($this)) return false; + } elseif (isset($data[self::EXPIRE]) && $data[self::EXPIRE]) { + $_overTime = $data[self::EXPIRE] + $data[self::STORETIME]; + if ($_overTime >= time()) return false; + } else + return false; + $this->delete($key); + return true; + } + + /** + * 生成安全的key + * + * @param string $key + * @return string + */ + protected function buildSecurityKey($key) { + return md5($this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key . $this->getSecurityCode() : $key . $this->getSecurityCode()); + } + + /** + * 返回缓存Key值前缀,默认值为null无任何前缀添加 + * + * @return the $prefix + */ + protected function getKeyPrefix() { + return $this->keyPrefix; + } + + /** + * @param sting $keyPrefix + */ + public function setKeyPrefix($keyPrefix) { + $this->keyPrefix = $keyPrefix; + } + + /** + * @return the $securityCode + */ + protected function getSecurityCode() { + return $this->securityCode; + } + + /** + * @param string $securityCode + */ + public function setSecurityCode($securityCode) { + $this->securityCode = $securityCode; + } + + /** + * 返回过期时间设置,默认值为0永不过期 + * @return the $expire + */ + public function getExpire() { + return $this->expire; + } + + /** + * @param int $expire + */ + public function setExpire($expire) { + $this->expire = intval($expire); + } + + /** + * 设置配置信息 + * + * @param array $config + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setSecurityCode($this->getConfig('security-code', '', '')); + $this->setKeyPrefix($this->getConfig('key-prefix', '', '')); + $this->setExpire($this->getConfig('expires', '', 0)); + } +} \ No newline at end of file diff --git a/wind/cache/AbstractWindCacheDependency.php b/wind/cache/AbstractWindCacheDependency.php new file mode 100644 index 00000000..80f56701 --- /dev/null +++ b/wind/cache/AbstractWindCacheDependency.php @@ -0,0 +1,64 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +abstract class AbstractWindCacheDependency extends WindModule { + + /** + * 依赖的依据 + * + * @var mixed + */ + protected $data = ''; + + /** + * @var string 依赖项的上次更改时间 + */ + protected $lastModified; + + /** + * 初始化设置,设置依赖 + */ + public function injectDependent() { + $this->lastModified = time(); + $this->data = $this->notifyDependencyChanged(); + } + + /** + * 检查是否有变更 + * + * @return boolean + */ + public function hasChanged() { + return $this->data != $this->notifyDependencyChanged(); + } + + /** + * 获得依赖数据 + * + * @return mixed + */ + public function getDenpendencyData() { + return $this->data; + } + + /** + * 获得最后更新时间 + * @return int + */ + public function getLastModified() { + return $this->lastModified; + } + + /** + * 是否有变化 + * + * @return mixed 新的值 + */ + protected abstract function notifyDependencyChanged(); + +} \ No newline at end of file diff --git a/wind/cache/dependency/WindDbCacheDependency.php b/wind/cache/dependency/WindDbCacheDependency.php new file mode 100644 index 00000000..fd58c835 --- /dev/null +++ b/wind/cache/dependency/WindDbCacheDependency.php @@ -0,0 +1,51 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +Wind::import('WIND:component.cache.dependency.AbstractWindCacheDependency'); +class WindDbCacheDependency extends AbstractWindCacheDependency{ + private $sql = ''; + private $configName = ''; + private $connection = null; + + public function __construct($sql, $configName = '') { + $sql && $this->sql = $sql; + $configName && $this->configName = $configName; + } + + /* + * (non-PHPdoc) + * @see WindCacheDependency::notifyDependencyChanged() + */ + protected function notifyDependencyChanged() { + if (!$this->sql) return null; + return $this->getConnection()->query($this->sql)->fetchAll(); + } + + /** + * 获得链接对象 + */ + private function getConnection() { + if ( null != $this->connection) return $this->connection; + $alias = 'db_' . $this->configName; + if (!$this->getSystemFactory()->checkAlias($alias)) { + $config = $this->getSystemConfig()->getDbConfig($this->configName); + $definition = array( + 'path' => $this->getConfig('class', '', 'COM:db.WindConnection', $config), + 'alias' => $alias, + 'config' => $config, + 'initMethod' => 'init', + 'scope' => 'application', + ); + $this->getSystemFactory()->addClassDefinitions($alias, $definition); + } + $this->connection = $this->getSystemFactory()->getInstance($alias); + return $this->connection; + } + + +} \ No newline at end of file diff --git a/wind/cache/dependency/WindFileCacheDependency.php b/wind/cache/dependency/WindFileCacheDependency.php new file mode 100644 index 00000000..c72a3719 --- /dev/null +++ b/wind/cache/dependency/WindFileCacheDependency.php @@ -0,0 +1,27 @@ + 2011-7-25 + * @link http://www.cnblogs.com/xiaoyaoxia/ + * @copyright Copyright © 2011-2012 xiaoxiao + * @license + * @package + */ +Wind::import('WIND:component.cache.AbstractWindCacheDependency'); +class WindFileCacheDependency extends AbstractWindCacheDependency { + private $fileName = ''; + + public function __construct($fileName = null) { + $this->fileName = $fileName; + } + + /* + * (non-PHPdoc) + * @see AbstractWindCacheDependency::notifyDependencyChanged() + */ + protected function notifyDependencyChanged() { + clearstatcache();//删除文件信息的缓存 + if ($this->fileName) { + return @filemtime($this->fileName); + } + } +} \ No newline at end of file diff --git a/wind/cache/exception/WindCacheException.php b/wind/cache/exception/WindCacheException.php new file mode 100644 index 00000000..17a4c37e --- /dev/null +++ b/wind/cache/exception/WindCacheException.php @@ -0,0 +1,13 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindCacheException extends WindException { + + +} + +?> \ No newline at end of file diff --git a/wind/cache/strategy/WindApcCache.php b/wind/cache/strategy/WindApcCache.php new file mode 100644 index 00000000..cbcc786e --- /dev/null +++ b/wind/cache/strategy/WindApcCache.php @@ -0,0 +1,45 @@ + + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ +class WindApcCache extends AbstractWindCache { + + public function __construct(){ + if (!extension_loaded('apc')) { + throw new WindCacheException('The apc extension must be loaded !'); + } + } + + /* + * @see AbstractWindCache#setValue() + */ + protected function setValue($key, $value, $expires = 0) { + return apc_store($key, $value, $expires); + } + + /* + * @see AbstractWindCache#getValue() + */ + protected function getValue($key) { + return apc_fetch($key); + } + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + return apc_delete($key); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + apc_clear_cache(); + return apc_clear_cache('user'); + } +} \ No newline at end of file diff --git a/wind/cache/strategy/WindDbCache.php b/wind/cache/strategy/WindDbCache.php new file mode 100644 index 00000000..56d8f5d4 --- /dev/null +++ b/wind/cache/strategy/WindDbCache.php @@ -0,0 +1,171 @@ + + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ +class WindDbCache extends AbstractWindCache { + + /** + * 链接句柄 + * @var AbstractWindDbAdapter + */ + private $connection; + + /** + * 缓存表 + * @var string + */ + private $table = 'pw_cache'; + + /** + * 缓存表的键字段 + * @var string + */ + private $keyField = 'key'; + + /** + * 缓存表的值字段 + * @var string + */ + private $valueField = 'value'; + + /** + * 缓存表过期时间字段 + * @var string + */ + private $expireField = 'expire'; + + /** + * 配置文件 + * @var string + */ + private $dbConfigName = ''; + + public function __construct(WindConnection $connection = null, $config = array()) { + $connection && $this->setConnection($connection); + $config && $this->setConfig($config); + } + + /* + * @see AbstractWindCache#setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return $this->store($key, $value, $expire); + } + + /* + * @see AbstractWindCache#getValue() + */ + protected function getValue($key) { + $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; + $data = $this->getConnection()->createStatement($sql)->getOne(array($key, time())); + return $data[$this->valueField]; + } + + /* + * @see AbstractWindCache#batchFetch() + */ + public function batchGet(array $keys) { + foreach ($keys as $key => $value) { + $keys[$key] = $this->buildSecurityKey($value); + } + list($sql, $result) = array('', array()); + $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys) . ' AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; + $data = $this->getConnection()->createStatement($sql)->queryAll(array(time())); + foreach ($data as $tmp) { + $result[] = $this->formatData(array_search($tmp[$this->keyField], $keys), $tmp[$this->valueField]); + } + return $result; + } + + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` = ? '; + return $this->getConnection()->createStatement($sql)->update(array($key)); + } + + /* + * @see AbstractWindCache#batchDelete() + */ + public function batchDelete(array $keys) { + foreach ($keys as $key => $value) { + $keys[$key] = $this->buildSecurityKey($value); + } + $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys); + return $this->getConnection()->execute($sql); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + return $this->getConnection()->execute('DELETE FROM ' . $this->getTableName()); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->table = $this->getConfig('table-name', '', 'pw_cache', $config); + $this->keyField = $this->getConfig('field-key', '', 'key', $config); + $this->valueField = $this->getConfig('field-value', '', 'value', $config); + $this->expireField = $this->getConfig('field-expire', '', 'expire', $config); + $this->dbConfigName = $this->getConfig('dbconfig-name', '', '', $config); + } + + /** + * 设置链接对象 + * @param WindConnection $connection + */ + public function setConnection($connection) { + if ($connection instanceof WindConnection) $this->connection = $connection; + } + + /** + * 返回表名 + * @return string + */ + private function getTableName() { + return $this->table; + } + + /** + * 存储数据 + * @param string $key + * @param string $value + * @param int $expires + * @param IWindCacheDependency $denpendency + * @return boolean + */ + private function store($key, $value, $expires = 0) { + ($expires > 0) ? $expires += time() : $expire=0; + $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires); + $sql = 'REPLACE INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db); + return $this->getConnection()->createStatement($sql)->update(); + } + + /** + * 获得链接对象 + * @return WindConnection + */ + private function getConnection() { + if (null == $this->connection) { + $config = $this->getSystemConfig()->getDbConfig($this->dbConfigName); + $path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); + $alias = $this->dbConfigName ? $path . $this->dbConfigName : $path . get_class($this); + if (!$this->getSystemFactory()->checkAlias($alias)) { + $definition = array('path' => $path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', 'scope' => 'application'); + $this->getSystemFactory()->addClassDefinitions($alias, $definition); + } + $this->connection = $this->getSystemFactory()->getInstance($alias); + } + return $this->connection; + } +} \ No newline at end of file diff --git a/wind/cache/strategy/WindEacceleratorCache.php b/wind/cache/strategy/WindEacceleratorCache.php new file mode 100644 index 00000000..35a466a2 --- /dev/null +++ b/wind/cache/strategy/WindEacceleratorCache.php @@ -0,0 +1,52 @@ + + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ +class WindEacceleratorCache extends AbstractWindCache { + + public function __construct() { + if (!function_exists('eaccelerator_get')) { + throw new WindCacheException('The eaccelerator extension must be loaded !'); + } + } + + /* + * @see AbstractWindCache#setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return eaccelerator_put($key, $value, $expire); + } + + /* + * @see AbstractWindCache#get() + */ + protected function getValue($key) { + return eaccelerator_get($key); + } + + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + return eaccelerator_rm($key); + } + + /* + * @see AbstractWindCache#clear() + * @return boolean + */ + public function clear() { + eaccelerator_gc(); + $cacheKeys = eaccelerator_list_keys(); + foreach ($cacheKeys as $key) { + $this->delete(substr($key['name'], 1)); + } + } +} \ No newline at end of file diff --git a/wind/cache/strategy/WindFileCache.php b/wind/cache/strategy/WindFileCache.php new file mode 100644 index 00000000..47a2c76a --- /dev/null +++ b/wind/cache/strategy/WindFileCache.php @@ -0,0 +1,151 @@ + + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ +class WindFileCache extends AbstractWindCache { + + /** + * 缓存目录 + * @var string + */ + private $cacheDir; + + /** + * 缓存后缀 + * @var string + */ + private $cacheFileSuffix = 'txt'; + + /** + * 缓存多级目录。最好不要超3层目录 + * @var int + */ + private $cacheDirectoryLevel = 0; + + /** + * 保存操作的路径信息, 存储使用过的key路径 + * @var array + */ + private $cacheFileList = array(); + + /* (non-PHPdoc) + * @see AbstractWindCache::setValue($key, $value, $expires) + */ + protected function setValue($key, $value, $expire = 0) { + return WindFile::write($key, $value) == strlen($value); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::get() + */ + protected function getValue($key) { + if (!is_file($key)) return null; + return WindFile::read($key); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::deleteValue() + */ + protected function deleteValue($key) { + return WindFile::write($key, ''); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::clear() + */ + public function clear() { + return WindFile::clearDir($this->getCacheDir()); + } + + /** + * 获取缓存文件名。 + * + * @param string $key + * @return string + */ + protected function buildSecurityKey($key) { + $key = parent::buildSecurityKey($key); + if (false !== ($dir = $this->checkCacheDir($key))) return $dir; + $_dir = $this->getCacheDir(); + if (0 < ($level = $this->getCacheDirectoryLevel())) { + $_subdir = substr(md5($key), 0, $level); + $_dir .= DIRECTORY_SEPARATOR . $_subdir; + if (!is_dir($_dir)) mkdir($_dir, 0777, true); + } + $filename = $key . '.' . $this->getCacheFileSuffix(); + $this->cacheFileList[$key] = ($_dir ? $_dir . DIRECTORY_SEPARATOR . $filename : $filename); + return $this->cacheFileList[$key]; + } + + /** + * 采用最近最少使用原则算法 + * + * @param string $key + * @return string + */ + private function checkCacheDir($key) { + return isset($this->cacheFileList[$key]) ? $this->cacheFileList[$key] : false; + } + + /** + * 设置缓存目录 + * @param string $dir + */ + public function setCacheDir($dir) { + $_dir = Wind::getRealDir($dir); + if (!is_dir($_dir)) mkdir($_dir, 0777, true); + $this->cacheDir = $_dir; + } + + /** + * @return the $cacheDir + */ + private function getCacheDir() { + return $this->cacheDir; + } + + /** + * @param string $cacheFileSuffix + */ + public function setCacheFileSuffix($cacheFileSuffix) { + $this->cacheFileSuffix = $cacheFileSuffix; + } + + /** + * @return the $cacheFileSuffix + */ + private function getCacheFileSuffix() { + return $this->cacheFileSuffix; + } + + /** + * @param int $cacheDirectoryLevel + */ + public function setCacheDirectoryLevel($cacheDirectoryLevel) { + $this->cacheDirectoryLevel = $cacheDirectoryLevel; + } + + /** + * 返回cache目录级别,默认为0,不分级,最大分级为5 + * @return the $cacheDirectoryLevel + */ + public function getCacheDirectoryLevel() { + return $this->cacheDirectoryLevel; + } + + /* (non-PHPdoc) + * @see AbstractWindCache::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setCacheDir($this->getConfig('dir')); + $this->setCacheFileSuffix($this->getConfig('suffix', '', 'txt')); + $this->setCacheDirectoryLevel($this->getConfig('dir-level', '', 0)); + } + +} \ No newline at end of file diff --git a/wind/cache/strategy/WindMemCache.php b/wind/cache/strategy/WindMemCache.php new file mode 100644 index 00000000..5b672af2 --- /dev/null +++ b/wind/cache/strategy/WindMemCache.php @@ -0,0 +1,86 @@ +'localhost', + * 'port'=>11211 + * 'pconn'=>true + * ), + * array( + * 'host'=>'localhost', + * 'port'=>11212 + * 'pconn'=>false + * ) + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ +class WindMemCache extends AbstractWindCache { + + /** + * memcache缓存操作句柄 + * @var WindMemcache + */ + protected $memcache = null; + + /** + * 是否对缓存采取压缩存储 + * @var int + */ + protected $compress = 0; + + public function __construct() { + if (!extension_loaded('Memcache')) { + throw new WindCacheException('WindMemCache requires PHP `Memcache` extension to be loaded !'); + } + $this->memcache = new Memcache(); + } + + /* + * @see AbstractWindCache::setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return $this->memcache->set($key, $value, $this->compress, (int) $expire); + } + + /* + * @see AbstractWindCache::getValue() + */ + protected function getValue($key) { + return $this->memcache->get($key); + } + + /* + * @see AbstractWindCache::deleteValue() + */ + protected function deleteValue($key) { + return $this->memcache->delete($key); + } + + /* + * @see AbstractWindCache::clear() + */ + public function clear() { + return $this->memcache->flush(); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->compress = $this->getConfig('compress', '', '0'); + $servers = $this->getConfig('servers', '', array()); + $defaultServer = array('host' => '', 'port' => '', 'pconn' => true, 'weight' => 1, 'timeout' => 15, + 'retry' => 15, 'status' => true, 'fcallback' => null); + foreach ((array) $servers as $server) { + if (!is_array($server)) throw new WindException('The memcache config is incorrect'); + if (!isset($server['host'])) throw new WindException('The memcache server ip address is not exist'); + if (!isset($server['port'])) throw new WindException('The memcache server port is not exist'); + call_user_func_array(array($this->memcache, 'addServer'), array_merge($defaultServer, $server)); + } + } + +} \ No newline at end of file diff --git a/wind/cache/strategy/WindWinCache.php b/wind/cache/strategy/WindWinCache.php new file mode 100644 index 00000000..a249b54c --- /dev/null +++ b/wind/cache/strategy/WindWinCache.php @@ -0,0 +1,46 @@ + + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ +class WindWinCache extends AbstractWindCache { + + public function __construct() { + if (!function_exists('wincache_ucache_get')) { + throw new WindCacheException('The wincache extension must be loaded !'); + } + } + + /* + * @see AbstractWindCache#setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return wincache_ucache_set($key, $value, $expire); + } + + /* + * @see AbstractWindCache#getValue() + */ + protected function getValue($key) { + return wincache_ucache_get($key); + } + + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + return wincache_ucache_delete($key); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + return wincache_ucache_clear(); + } + +} \ No newline at end of file diff --git a/wind/cache/strategy/WindXCache.php b/wind/cache/strategy/WindXCache.php new file mode 100644 index 00000000..d07fa7ba --- /dev/null +++ b/wind/cache/strategy/WindXCache.php @@ -0,0 +1,71 @@ + + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ +class WindXCache extends AbstractWindCache { + private $authUser = ''; + private $authPwd = ''; + + public function __construct() { + if (!extension_loaded('xcache')) { + throw new WindCacheException('The xcache extension must be loaded !'); + } + } + + /* + * @see AbstractWindCache#setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return xcache_set($key, $value, $expire); + } + + /* + * @see AbstractWindCache#getValue() + */ + protected function getValue($key) { + return xcache_get($key); + } + + /* + * @see AbstractWindCache#deleteValue() + */ + protected function deleteValue($key) { + return xcache_unset($key); + } + + /* + * @see AbstractWindCache#clear() + */ + public function clear() { + //xcache_clear_cache需要验证权限 + $tmp['user'] = isset($_SERVER['PHP_AUTH_USER']) ? null : $_SERVER['PHP_AUTH_USER']; + $tmp['pwd'] = isset($_SERVER['PHP_AUTH_PW']) ? null : $_SERVER['PHP_AUTH_PW']; + $_SERVER['PHP_AUTH_USER'] = $this->authUser; + $_SERVER['PHP_AUTH_PW'] = $this->authPwd; + //如果配置中xcache.var_count > 0 则不能用xcache_clear_cache(XC_TYPE_VAR, 0)的方式删除 + $max = xcache_count(XC_TYPE_VAR); + for ($i = 0; $i < $max; $i++) { + xcache_clear_cache(XC_TYPE_VAR, $i); + } + //恢复之前的权限 + $_SERVER['PHP_AUTH_USER'] = $tmp['user']; + $_SERVER['PHP_AUTH_PW'] = $tmp['pwd']; + return true; + } + + /* + * (non-PHPdoc) + * @see AbstractWindCache::setConfig() + */ + public function setConfig($config = array()) { + if (!$config) return false; + parent::setConfig($config); + $this->authUser = $this->getConfig('user'); + $this->authPwd = $this->getConfig('pwd'); + } + +} \ No newline at end of file diff --git a/wind/cache/strategy/WindZendCache.php b/wind/cache/strategy/WindZendCache.php new file mode 100644 index 00000000..dd36c252 --- /dev/null +++ b/wind/cache/strategy/WindZendCache.php @@ -0,0 +1,45 @@ + + * @author xiaoxiao + * @version 2011-7-26 xiaoxiao + */ +class WindZendCache extends AbstractWindCache { + + public function __construct() { + if (!function_exists('zend_shm_cache_fetch')) { + throw new WindCacheException('The zend cache extension must be loaded !'); + } + } + + /* (non-PHPdoc) + * @see AbstractWindCache::setValue() + */ + protected function setValue($key, $value, $expire = 0) { + return zend_shm_cache_store($key, $value, $expire); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::getValue() + */ + protected function getValue($key) { + return zend_shm_cache_fetch($key); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::deleteValue() + */ + protected function deleteValue($key) { + return zend_shm_cache_delete($key); + } + + /* (non-PHPdoc) + * @see AbstractWindCache::clear() + */ + public function clear() { + return zend_shm_cache_clear(); + } + +} \ No newline at end of file diff --git a/wind/collections/WindList.php b/wind/collections/WindList.php new file mode 100644 index 00000000..f8783ca8 --- /dev/null +++ b/wind/collections/WindList.php @@ -0,0 +1,280 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * WindList集合. + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindList implements IteratorAggregate, ArrayAccess, Countable { + + /** + * @var array 集合列表 + */ + private $list = array(); + /** + * @var string 列表总数指示器 + */ + private $count = 0; + /** + * @var boolean 列表是否只读 + */ + private $isReadOnly = false; + + /** + * @var boolean 是否固定大小 + */ + private $isFixedSize = false; + + /** + * WindList 实现有三种类别:只读、固定大小、可变大小。 + * 无法修改只读 WindList。 + * 固定大小的 WindList 不允许添加或移除元素,但允许修改现有元素。 + * 可变大小的 WindList 允许添加、移除和修改元素。 + * @param boolean $readOnly 是否只读 + * @param array|WindList $data 固定长度,如果指定了$data,那么这个WindList集合的长度是固定的,只许修改 + */ + public function __construct($data = array(),$readOnly = false) { + $this->isReadOnly = $readOnly; + if(false === empty($data)){ + if(is_array($data)){ + $this->list = $data; + }elseif($data instanceof WindList){ + $this->list = $data->getList(); + }else{ + throw new WindException("Parameter type is incorrect"); + } + $this->isFixedSize = true; + $this->count = count($this->list); + } + + } + /** + * 向 WindList 中添加项。 + * @param mixed $value + * @return boolean + */ + public function add($value) { + return $this->insertAt($this->count, $value); + } + /** + * 在 WindList 中的指定索引处插入项。 + * @param int $index + * @param mixed $value + * @return boolean + */ + public function insertAt($index, $value) { + if($this->isFixedSize && $this->count === $index){ + throw new WindException("The list size is fixed"); + } + if (false === $this->isReadOnly) { + if ($this->count === $index) { + $this->list[$this->count++] = $value; + } elseif (0 <= $index && $this->count > $index) { + array_splice($this->list, $index, 0, array($value)); + $this->count++; + } elseif ($this->count < $index || 0 > $index) { + throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); + } + } else { + throw new WindException('The list of read-only'); + } + return true; + } + /** + * 取得指定索引的项 + * @param int $index 指定索引 + * @return mixed + */ + public function itemAt($index) { + if (false === isset($this->list[$index])) { + throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); + } + return $this->list[$index]; + } + /** + * 返回指定项的索引,返回-1表向没有指定项 + * @param mixed $value 指定项 + * @return int + */ + public function indexOf($value) { + return false !== ($index = array_search($value, $this->list, true)) ? $index : -1; + } + /** + * 判断WindList中是否包含指定项 + * @param mixed $value 指定项 + * @return boolean + */ + public function contain($value) { + return 0 <= $this->indexOf($value); + } + /** + * 判断WindList中是否包含指定的索引 + * @param int $index 指定索引 + * @return boolean + */ + public function containAt($index) { + return 0 <= $index && $this->count > $index; + } + /** + * 修改WindList中指定索引的项 + * @param int $index 指定索引 + * @param mixed $value 要修改的项 + * @return boolean + */ + public function modify($index,$value){ + $this->removeAt($index,true); + $this->count++; + $this->insertAt($index, $value); + $this->count--; + return true; + } + /** + * 从WindList中移除指定索引的项 + * @param int $index 指定索引 + * @return mixed + */ + public function removeAt($index,$force = false) { + if ($this->isReadOnly) { + throw new WindException('The list of read-only'); + } + if($this->isFixedSize && false === $force){ + throw new WindException("The list size is fixed"); + } + if ($index > $this->count || $index < 0) { + throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); + } + $this->count--; + if (0 === $index) { + return array_shift($this->list); + } + if ($this->count === $index) { + return array_pop($this->list); + } + $item = $this->list[$index]; + array_splice($this->list, $index, 1); + return $item; + } + /** + * 从WindList中移除指定的项 + * @param mixed $value 指定的项 + * @return boolean + */ + public function remove($value) { + return $this->removeAt($this->indexOf($value)); + } + /** + * 清空WindList + * @return boolean + */ + public function clear() { + if ($this->isReadOnly) { + throw new WindException('The list of read-only'); + } + if($this->isFixedSize){ + throw new WindException("The list size is fixed"); + } + $this->count = 0; + $this->list = array(); + return true; + } + /** + * 将数组中的值合并到WindList + * @param array $array 要合并的数组 + * @return boolean + */ + public function mergeFromArray(array $array) { + foreach ($array as $value) { + $this->add($value); + } + return true; + } + /** + * 将WindList集合合并到WindList + * @param WindList $list 要合并的WindList集合 + * @return boolean + */ + public function mergeFromList(WindList $list) { + foreach ($list as $value) { + $this->add($value); + } + return true; + } + /** + * @return array + */ + public function getList() { + return $this->list; + } + /** + * 取得集合的总数 + * @return string + */ + public function getCount() { + return $this->count; + } + /** + * 取得集合是否只读 + * @return boolean + */ + public function getIsReadOnly() { + return $this->isReadOnly; + } + /** + * 取得集合是否是固定大小 + * @return boolean + */ + public function getIsFixedSize(){ + return $this->isFixedSize; + } + /* + * 计算集合的总个数 + * @see Countable#count() + */ + public function count() { + return $this->getCount(); + } + /** + * @param int $offset + */ + public function offsetExists($offset) { + return $this->containAt($offset); + } + /** + * @param int $offset + */ + public function offsetGet($offset) { + return $this->itemAt($offset); + } + /** + * @param int $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) { + if (null === $offset || $this->count === $offset) { + return $this->add($value); + } + return $this->modify($offset, $value); + } + /** + * @param int $offset + */ + public function offsetUnset($offset) { + return $this->removeAt($offset); + } + /** + * 取得集合的迭代器 + */ + public function getIterator() { + return new ArrayIterator($this->list); + } + +} \ No newline at end of file diff --git a/wind/collections/WindQueue.php b/wind/collections/WindQueue.php new file mode 100644 index 00000000..0400068c --- /dev/null +++ b/wind/collections/WindQueue.php @@ -0,0 +1,134 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 队列操作,先进先出 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindQueue implements IteratorAggregate,Countable{ + /** + * @var array 队列列表 + */ + private $list = array(); + /** + * @var string 列表总数指示器 + */ + private $count = 0; + + /** + * 移除并返回位于 Queue顶部的元素。 + * @return mixed + */ + public function dequeue(){ + if(!$this->count){ + throw new WindException("The queue is empty"); + } + --$this->count; + return array_shift($this->list); + } + + /** + * 返回位于 Queue顶部的对象但不将其移除。 + * @return mixed + */ + public function peek(){ + if(!$this->count){ + throw new WindException("The queue is empty"); + } + return $this->list[0]; + } + + /** + * 将元素添加到 Queue的底部。 + * @param mixed $value + * @return number + */ + public function enqueue($value){ + ++$this->count; + return array_push($this->list,$value); + } + + /** + * 确定某元素是否在 Queue中。 + * @param mixed $value + * @return boolean + */ + public function contain($value){ + return false !==array_search($value, $this->list, true); + } + + /** + * 将数组中的值合并到当前WindQueue队列 + * @param array $array 要合并的数组 + * @return boolean + */ + public function mergeFromArray(array $array) { + foreach ($array as $value) { + $this->enqueue($value); + } + return true; + } + /** + * 将WindQueue队列集合合并到当前WindQueue队列 + * @param WindQueue $list 要合并的WindQueue集合 + * @return boolean + */ + public function mergeFromQueue(WindQueue $queue) { + foreach ($queue as $value) { + $this->enqueue($value); + } + return true; + } + + /** + *清空队列 + */ + public function clear(){ + $this->list = array(); + $this->count = 0; + return true; + } + + /** + * 创建 Queue的浅表副本。 + * @return WindQueue + */ + public function __clone(){ + return new self(); + } + + /** + * 取得队列个数 + * @return int + */ + public function getCount(){ + return $this->count; + } + + + /* + * 计算队列个数 + * @see Countable#count() + */ + public function count() { + return $this->getCount(); + } + + /** + * 取得队列的迭代器 + */ + public function getIterator() { + return new ArrayIterator($this->list); + } + + +} \ No newline at end of file diff --git a/wind/collections/WindSortedList.php b/wind/collections/WindSortedList.php new file mode 100644 index 00000000..6408320a --- /dev/null +++ b/wind/collections/WindSortedList.php @@ -0,0 +1,333 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 表示键/值对的集合,这些键值对按键排序并可按照键和索引访问。 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSortedList implements IteratorAggregate, ArrayAccess, Countable { + /** + * @var array 集合列表 + */ + private $list = array(); + /** + * @var int 列表总数指示器 + */ + private $count = 0; + /** + * @var boolean 列表是否只读 + */ + private $isReadOnly = false; + + /** + * @var boolean 是否固定大小 + */ + private $isFixedSize = false; + + /** + * WindList 实现有三种类别:只读、固定大小、可变大小。 + * 无法修改只读 WindList。 + * 固定大小的 WindList 不允许添加或移除元素,但允许修改现有元素。 + * 可变大小的 WindList 允许添加、移除和修改元素。 + * @param boolean $readOnly 是否只读 + * @param array|WindList $data 固定长度,如果指定了$data,那么这个WindList集合的长度是固定的,只许修改 + */ + public function __construct($data = array(), $readOnly = false) { + $this->isReadOnly = $readOnly; + if (false === empty($data)) { + if (is_array($data)) { + $this->list = $data; + } elseif ($data instanceof WindList) { + $this->list = $data->getList(); + } else { + throw new WindException("Parameter type is incorrect"); + } + $this->isFixedSize = true; + $this->count = count($this->list); + } + + } + + /** + * 将带有指定键和值的元素添加到 WindSortedList 对象。 + * @param mixed $key + * @param mixed $value + */ + public function add($key, $value) { + $this->checkPermissions(); + if (isset($this->list[$key])) { + throw new WindException($key . ' key already exists in the collection'); + } + $this->list[$key] = $value; + ++$this->count; + return true; + } + /** + * 确定 WindSortedList对象是否包含特定的键。 + * @param mixed $key + * @return boolean + */ + public function contains($key) { + return $this->containsKey($key); + } + + /** + * 根据指定的索引确定 WindSortedList对象是否包含特定的键。 + * @param mixed $key + * @return boolean + */ + public function containsIndex($index) { + return $this->containsKey($this->getKey($index)); + } + + /** + * 确定 WindSortedList对象是否包含特定的键。 + * @param mixed $key + * @return boolean + */ + public function containsKey($key) { + return 0 <= $this->indexOfKey($key); + } + + /** + * 确定 WindSortedList对象是否包含特定值。 + * @param mixed $value + * @return boolean + */ + public function containsValue($value) { + return 0 <= $this->indexOfValue($value); + } + + /** + * 获取 WindSortedList 对象的指定索引处的键。 + * @param int $index 指定的索引 + * @return mixed + */ + public function getKey($index) { + $keys = $this->getKeyList(); + if (false === isset($keys[$index])) { + throw new WindException('Index out of range, is indeed the range should be between 0 to ' . $this->count); + } + return $keys[$index]; + } + + /** + * 获取WindSortedList 对象中的键。 + * @return mixed + */ + public function getKeyList() { + return array_keys($this->list); + } + + /** + * 获取WindSortedList 对象中的值。 + * @return mixed + */ + public function getValueList() { + return array_values($this->list); + } + + /** + * 返回WindSortedList 对象中指定键的从零开始的索引。 + * @param mixed $key + * @return mixed + */ + public function indexOfKey($key) { + return false !== ($index = array_search($key, $this->getKeyList(), true)) ? $index : -1; + } + + /** + * 返回指定的值在 SortedList 对象中第一个匹配项的从零开始的索引。 + * @param mixed $value + * @return mixed + */ + public function indexOfValue($value) { + return false !== ($index = array_search($value, $this->getValueList(), true)) ? $index : -1; + } + + /** + * 从WindSortedList中返回指定键的的值 + * @param int $key + * @return mixed + */ + public function item($key) { + if (false === isset($this->list[$key])) { + throw new WindException($key . ' is not exists in the collection'); + } + return $this->list[$key]; + } + /** + * 从WindSortedList中返回指定索引的的值 + * @param int $index + * @return mixed + */ + public function itemAt($index) { + $key = $this->getKey($index); + return $this->list[$key]; + } + /** + * 从 SortedList 对象中移除带有指定键的元素。 + * @param mixed $key + * @return mixed + */ + public function remove($key) { + $this->checkPermissions(); + if (false === isset($this->list[$key])) { + throw new WindException($key . ' is not exists in the collection'); + } + $item = $this->list[$key]; + unset($this->list[$key]); + --$this->count; + return $item; + } + /** + * 移除 WindSortedList对象的指定索引处的元素。 + * @param int $index + * @return mixed + */ + public function removeAt($index) { + $this->checkPermissions(); + $key = $this->getKey($index); + $item = $this->list[$key]; + unset($this->list[$key]); + --$this->count; + return $item; + } + /** + * 替换WindSortedList对象中指定索引处的值。 + * @param int $index + * @param mixed $value + * @return boolean + */ + public function setByIndex($index, $value) { + $this->checkPermissions(false); + $key = $this->getKey($index); + $this->list[$key] = $value; + return true; + } + /** + * 替换WindSortedList对象中指定键处的值。 + * 如果指定的键存在,那么替换,否则新增 + * @param mixed $key + * @param mixed $value + * @return mixed + */ + public function setByKey($key, $value) { + $this->checkPermissions(false); + if (isset($this->list[$key])) { + $item = $this->list[$key]; + $this->list[$key] = $value; + return $item; + } + $this->list[$key] = $value; + ++$this->count; + return $value; + } + + /** + * 从 SortedList 对象中移除所有元素。 + * @return boolean + */ + public function clear() { + $this->checkPermissions(); + $this->count = 0; + $this->list = array(); + return true; + } + /** + * 取得集合是否只读 + * @return boolean + */ + public function getIsReadOnly() { + return $this->isReadOnly; + } + /** + * 取得集合是否是固定大小 + * @return boolean + */ + public function getIsFixedSize(){ + return $this->isFixedSize; + } + /** + * 返回集合的总数 + * @return number + */ + public function getCount() { + return $this->count; + } + /* 计算集合总数 + * @see Countable#count() + */ + public function count() { + return $this->getCount(); + } + /** + * 取得WindSortedList集合迭代器 + * @return ArrayIterator + */ + public function getIterator() { + return new ArrayIterator($this->list); + } + /* + * @see ArrayAccess#offsetExists() + */ + public function offsetExists($offset) { + if (is_int($offset)) { + return $this->containsIndex($offset); + } + return $this->containsKey($offset); + } + /* + * @see ArrayAccess#offsetGet() + */ + public function offsetGet($offset) { + if (is_int($offset)) { + return $this->itemAt($offset); + } + return $this->item($offset); + } + /* + * @see ArrayAccess#offsetSet() + */ + public function offsetSet($offset, $value) { + if (is_int($offset)) { + return $this->setByIndex($offset, $value); + } + return $this->setByKey($offset, $value); + } + /* + * @see ArrayAccess#offsetUnset() + */ + public function offsetUnset($offset) { + if (is_int($offset)) { + return $this->removeAt($offset); + } + return $this->remove($offset); + } + /** + * 创建 WindSortedList对象的浅表副本。 + * @return WindSortedList + */ + public function __clone() { + return new self($this->list, $this->isReadOnly); + } + + private function checkPermissions($ifcheckFixedSize = true) { + if ($this->isReadOnly) { + throw new WindException('The list of read-only'); + } + if ($this->isFixedSize && $ifcheckFixedSize) { + throw new WindException("The list size is fixed"); + } + } + +} \ No newline at end of file diff --git a/wind/collections/WindStack.php b/wind/collections/WindStack.php new file mode 100644 index 00000000..0a935496 --- /dev/null +++ b/wind/collections/WindStack.php @@ -0,0 +1,125 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 堆栈操作,先进后出 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindStack implements IteratorAggregate,Countable{ + + /** + * @var array 集合列表 + */ + private $list = array(); + /** + * @var string 列表总数指示器 + */ + private $count = 0; + + /** + * 移除并返回位于 Stack 底部的对象。 + * @return mixed + */ + public function pop(){ + if(!$this->count){ + throw new WindException("The stack is empty"); + } + --$this->count; + return array_pop($this->list); + } + + /** + * 返回位于 Stack底部的对象但不将其移除。 + * @return mixed + */ + public function peek(){ + if(!$this->count){ + throw new WindException("The stack is empty"); + } + return $this->list[$this->count-1]; + } + + /** + * 确定某元素是否在 Stack中。 + * @param mixed $value + * @return boolean + */ + public function contain($value){ + return false !== array_search($value, $this->list, true); + } + /** + * 将元素插入 Stack 的底部。 + * @param mixed $value + * @return number + */ + public function push($value){ + ++$this->count; + return array_push($this->list,$value); + } + /** + * 清空队列 + */ + public function clear(){ + $this->count = 0; + $this->list = array(); + return true; + } + /** + * 将数组中的值合并到当前tack队列 + * @param array $array 要合并的数组 + * @return boolean + */ + public function mergeFromArray($array) { + foreach ($array as $value) { + $this->push($value); + } + return true; + } + /** + * 将WindStack堆栈集合合并到当前Stack队列 + * @param WindStack $list 要合并的WindStack集合 + * @return boolean + */ + public function mergeFromStack(WindStack $stack) { + foreach ($stack as $value) { + $this->push($value); + } + return true; + } + /** + * 取得堆栈个数 + * @return string + */ + public function getCount(){ + return $this->count; + } + /* + * 计算堆栈的总个数 + * @see Countable#count() + */ + public function count() { + return $this->getCount(); + } + /** + * 取得堆栈的迭代器 + */ + public function getIterator() { + return new ArrayIterator($this->list); + } + /** + * 创建 stack的浅表副本。 + * @return WindStack + */ + public function __clone(){ + return new self(); + } +} \ No newline at end of file From 588cabd36a81c2bd6dabb2bd4e18054302d38323 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 06:02:32 +0000 Subject: [PATCH 0422/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2494 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/dao/WindDao.php | 35 + wind/dao/WindDaoFactory.php | 63 ++ wind/dao/exception/WindDaoException.php | 27 + wind/dao/listener/WindDaoCacheListener.php | 55 ++ wind/db/WindConnection.php | 281 ++++++ wind/db/WindConnectionManager.php | 71 ++ wind/db/WindResultSet.php | 165 ++++ wind/db/WindSqlStatement.php | 375 ++++++++ wind/db/drivers/mssql/WindMsSql.php | 159 ++++ wind/db/drivers/mssql/WindMsSqlBuilder.php | 93 ++ wind/db/drivers/mysql/WindMySql.php | 207 ++++ wind/db/drivers/mysql/WindMySqlBuilder.php | 99 ++ wind/db/exception/WindDbException.php | 123 +++ wind/db/mysql/WindMysqlPdoAdapter.php | 82 ++ wind/ftp/AbstractWindFtp.php | 185 ++++ wind/ftp/WindFtp.php | 186 ++++ wind/ftp/WindSocketFtp.php | 274 ++++++ wind/http/cookie/WindCookie.php | 94 ++ wind/http/cookie/WindCookieObject.php | 185 ++++ wind/http/request/IWindRequest.php | 25 + wind/http/request/WindHttpRequest.php | 669 +++++++++++++ wind/http/response/IWindResponse.php | 11 + wind/http/response/WindHttpResponse.php | 568 +++++++++++ wind/http/session/AbstractWindUserSession.php | 57 ++ wind/http/session/WindDbSession.php | 42 + wind/http/session/WindSession.php | 370 ++++++++ wind/http/transfer/AbstractWindHttp.php | 280 ++++++ wind/http/transfer/WindHttpCurl.php | 147 +++ wind/http/transfer/WindHttpSocket.php | 166 ++++ wind/http/transfer/WindHttpStream.php | 178 ++++ wind/log/WindDebug.php | 175 ++++ wind/log/WindLogger.php | 386 ++++++++ wind/mail/WindMail.php | 898 ++++++++++++++++++ wind/mail/protocol/WindImap.php | 663 +++++++++++++ wind/mail/protocol/WindPop3.php | 260 +++++ wind/mail/protocol/WindSmtp.php | 211 ++++ wind/mail/protocol/WindSocket.php | 121 +++ wind/mail/sender/IWindSendMail.php | 15 + wind/mail/sender/WindPhpMail.php | 34 + wind/mail/sender/WindSendMail.php | 85 ++ wind/mail/sender/WindSmtpMail.php | 92 ++ wind/parser/IWindConfigParser.php | 27 + wind/parser/WindConfigParser.php | 129 +++ wind/parser/WindIniParser.php | 147 +++ wind/parser/WindPropertiesParser.php | 214 +++++ wind/parser/WindXmlParser.php | 109 +++ wind/router/AbstractWindRouter.php | 170 ++++ wind/router/WindRouter.php | 40 + wind/router/WindUrlRewriteRouter.php | 346 +++++++ wind/router/route/AbstractWindRoute.php | 42 + wind/router/route/WindRewriteRoute.php | 31 + wind/router/route/WindRoute.php | 53 ++ wind/upload/AbstractWindUpload.php | 249 +++++ wind/upload/WindCurlUpload.php | 32 + wind/upload/WindFormUpload.php | 45 + wind/upload/WindFtpUpload.php | 56 ++ wind/utility/WindArray.php | 83 ++ wind/utility/WindFile.php | 254 +++++ wind/utility/WindHtmlHelper.php | 43 + wind/utility/WindImage.php | 303 ++++++ wind/utility/WindPack.php | 397 ++++++++ wind/utility/WindSecurity.php | 300 ++++++ wind/utility/WindString.php | 242 +++++ wind/utility/WindUtility.php | 82 ++ wind/utility/WindValidator.php | 344 +++++++ wind/utility/date/WindDate.php | 272 ++++++ wind/utility/date/WindGeneralDate.php | 248 +++++ wind/utility/json/WindDecoder.php | 235 +++++ wind/utility/json/WindEncoder.php | 202 ++++ wind/viewer/AbstractWindTemplateCompiler.php | 128 +++ wind/viewer/AbstractWindViewTemplate.php | 72 ++ wind/viewer/IWindView.php | 20 + wind/viewer/IWindViewerResolver.php | 26 + wind/viewer/WindLayout.php | 122 +++ wind/viewer/WindView.php | 168 ++++ wind/viewer/WindViewerResolver.php | 187 ++++ .../compiler/WindTemplateCompilerAction.php | 40 + .../WindTemplateCompilerComponent.php | 149 +++ .../compiler/WindTemplateCompilerCss.php | 23 + .../compiler/WindTemplateCompilerEcho.php | 34 + .../compiler/WindTemplateCompilerInternal.php | 25 + .../compiler/WindTemplateCompilerPage.php | 77 ++ .../compiler/WindTemplateCompilerScript.php | 33 + .../compiler/WindTemplateCompilerTemplate.php | 55 ++ wind/viewer/compiler/WindViewTemplate.php | 190 ++++ wind/viewer/errorPage/404.htm | 10 + wind/viewer/errorPage/default_error.htm | 45 + wind/viewer/exception/WindViewException.php | 30 + .../viewer/listener/WindViewCacheListener.php | 52 + 89 files changed, 14393 insertions(+) create mode 100644 wind/dao/WindDao.php create mode 100644 wind/dao/WindDaoFactory.php create mode 100644 wind/dao/exception/WindDaoException.php create mode 100644 wind/dao/listener/WindDaoCacheListener.php create mode 100644 wind/db/WindConnection.php create mode 100644 wind/db/WindConnectionManager.php create mode 100644 wind/db/WindResultSet.php create mode 100644 wind/db/WindSqlStatement.php create mode 100644 wind/db/drivers/mssql/WindMsSql.php create mode 100644 wind/db/drivers/mssql/WindMsSqlBuilder.php create mode 100644 wind/db/drivers/mysql/WindMySql.php create mode 100644 wind/db/drivers/mysql/WindMySqlBuilder.php create mode 100644 wind/db/exception/WindDbException.php create mode 100644 wind/db/mysql/WindMysqlPdoAdapter.php create mode 100644 wind/ftp/AbstractWindFtp.php create mode 100644 wind/ftp/WindFtp.php create mode 100644 wind/ftp/WindSocketFtp.php create mode 100644 wind/http/cookie/WindCookie.php create mode 100644 wind/http/cookie/WindCookieObject.php create mode 100644 wind/http/request/IWindRequest.php create mode 100644 wind/http/request/WindHttpRequest.php create mode 100644 wind/http/response/IWindResponse.php create mode 100644 wind/http/response/WindHttpResponse.php create mode 100644 wind/http/session/AbstractWindUserSession.php create mode 100644 wind/http/session/WindDbSession.php create mode 100644 wind/http/session/WindSession.php create mode 100644 wind/http/transfer/AbstractWindHttp.php create mode 100644 wind/http/transfer/WindHttpCurl.php create mode 100644 wind/http/transfer/WindHttpSocket.php create mode 100644 wind/http/transfer/WindHttpStream.php create mode 100644 wind/log/WindDebug.php create mode 100644 wind/log/WindLogger.php create mode 100644 wind/mail/WindMail.php create mode 100644 wind/mail/protocol/WindImap.php create mode 100644 wind/mail/protocol/WindPop3.php create mode 100644 wind/mail/protocol/WindSmtp.php create mode 100644 wind/mail/protocol/WindSocket.php create mode 100644 wind/mail/sender/IWindSendMail.php create mode 100644 wind/mail/sender/WindPhpMail.php create mode 100644 wind/mail/sender/WindSendMail.php create mode 100644 wind/mail/sender/WindSmtpMail.php create mode 100644 wind/parser/IWindConfigParser.php create mode 100644 wind/parser/WindConfigParser.php create mode 100644 wind/parser/WindIniParser.php create mode 100644 wind/parser/WindPropertiesParser.php create mode 100644 wind/parser/WindXmlParser.php create mode 100644 wind/router/AbstractWindRouter.php create mode 100644 wind/router/WindRouter.php create mode 100644 wind/router/WindUrlRewriteRouter.php create mode 100644 wind/router/route/AbstractWindRoute.php create mode 100644 wind/router/route/WindRewriteRoute.php create mode 100644 wind/router/route/WindRoute.php create mode 100644 wind/upload/AbstractWindUpload.php create mode 100644 wind/upload/WindCurlUpload.php create mode 100644 wind/upload/WindFormUpload.php create mode 100644 wind/upload/WindFtpUpload.php create mode 100644 wind/utility/WindArray.php create mode 100644 wind/utility/WindFile.php create mode 100644 wind/utility/WindHtmlHelper.php create mode 100644 wind/utility/WindImage.php create mode 100644 wind/utility/WindPack.php create mode 100644 wind/utility/WindSecurity.php create mode 100644 wind/utility/WindString.php create mode 100644 wind/utility/WindUtility.php create mode 100644 wind/utility/WindValidator.php create mode 100644 wind/utility/date/WindDate.php create mode 100644 wind/utility/date/WindGeneralDate.php create mode 100644 wind/utility/json/WindDecoder.php create mode 100644 wind/utility/json/WindEncoder.php create mode 100644 wind/viewer/AbstractWindTemplateCompiler.php create mode 100644 wind/viewer/AbstractWindViewTemplate.php create mode 100644 wind/viewer/IWindView.php create mode 100644 wind/viewer/IWindViewerResolver.php create mode 100644 wind/viewer/WindLayout.php create mode 100644 wind/viewer/WindView.php create mode 100644 wind/viewer/WindViewerResolver.php create mode 100644 wind/viewer/compiler/WindTemplateCompilerAction.php create mode 100644 wind/viewer/compiler/WindTemplateCompilerComponent.php create mode 100644 wind/viewer/compiler/WindTemplateCompilerCss.php create mode 100644 wind/viewer/compiler/WindTemplateCompilerEcho.php create mode 100644 wind/viewer/compiler/WindTemplateCompilerInternal.php create mode 100644 wind/viewer/compiler/WindTemplateCompilerPage.php create mode 100644 wind/viewer/compiler/WindTemplateCompilerScript.php create mode 100644 wind/viewer/compiler/WindTemplateCompilerTemplate.php create mode 100644 wind/viewer/compiler/WindViewTemplate.php create mode 100644 wind/viewer/errorPage/404.htm create mode 100644 wind/viewer/errorPage/default_error.htm create mode 100644 wind/viewer/exception/WindViewException.php create mode 100644 wind/viewer/listener/WindViewCacheListener.php diff --git a/wind/dao/WindDao.php b/wind/dao/WindDao.php new file mode 100644 index 00000000..567e87ab --- /dev/null +++ b/wind/dao/WindDao.php @@ -0,0 +1,35 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindDao extends WindModule { + /** + * @var object + */ + protected $connection = null; + + /** + * 根据用户配置决定配置是采用配置链接管理 + * @return WindConnection + */ + public function getConnection($name = '') { + $this->_getConnection(); + if ($this->connection instanceof WindConnectionManager) { + return $this->connection->getConnection($name); + } + return $this->connection; + } + + /** + * @param field_type $connection + */ + public function setConnection($connection) { + $this->connection = $connection; + } +} +?> \ No newline at end of file diff --git a/wind/dao/WindDaoFactory.php b/wind/dao/WindDaoFactory.php new file mode 100644 index 00000000..009e610d --- /dev/null +++ b/wind/dao/WindDaoFactory.php @@ -0,0 +1,63 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindDaoFactory extends WindModule { + /** + * dao路径信息 + * @var string + */ + protected $daoResource = ''; + + /** + * 返回Dao类实例 + * $className接受两种形式呃参数如下 + * 'namespace:path' + * 'className' + * + * @param string $className + * @return WindDao + */ + public function getDao($className) { + try { + if (strpos($className, ":") === false) + $className = $this->getDaoResource() . '.' . $className; + Wind::getApp()->getWindFactory()->addClassDefinitions($className, + array('path' => $className, 'scope' => 'application')); + $daoInstance = Wind::getApp()->getWindFactory()->getInstance($className); + $daoInstance->setDelayAttributes(array('connection' => array('ref' => 'db'))); + return $daoInstance; + } catch (Exception $exception) { + throw new WindDaoException( + '[component.dao.WindDaoFactory] create dao ' . $className . ' fail.' . $exception->getMessage()); + } + } + + /** + * 获得dao存放的目录 + * @return string $daoResource + */ + public function getDaoResource() { + return $this->daoResource; + } + + /** + * 设置dao的获取目录 + * @param string $daoResource + */ + public function setDaoResource($daoResource) { + $this->daoResource = $daoResource; + } +} +?> \ No newline at end of file diff --git a/wind/dao/exception/WindDaoException.php b/wind/dao/exception/WindDaoException.php new file mode 100644 index 00000000..69cb36e5 --- /dev/null +++ b/wind/dao/exception/WindDaoException.php @@ -0,0 +1,27 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindDaoException extends WindException { + + /** + * 自定义异常号的对应异常信息 + * + * @param int $code 异常号 + * @return string 返回异常号对应的异常组装信息原型 + */ + protected function messageMapper($code) { + $messages = array(); + + return isset($messages[$code]) ? $messages[$code] : '$message'; + } +} + +?> \ No newline at end of file diff --git a/wind/dao/listener/WindDaoCacheListener.php b/wind/dao/listener/WindDaoCacheListener.php new file mode 100644 index 00000000..e35b2c6b --- /dev/null +++ b/wind/dao/listener/WindDaoCacheListener.php @@ -0,0 +1,55 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindDaoCacheListener extends WindHandlerInterceptor { + + private $daoObject = null; + + /** + * @param AbstractWindDao $instance + */ + function __construct($instance) { + $this->daoObject = $instance; + } + + /* + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + /* @var $cacheHandler AbstractWindCache */ + $cacheHandler = $this->daoObject->getCacheHandler(); + $key = $this->generateKey(func_get_args()); + $result = $cacheHandler->get($key); + return empty($result) ? null : $result; + } + + /* + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + /* @var $cacheHandler AbstractWindCache */ + $cacheHandler = $this->daoObject->getCacheHandler(); + $key = $this->generateKey(func_get_args()); + $cacheHandler->set($key, $this->result); + } + + /** + * 返回缓存键值 + * @param array $args + * @return string + */ + private function generateKey($args) { + return $this->event[0] . '_' . $this->event[1] . '_' . (is_array($args[0]) ? $args[0][0] : $args[0]); + } +} + +?> \ No newline at end of file diff --git a/wind/db/WindConnection.php b/wind/db/WindConnection.php new file mode 100644 index 00000000..ffd2220a --- /dev/null +++ b/wind/db/WindConnection.php @@ -0,0 +1,281 @@ + + * @version $Id$ + * @package + */ +class WindConnection extends WindModule { + /** + * PDO 链接字符串 + * @var string + */ + private $_dsn; + private $_driverName; + private $_user; + private $_pwd; + private $_tablePrefix; + private $_charset; + private $_enableLog = false; + /** + * @var array + */ + private $_attributes = array(); + /** + * @var PDO + */ + private $_dbHandle = null; + + /** + * @param string $dsn + * @param string $username + * @param string $password + */ + public function __construct($dsn = '', $username = '', $password = '') { + $this->_dsn = $dsn; + $this->_user = $username; + $this->_pwd = $password; + } + + /** + * 接受一条sql语句,并返回sqlStatement对象 + * @param string $sql | sql语句 + * @return WindSqlStatement + */ + public function createStatement($sql = null) { + return new WindSqlStatement($this, $sql); + } + + /** + * 返回数据库链接对象 + * @return WindMysqlPdoAdapter + */ + public function getDbHandle() { + if ($this->_dbHandle === null) + $this->init(); + return $this->_dbHandle; + } + + /** + * 获得链接相关属性设置 + * @param string $attribute + * @return string + * */ + public function getAttribute($attribute = '') { + if (!$attribute) + return; + if ($this->_dbHandle !== null) { + return $this->_dbHandle->getAttribute($attribute); + } else + return isset($this->_attributes[$attribute]) ? $this->_attributes[$attribute] : ''; + } + + /** + * 设置链接相关属性 + * @param string $attribute + * @param string $value + * @return + * */ + public function setAttribute($attribute, $value = null) { + if (!$attribute) + return; + if ($this->_dbHandle !== null && $this->_dbHandle instanceof PDO) { + $this->_dbHandle->setAttribute($attribute, $value); + } else + $this->_attributes[$attribute] = $value; + } + + /** + * 返回DB驱动类型 + * @return string + */ + public function getDriverName() { + if ($this->_driverName) + return $this->_driverName; + if ($this->_dbHandle !== null) { + $this->_driverName = $this->_dbHandle->getAttribute(PDO::ATTR_DRIVER_NAME); + } elseif (($pos = strpos($this->_dsn, ':')) !== false) { + $this->_driverName = strtolower(substr($this->_dsn, 0, $pos)); + } + return $this->_driverName; + } + + /** + * 执行一条sql语句 同时返回影响行数 + * @param string $sql | SQL statement + * @return int + */ + public function execute($sql) { + try { + $result = $this->getDbHandle()->exec($sql); + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindConnection.execute] \r\n\tSQL: " . $sql . + " \r\n\tResult:" . WindString::varToString( + $result)); + return $result; + } catch (PDOException $e) { + $this->close(); + throw new WindDbException($e->getMessage()); + } + } + + /** + * 执行一条查询同时返回结果集 + * @param string $sql | SQL statement + * @return WindResultSet + */ + public function query($sql) { + try { + $statement = $this->getDbHandle()->query($sql); + return new WindResultSet($statement); + } catch (PDOException $e) { + throw new WindDbException(); + } + } + + /** + * 过滤SQL元数据,数据库对象(如表名字,字段等) + * + * @param string $data + * @throws WindDbException + */ + public function sqlMetadata($data) { + $data = str_replace(array('`', ' '), '', $data); + return ' `' . $data . '` '; + } + + /** + * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组 + * + * @param array $array + */ + public function quoteArray($array) { + return $this->getDbHandle()->filterArray($array); + } + + /** + * sql元数据安全过滤 + * + * @param string $string + */ + public function quote($string) { + return $this->getDbHandle()->quote($string); + } + + /** + * 组装单条 key=value 形式的SQL查询语句值 insert/update并进行安全过滤 + * + * @param array $array + */ + public function sqlSingle($array) { + return $this->getDbHandle()->sqlSingle($array); + } + + /** + * 创建表 + * + * @param string $tableName + * @param array $fileds + */ + public function createTable($tableName, $values, $engine = '', $autoIncrement = '') { + return $this->getDbHandle()->createTable($tableName, $values, $engine, $this->_charset, + $autoIncrement); + } + + /** + * 返回最后一条插入数据ID + * + * @param string $name + * @return int + */ + public function lastInsertId($name = '') { + if ($name) + return $this->getDbHandle()->lastInsertId($name); + else + return $this->getDbHandle()->lastInsertId(); + } + + /** + * 关闭数据库连接 + */ + public function close() { + $this->_dbHandle = null; + } + + /** + * 初始化DB句柄 + * + * @throws Exception + * @return + */ + public function init() { + try { + $driverName = $this->getDriverName(); + $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; + $dbHandleClass = Wind::import($dbHandleClass); + $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, + (array) $this->_attributes); + $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->_dbHandle->setCharset($this->_charset); + if (WIND_DEBUG & 2) { + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindConnection.init] Initialize db connection success. \r\n\tDSN:" . $this->_dsn . "\r\n\tUser:" . $this->_user . "\r\n\tCharset:" . $this->_charset . "\r\n\tTablePrefix:" . $this->_tablePrefix . "\r\n\tDriverName:" . $this->_driverName, + 'component.db'); + } + } catch (PDOException $e) { + $this->close(); + throw new WindDbException($e->getMessage()); + } + } + + /** + * (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->_dsn = $this->getConfig('dsn', '', $this->_dsn); + $this->_user = $this->getConfig('user', '', $this->_user); + $this->_pwd = $this->getConfig('pwd', '', $this->_pwd); + $this->_enableLog = $this->getConfig('enablelog', '', $this->_enableLog); + $this->_charset = $this->getConfig('charset', '', $this->_charset); + $this->_tablePrefix = $this->getConfig('tableprefix', '', $this->_tablePrefix); + } + + /** + * 获得是否启用日志记录功能 + * @return boolean $enableLog + */ + public function getEnableLog() { + return $this->_enableLog; + } + + /** + * 设置是否启用日志记录功能 + * @param boolean $enableLog + */ + public function setEnableLog($enableLog) { + $this->_enableLog = (boolean) $enableLog; + } + + /** + * 获得表前缀 + * @return string $tablePrefix + */ + public function getTablePrefix() { + return $this->_tablePrefix; + } + + /** + * 设置表前缀 + * @param string $tablePrefix + */ + public function setTablePrefix($tablePrefix) { + $this->_tablePrefix = $tablePrefix; + } +} +?> \ No newline at end of file diff --git a/wind/db/WindConnectionManager.php b/wind/db/WindConnectionManager.php new file mode 100644 index 00000000..7f79e1d5 --- /dev/null +++ b/wind/db/WindConnectionManager.php @@ -0,0 +1,71 @@ + + * + * mysql:host=localhost;dbname=test + * root + * root + * utf8 + * pw_ + * + * + * mysql:host=localhost;dbname=test + * root + * root + * utf8 + * pw_ + * + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindConnectionManager extends WindConnection { + /** + * 链接池 + * @var array + */ + private $connPool = array(); + + /* (non-PHPdoc) + * @see WindConnection::init() + */ + public function init() { + try { + $driverName = $this->getDriverName(); + $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; + $dbHandleClass = Wind::import($dbHandleClass); + $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, + (array) $this->_attributes); + $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->_dbHandle->setCharset($this->_charset); + if (WIND_DEBUG & 2) { + $reflection = new ReflectionClass(get_class($this)); + $properties = $reflection->getProperties(); + Wind::getApp()->getComponent('windLogger')->info( + "component.db.WindConnection.init() Initialize db connection success." . WindString::varToString( + $properties), 'component.db'); + } + } catch (PDOException $e) { + $this->close(); + throw new WindDbException($e->getMessage()); + } + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + if ($config) { + if (is_string($config)) + $config = Wind::getApp()->getComponent('configParser')->parse($config); + if (!empty($this->_config)) { + $this->_config = array_merge($this->_config, (array) $config); + } else + $this->_config = $config; + } + } +} \ No newline at end of file diff --git a/wind/db/WindResultSet.php b/wind/db/WindResultSet.php new file mode 100644 index 00000000..10548c2f --- /dev/null +++ b/wind/db/WindResultSet.php @@ -0,0 +1,165 @@ + + * @version $Id$ + * @package + */ +class WindResultSet { + /** + * @var PDOStatement + */ + private $_statement = null; + /** + * PDO fetchMode, default fetchMode PDO::FETCH_ASSOC + * @var number + */ + private $_fetchMode = PDO::FETCH_ASSOC; + /** + * PDO fetchType, default fetchType PDO::FETCH_ORI_FIRST + * @var number + */ + private $_fetchType = PDO::FETCH_ORI_FIRST; + private $_columns = array(); + + /** + * 构造函数 + * + * @param WindSqlStatement $sqlStatement 预处理对象 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL + */ + public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { + if ($sqlStatement instanceof WindSqlStatement) { + $this->_statement = $sqlStatement->getStatement(); + $this->_columns = $sqlStatement->getColumns(); + } else + $this->_statement = $sqlStatement; + if ($fetchMode != 0) + $this->_fetchMode = $fetchMode; + if ($fetchMode != 0) + $this->_fetchType = $fetchType; + } + + /** + * 设置获取模式 + * + * @param int $fetchMode 设置获取的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM... + * @param boolean $flush 是否统一设置所有PDOStatement中的获取方式 + */ + public function setFetchMode($fetchMode, $flush = false) { + $this->_fetchMode = $fetchMode; + if ($flush) { + $fetchMode = func_get_args(); + call_user_func_array(array($this->_statement, 'setFetchMode'), $fetchMode); + } + } + + /** + * 返回最后一条Sql语句的影响行数 + * + * @return int + */ + public function rowCount() { + return $this->_statement->rowCount(); + } + + /** + * 返回结果集中的列数 + * + * @return number + */ + public function columnCount() { + return $this->_statement->columnCount(); + } + + /** + * 获得结果集的下一行 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,设置Statement的属性设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL + * @return array + */ + public function fetch($fetchMode = 0, $fetchType = 0) { + if ($fetchMode === 0) + $fetchMode = $this->_fetchMode; + if ($fetchType === 0) + $fetchMode = $this->_fetchType; + return $this->_fetch($fetchMode, $fetchType); + } + + /** + * (non-PHPdoc) + * @see WindResult::fetch() + */ + private function _fetch($fetchMode, $fetchType) { + if (!empty($this->_columns)) + $fetchMode = PDO::FETCH_BOUND; + $result = array(); + if ($row = $this->_statement->fetch($fetchMode, $fetchType)) { + if (empty($this->_columns)) + $result = $row; + else + foreach ($this->_columns as $key => $value) { + $result[$key] = $value; + } + } + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindResultSet._fetch] \r\n\tResult:" . WindString::varToString( + $result)); + + return $result; + } + + /** + * 返回所有的查询结果 + * + * @param string $index 输出数组下标 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @return array + */ + public function fetchAll($index = '', $fetchMode = 0) { + if ($fetchMode === 0) + $fetchMode = $this->_fetchMode; + $result = array(); + if (!$index) + while ($row = $this->fetch($fetchMode)) + $result[] = $row; + else + while ($row = $this->fetch($fetchMode)) { + if (!isset($row[$index])) + continue; + $result[$row[$index]] = $row; + } + return $result; + } + + /** + * 从下一行记录中获得下标是$index的值,如果获取失败则返回false + * + * @param int $index 列下标 + * @return string|bool + */ + public function fetchColumn($index = 0) { + $result = $this->_statement->fetchColumn($index); + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindResultSet.fetchColumn] \r\n\tResult:" . WindString::varToString( + $result)); + return $result; + } + + /** + * 获得结果集中的下一行,同时根据设置的类返回如果没有设置则返回的使StdClass对象 + * + * @param string $className 使用的类 + * @param array $ctor_args 初始化参数 + * @return object + */ + public function fetchObject($className = '', $ctor_args = array()) { + if ($className === '') + return $this->_statement->fetchObject(); + else + return $this->_statement->fetchObject($className, $ctor_args); + } +} +?> \ No newline at end of file diff --git a/wind/db/WindSqlStatement.php b/wind/db/WindSqlStatement.php new file mode 100644 index 00000000..e3cfa7a2 --- /dev/null +++ b/wind/db/WindSqlStatement.php @@ -0,0 +1,375 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindSqlStatement { + /** + * @var WindConnection + */ + private $_connection; + /** + * @var PDOStatement + */ + private $_statement = null; + /** + * sql语句字符串 + * + * @var string + */ + private $_queryString; + /** + * PDO类型映射 + * + * @var array + */ + private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, + 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); + private $_columns = array(); + + /** + * 构造函数 + * + * @param WindConnection $connection WindConnection对象 + * @param string $query 预定义语句 + */ + public function __construct($connection, $query) { + $this->_connection = $connection; + $this->setQueryString($query); + } + + /** + * 参数绑定 + * + * @param mixed $parameter 预定义语句的待绑定的位置 + * @param mixed &$variable 绑定的值 + * @param int $dataType 值的类型(PDO::PARAM_STR/PDO::PARAM_INT...) + * @param int $length 绑定值的长度 + * @param mixed $driverOptions + * @throws WindDbException + * @return WindSqlStatement + */ + public function bindParam($parameter, &$variable, $dataType = null, $length = null, $driverOptions = null) { + try { + $this->init(); + if ($dataType === null) { + $dataType = $this->_getPdoDataType($variable); + } + if ($length === null) + $this->getStatement()->bindParam($parameter, $variable, $dataType); + else + $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, + $driverOptions); + return $this; + } catch (PDOException $e) { + throw new WindDbException($e->getMessage()); + } + } + + /** + * 批量绑定变量 + * + * 如果是一维数组,则使用key=>value的形式,key代表变量位置,value代表替换的值,而替换值需要的类型则通过该值的类型来判断---不准确 + * 如果是一个二维数组,则允许,key=>array(0=>value, 1=>data_type, 2=>length, 3=>driver_options)的方式来传递变量。 + * + * @param array $parameters + * @throws WindDbException + * @return WindSqlStatement + */ + public function bindParams(&$parameters) { + if (!is_array($parameters)) + throw new WindDbException( + '[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype( + $parameters)); + + $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1)); + foreach ($parameters as $key => $value) { + $_key = $keied ? $key : $key + 1; + if (is_array($value)) { + $dataType = isset($value[1]) ? $value[1] : $this->_getPdoDataType($value[0]); + $length = isset($value[2]) ? $value[2] : null; + $driverOptions = isset($value[3]) ? $value[3] : null; + $this->bindParam($_key, $parameters[$key][0], $dataType, $length, $driverOptions); + } else + $this->bindParam($_key, $parameters[$key], $this->_getPdoDataType($value)); + } + return $this; + } + + /** + * 参数绑定 + * + * @param string $parameter 预定义语句的待绑定的位置 + * @param string $value 绑定的值 + * @param int $data_type 值的类型 + * @throws WindDbException + * @return WindSqlStatement + */ + public function bindValue($parameter, $value, $data_type = null) { + try { + $this->init(); + if ($data_type === null) + $data_type = $this->_getPdoDataType($value); + $this->getStatement()->bindValue($parameter, $value, $data_type); + return $this; + } catch (PDOException $e) { + throw new WindDbException($e->getMessage()); + } + } + + /** + * 调用bindValue的批量绑定参数 + * + * @param array $values 待绑定的参数值 + * @throws WindDbException + * @return WindSqlStatement + */ + public function bindValues($values) { + if (!is_array($values)) + throw new WindDbException( + '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type \'' . gettype( + $values) . '\''); + + $keied = (array_keys($values) !== range(0, sizeof($values) - 1)); + foreach ($values as $key => $value) { + if (!$keied) + $key = $key + 1; + $this->bindValue($key, $value, $this->_getPdoDataType($value)); + } + return $this; + } + + /** + * 绑定输出结果集的列到PHP变量 + * + * @param mixed $column 需要被绑定的字段列表,可以是字段名,也可以是字段的对应的下标 + * @param mixed &$param 需要被绑定的php变量 + * @param int $type 参数的数据类型 PDO::PARAM_* + * @param int $maxlen A hint for pre-allocation. + * @param mixed $driverdata Optional parameter(s) for the driver. + * @throws WindDbException + * @return WindSqlStatement + */ + public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $driverdata = null) { + try { + $this->init(); + if ($type == null) + $type = $this->_getPdoDataType($param); + if ($type == null) + $this->getStatement()->bindColumn($column, $param); + elseif ($maxlen == null) + $this->getStatement()->bindColumn($column, $param, $type); + else + $this->getStatement()->bindColumn($column, $param, $type, $maxlen, $driverdata); + $this->_columns[$column] = & $param; + return $this; + } catch (PDOException $e) { + throw new WindDbException($e->getMessage()); + } + } + + /** + * 批量绑定输出结果集的列到PHP变量 + * + * @param array $columns 待绑定的列 + * @param array &$param 需要绑定的php变量 + * @return WindSqlStatement + */ + public function bindColumns($columns, &$param = array()) { + $int = 0; + foreach ($columns as $value) { + $this->bindColumn($value, $param[$int++]); + } + return $this; + } + + /** + * 绑定参数,执行SQL语句,并返回更新影响行数 + * @param array $params 预定义语句中需要绑定的参数 + * @param boolean $rowCount 是否返回影响行数 + * @throws WindDbException + * @return int|boolean + */ + public function update($params = array(), $rowCount = false) { + return $this->execute($params, $rowCount); + } + + /** + * 绑定参数,执行SQL语句,并返回查询结果 + * + * @param array $params 预定义语句中需要绑定的参数 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL + * @return WindResultSet + */ + public function query($params = array(), $fetchMode = 0, $fetchType = 0) { + $this->execute($params, false); + return new WindResultSet($this, $fetchMode, $fetchType); + } + + /** + * 绑定参数,执行SQL语句,并返回查询结果 + * + * @param array $params 预定义语句中需要绑定的参数 + * @param string $index 返回的数组的下标对应的字段 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL + * @return array 返回处理后的结果 + */ + public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) { + $this->execute($params, false); + $rs = new WindResultSet($this, $fetchMode, $fetchType); + return $rs->fetchAll($index); + } + + /** + * 绑定参数,执行SQL语句,并返回查询到的结果集中某一个列的值 + * + * @param array $params 预定义语句中需要绑定的参数 + * @param int $column 列的下标,默认为0即第一列 + * @return string + */ + public function getValue($params = array(), $column = 0) { + $this->execute($params, false); + $rs = new WindResultSet($this, PDO::FETCH_NUM, 0); + return $rs->fetchColumn($column); + } + + /** + * 绑定参数,执行SQL语句,并返回一行查询结果 + * + * @param array $params 预定义语句中需要绑定的参数 + * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM + * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL + * @return array + */ + public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { + $this->execute($params, false); + $rs = new WindResultSet($this, $fetchMode, $fetchType); + return $rs->fetch(); + } + + /* (non-PHPdoc) + * @see WindConnection::lastInsterId() + */ + public function lastInsertId($name = '') { + return $this->getConnection($name); + } + + /** + * 绑定参数,执行SQL语句,并返回影响行数 + * + * @param array $params -- 绑定的参数和bindValues的参数一样 + * @param boolean $rowCount 是否返回受印象行数 + * @return rowCount + */ + public function execute($params = array(), $rowCount = true) { + try { + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->profileBegin( + 'SQL:execute sql statement.', 'component.db'); + $this->init(); + $this->bindValues($params); + $this->getStatement()->execute(); + $_result = $rowCount ? $this->getStatement()->rowCount() : true; + if (WIND_DEBUG & 2) { + Wind::getApp()->getComponent('windLogger')->profileEnd( + 'SQL:execute sql statement.', 'component.db'); + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindSqlStatement.execute] \r\n\tSQL:" . $this->getQueryString(), + 'component.db'); + } + return $_result; + } catch (PDOException $e) { + throw new WindDbException('[component.db.WindSqlStatement.execute]' . $e->getMessage()); + } + } + + /** + * 设置查询预定义语句 + * + * @param string $queryString + * @return WindSqlStatement + */ + public function setQueryString($queryString) { + if (!$queryString) + return $this; + if ($_prefix = $this->getConnection()->getTablePrefix()) { + list($new, $old) = strpos($_prefix, '|') !== false ? explode('|', $_prefix) : array( + $_prefix, ''); + $queryString = preg_replace('/{(' . $old . ')?(.*?)}/', $new . '\2', $queryString); + } + $this->_queryString = $queryString; + return $this; + } + + /** + * 获得查询的预定义语句 + * + * @return string $_queryString + */ + public function getQueryString() { + return $this->_queryString; + } + + /** + * 获得PDO链接对象 + * + * @return WindConnection + */ + public function getConnection() { + return $this->_connection; + } + + /** + * 获得PDOStatement对象 + * + * @return PDOStatement + */ + public function getStatement() { + return $this->_statement; + } + + /** + * 获得需要绑定的结果输出的列值 + * + * @return array $_columns + */ + public function getColumns() { + return $this->_columns; + } + + /** + * 初始化数据库链接信息 + */ + public function init() { + if ($this->_statement === null) { + try { + $this->_statement = $this->getConnection()->getDbHandle()->prepare( + $this->getQueryString()); + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + "[component.db.WindSqlStatement.init] Initialize statement success.", + 'component.db'); + } catch (PDOException $e) { + throw new WindDbException( + "Initialization WindSqlStatement failed." . $e->getMessage()); + } + } + } + + /** + * 获得绑定参数的类型 + * + * @param string $variable + * @return int + */ + private function _getPdoDataType($variable) { + return isset($this->_typeMap[gettype($variable)]) ? $this->_typeMap[gettype($variable)] : PDO::PARAM_STR; + } +} +?> \ No newline at end of file diff --git a/wind/db/drivers/mssql/WindMsSql.php b/wind/db/drivers/mssql/WindMsSql.php new file mode 100644 index 00000000..af1e8674 --- /dev/null +++ b/wind/db/drivers/mssql/WindMsSql.php @@ -0,0 +1,159 @@ + 2010-11-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.drivers.AbstractWindDbAdapter'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMsSql extends AbstractWindDbAdapter { + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#connect() + */ + protected function connect() { + if (!is_resource($this->connection) || ($this->config[IWindDbConfig::FORCE])) { + $host = isset($this->config[IWindDbConfig::PORT]) ? $this->config[IWindDbConfig::HOST] . ':' . $this->config[IWindDbConfig::PORT] : $this->config[IWindDbConfig::HOST]; + $user = $this->config[IWindDbConfig::USER]; + $pass = $this->config[IWindDbConfig::PASS]; + $pconnect = ('true' === $this->config[IWindDbConfig::PCONNECT] ); + $this->connection = $pconnect ? mssql_pconnect($host, $user, $pass) : mssql_connect($host, $user, $pass, $this->config[IWindDbConfig::FORCE]); + $this->changeDB($this->config[IWindDbConfig::NAME]); + } + return $this->connection; + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#query() + */ + public function query($sql) { + $this->query = mssql_query($sql, $this->connection); + $this->error($sql); + return true; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getAffectedRows() + */ + public function getAffectedRows() { + $this->query('SELECT @@ROWCOUNT AS affectedRow'); + $row = $this->getRow(); + return (int) $row['affectedRow']; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getLastInsertId() + */ + public function getLastInsertId() { + $this->query('SELECT @@IDENTITY as insertId'); + $row = $this->getRow(); + return (int) $row['insertId']; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getMetaTables() + */ + public function getMetaTables($schema = '') { + $schema = $schema ? $schema : $this->getSchema(); + if (empty($schema)) { + throw new WindSqlException('', WindSqlException::DB_EMPTY); + } + $this->query("SELECT name,object_id FROM {$schema}.sys.all_objects WHERE type = 'U'"); + return $this->getAllRow(IWindDbConfig::ASSOC); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getMetaColumns() + */ + public function getMetaColumns($table) { + if (empty($table)) { + throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); + } + $this->query('SELECT b.name Field,b.max_length,b.precision,b.scale,b.is_nullable,b.is_identity FROM sys.objects a + INNER JOIN sys.all_columns b ON a.object_id = b.object_id + INNER JOIN sys.types c ON b.system_type_id = c.system_type_id where a.name = ' . $this->escapeString($table)); + return $this->getAllRow(IWindDbConfig::ASSOC); + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#getAllRow() + */ + public function getAllRow($resultIndex = null,$fetch_type = IWindDbConfig::ASSOC) { + if (!is_resource($this->query)) { + throw new WindSqlException('', WindSqlException::DB_QUERY_LINK_EMPTY); + } + if (!in_array($fetch_type, array(1, 2, 3))) { + throw new WindSqlException('', WindSqlException::DB_QUERY_FETCH_ERROR); + } + $result = array(); + while (false !== ($record = mssql_fetch_array($this->query, $fetch_type))) { + if($resultIndex && isset($record[$resultIndex])){ + $result[$record[$resultIndex]] = $record; + }else{ + $result[] = $record; + } + } + return $result; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getRow() + */ + public function getRow($fetch_type = IWindDbConfig::ASSOC) { + return mssql_fetch_array($this->query, $fetch_type); + } + + /** + *@see wind/component/db/base/WindDbAdapter#beginTrans() + */ + public function beginTrans() { + + } + + /** + * @see wind/component/db/base/WindDbAdapter#commitTrans() + */ + public function commitTrans() { + + } + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#close() + */ + public function close() { + if (is_resource($this->connection)) { + mssql_close($this->connection); + } + } + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#dispose() + */ + public function dispose() { + $this->close($this->connection); + $this->connection = null; + $this->query = null; + } + + /** + * 切换数据库 + * @see wind/base/WDbAdapter#changeDB() + * @param string $databse 要切换的数据库 + * @param string|int|resource $key 数据库连接标识 + * @return boolean + */ + public function changeDB($database) { + return mssql_select_db($database, $this->connection); + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#error() + */ + protected function error($sql) { + $this->last_sql = $sql; + return true; + } +} \ No newline at end of file diff --git a/wind/db/drivers/mssql/WindMsSqlBuilder.php b/wind/db/drivers/mssql/WindMsSqlBuilder.php new file mode 100644 index 00000000..096d0bb4 --- /dev/null +++ b/wind/db/drivers/mssql/WindMsSqlBuilder.php @@ -0,0 +1,93 @@ + 2010-11-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.db.drivers.AbstractWindSqlBuilder'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMsSqlBuilder extends AbstractWindSqlBuilder { + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getInsertSql() + */ + public function getInsertSql() { + $sql = sprintf('INSERT %s(%s) VALUES %s', $this->buildFrom(), $this->buildField(), $this->buildData()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getUpdateSql() + */ + public function getUpdateSql() { + $sql = sprintf('UPDATE %s SET %s%s%s', $this->buildFrom(), $this->buildSet(), $this->buildWhere(), $this->buildOrder()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getDeleteSql() + */ + public function getDeleteSql() { + $sql = sprintf('DELETE FROM %s%s%s', $this->buildFrom(), $this->buildWhere(), $this->buildOrder()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getSelectSql() + */ + public function getSelectSql() { + $sql = sprintf('SELECT %s%s FROM %s%s%s%s%s%s', $this->buildDistinct(), $this->buildField(), $this->buildFROM(), $this->buildJoin(), $this->buildWhere(), $this->buildGroup(), $this->buildHaving(), $this->buildOrder()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getReplaceSql() { + return ''; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getLastInsertIdSql() { + return sprintf('SELECT ' . '%s', '@@IDENTITY AS insertId'); + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getAffectedSql($ifquery = true) { + return sprintf('SELECT ' . '%s', '@@ROWCOUNT AS affectedRows'); + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getMetaTableSql() + */ + public function getMetaTableSql($schema) { + $schema = $schema ? $schema . '.' : ''; + return "SELECT name,object_id FROM {$schema}sys.all_objects WHERE type = 'U'"; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindSqlBuilder#getMetaColumnSql() + */ + public function getMetaColumnSql($table) { + if (empty($table)) { + throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); + } + $sql = $this->from('sys.objects', 'a')->field('b.name Field,b.max_length,b.precision,b.scale,b.is_nullable,b.is_identity')->innerJoin('sys.all_columns', 'a.object_id = b.object_id', 'b')->innerJoin('sys.types', 'b.system_type_id = c.system_type_id', 'c')->where('a.name = ? ', $table)->getSelectSql(); + return $sql; + + } + +} \ No newline at end of file diff --git a/wind/db/drivers/mysql/WindMySql.php b/wind/db/drivers/mysql/WindMySql.php new file mode 100644 index 00000000..981d447a --- /dev/null +++ b/wind/db/drivers/mysql/WindMySql.php @@ -0,0 +1,207 @@ + 2010-11-11 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.db.drivers.AbstractWindDbAdapter'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMySql extends AbstractWindDbAdapter { + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#connect() + */ + protected function connect() { + if (!is_resource($this->connection) || $this->config[IWindDbConfig::FORCE]) { + $host = isset($this->config[IWindDbConfig::PORT]) ? $this->config[IWindDbConfig::HOST] . ':' . $this->config[IWindDbConfig::PORT] : $this->config[IWindDbConfig::HOST]; + $user = $this->config[IWindDbConfig::USER]; + $pass = $this->config[IWindDbConfig::PASS]; + $pconnect = ('true' === $this->config[IWindDbConfig::PCONNECT] ); + $this->connection = $pconnect ? mysql_pconnect($host, $user, $pass) : mysql_connect($host, $user, $pass, $this->config[IWindDbConfig::FORCE]); + $this->changeDB($this->config[IWindDbConfig::NAME]); + $this->setCharset($this->config[IWindDbConfig::CHARSET]); + } else { + $this->changeDB($this->config[IWindDbConfig::NAME]); + } + return $this->connection; + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#query() + */ + public function query($sql) { + $this->query = mysql_query($sql, $this->connection); + $this->error($sql); + return true; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getAffectedRows() + */ + public function getAffectedRows() { + return mysql_affected_rows($this->connection); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getLastInsertId() + */ + public function getLastInsertId() { + return mysql_insert_id($this->connection); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getMetaTables() + */ + public function getMetaTables($schema = '') { + $schema = $schema ? $schema : $this->getSchema(); + if (empty($schema)) { + throw new WindSqlException('', WindSqlException::DB_EMPTY); + } + $this->query('SHOW TABLES FROM ' . $schema); + return $this->getAllRow(IWindDbConfig::ASSOC); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getMetaColumns() + */ + public function getMetaColumns($table) { + if (empty($table)) { + throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); + } + $this->query('SHOW COLUMNS FROM ' . $table); + return $this->getAllRow(IWindDbConfig::ASSOC); + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#getAllRow() + */ + public function getAllRow($resultIndex = null,$fetch_type = IWindDbConfig::ASSOC) { + if (!is_resource($this->query)) { + throw new WindSqlException('', WindSqlException::DB_QUERY_LINK_EMPTY); + } + if (!in_array($fetch_type, array(1, 2, 3))) { + throw new WindSqlException('', WindSqlException::DB_QUERY_FETCH_ERROR); + } + $result = array(); + while (false !== ($record = mysql_fetch_array($this->query, $fetch_type))) { + if($resultIndex && isset($record[$resultIndex])){ + $result[$record[$resultIndex]] = $record; + }else{ + $result[] = $record; + } + } + return $result; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#getRow() + */ + public function getRow($fetch_type = IWindDbConfig::ASSOC) { + return mysql_fetch_array($this->query, $fetch_type); + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindDbAdapter#beginTrans() + */ + public function beginTrans() { + if ($this->transCounter == 0) { + $this->query('START TRANSACTION'); + } elseif ($this->transCounter && $this->enableSavePoint) { + $savepoint = 'savepoint_' . $this->transCounter; + $this->query("SAVEPOINT `{$savepoint}`"); + array_push($this->savepoint, $savepoint); + } + ++$this->transCounter; + return true; + } + + /** + *@see wind/component/db/base/WindDbAdapter#commitTrans() + */ + public function commitTrans() { + if ($this->transCounter <= 0) { + throw new WindSqlException('', WindSqlException::DB_QUERY_TRAN_BEGIN); + } + --$this->transCounter; + if ($this->transCounter == 0) { + if ($this->last_errstr) { + $this->query('ROLLBACK'); + } else { + $this->query('COMMIT'); + } + } elseif ($this->enableSavePoint) { + $savepoint = array_pop($this->savepoint); + if ($this->last_errstr) { + $this->query("ROLLBACK TO SAVEPOINT `{$savepoint}`"); + } + } + } + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#close() + */ + public function close() { + if (is_resource($this->connection)) { + mysql_close($this->connection); + } + } + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#dispose() + */ + public function dispose() { + $this->close($this->connection); + $this->connection = null; + $this->query = null; + } + /** + * 取得mysql版本号 + * @param string|int|resource $key 数据库连接标识 + * @return string + */ + public function getVersion() { + return mysql_get_server_info($this->connection); + } + /** + * @param string $charset 字符集 + * @param string | int $key 数据库连接标识 + * @return boolean + */ + public function setCharset($charset) { + $version = (int) substr($this->getVersion(), 0, 1); + if ($version > 4) { + $this->query("SET NAMES '" . $charset . "'"); + } + return true; + } + + /** + * 切换数据库 + * @see wind/base/WDbAdapter#changeDB() + * @param string $databse 要切换的数据库 + * @param string|int|resource $key 数据库连接标识 + * @return boolean + */ + public function changeDB($database) { + return mysql_select_db($database, $this->connection); + } + + /* (non-PHPdoc) + * @see wind/base/WDbAdapter#error() + */ + protected function error($sql) { + $this->last_errstr = mysql_error(); + $this->last_errcode = mysql_errno(); + $this->last_sql = $sql; + if ($this->last_errstr || $this->last_errcode) { + $errInfo = 'This sql statement error has occurred:'.$this->last_sql.'.
'; + $errInfo .= 'Error Message:'.$this->last_errstr.'.
'; + throw new WindSqlException($errInfo, $this->last_errcode); + } + return true; + } + +} \ No newline at end of file diff --git a/wind/db/drivers/mysql/WindMySqlBuilder.php b/wind/db/drivers/mysql/WindMySqlBuilder.php new file mode 100644 index 00000000..3eebd80f --- /dev/null +++ b/wind/db/drivers/mysql/WindMySqlBuilder.php @@ -0,0 +1,99 @@ + 2010-11-11 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.db.drivers.AbstractWindSqlBuilder'); +/** + * mysql常用sql语句组装器 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +final class WindMySqlBuilder extends AbstractWindSqlBuilder { + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getInsertSql() + */ + public function getInsertSql() { + $sql = sprintf('INSERT %s(%s) VALUES %s', $this->buildFrom(), $this->buildField(), $this->buildData()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getUpdateSql() + */ + public function getUpdateSql() { + $sql = sprintf('UPDATE %s SET %s%s%s%s', $this->buildFrom(), $this->buildSet(), $this->buildWhere(), $this->buildOrder(), $this->buildLimit()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getDeleteSql() + */ + public function getDeleteSql() { + $sql = sprintf('DELETE FROM %s%s%s%s', $this->buildFrom(), $this->buildWhere(), $this->buildOrder(), $this->buildLimit()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getSelectSql() + */ + public function getSelectSql() { + $sql = sprintf('SELECT %s%s FROM %s%s%s%s%s%s%s', $this->buildDistinct(), $this->buildField(), $this->buildFROM(), $this->buildJoin(), $this->buildWhere(), $this->buildGroup(), $this->buildHaving(), $this->buildOrder(), $this->buildLimit()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getReplaceSql() { + $sql = sprintf('REPLACE %s(%s) VALUES %s', $this->buildFROM(), $this->buildField(), $this->buildData()); + $this->reset(); + return $sql; + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getLastInsertIdSql() { + return sprintf('SELECT ' . '%s', 'LAST_INSERT_ID() AS insertId'); + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getReplaceSql() + */ + public function getAffectedSql($ifquery = true) { + $rows = $ifquery ? 'FOUND_ROWS()' : 'ROW_COUNT()'; + return sprintf('SELECT ' . '%s', "$rows AS afftectedRows"); + } + + /* (non-PHPdoc) + * @see wind/base/WSqlBuilder#getMetaTableSql() + */ + public function getMetaTableSql($schema) { + if (empty($schema)) { + throw new WindSqlException('', WindSqlException::DB_EMPTY); + } + return 'SHOW TABLES FROM ' . $schema; + } + + /* (non-PHPdoc) + * @see wind/component/db/base/WindSqlBuilder#getMetaColumnSql() + */ + public function getMetaColumnSql($table) { + if (empty($table)) { + throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); + } + return 'SHOW COLUMNS FROM ' . $table; + } + +} + diff --git a/wind/db/exception/WindDbException.php b/wind/db/exception/WindDbException.php new file mode 100644 index 00000000..17a5813e --- /dev/null +++ b/wind/db/exception/WindDbException.php @@ -0,0 +1,123 @@ + + * @version $Id$ + * @package + */ +class WindDbException extends WindException { + + /** + * 连接相关的异常 + * @var unknown_type + */ + const DB_CONN_EMPTY = 200; + + const DB_CONN_FORMAT = 201; + + const DB_CONN_NOT_EXIST = 202; + + const DB_CONN_EXIST = 203; + + const DB_CONNECT_NOT_EXIST = 204; + + /** + * 查讯 相关的异常 + * @var unknown_type + */ + const DB_QUERY_EMPTY = 210; + + const DB_QUERY_LINK_EMPTY = 211; + + const DB_QUERY_FIELD_EMPTY = 212; + + const DB_QUERY_FIELD_EXIST = 213; + + const DB_QUERY_FIELD_FORMAT = 214; + + const DB_QUERY_INSERT_DATA = 215; + + const DB_QUERY_UPDATE_DATA = 216; + + const DB_QUERY_CONDTTION_FORMAT = 217; + + const DB_QUERY_GROUP_MATCH = 218; + + const DB_QUERY_LOGIC_MATCH = 219; + + const DB_QUERY_FETCH_ERROR = 220; + + const DB_QUERY_TRAN_BEGIN = 221; + + const DB_QUERY_COMPARESS_ERROR = 222; + + const DB_QUERY_COMPARESS_EXIST = 223; + + const DB_QUERY_WHERE_ERROR = 224; + + const DB_QUERY_JOIN_TYPE_ERROR = 225; + + /** + * 字段异常 + * @var unknown_type + */ + const DB_TABLE_EMPTY = 240; + + const DB_EMPTY = 241; + + const DB_DRIVER_NOT_EXIST = 242; + + const DB_DRIVER_EXIST = 243; + + const DB_BUILDER_NOT_EXIST = 250; + + const DB_BUILDER_EXIST = 251; + + const DB_DRIVER_BUILDER_NOT_MATCH = 252; + + const DB_ADAPTER_NOT_EXIST = 260; + + const DB_ADAPTER_EXIST = 261; + + /** + * 重定义异常类型 + * + * @see WindException::messageMapper() + * @param int $code 异常号 + * @return string 最终输出异常信息的原型 + */ + protected function messageMapper($code) { + $messages = array(self::DB_CONN_EMPTY => 'Database configuration is empty. \'$message\' ', + self::DB_CONN_FORMAT => 'Database configuration format is incorrect. \'$message\' ', + self::DB_CONN_NOT_EXIST => '\'$message\' The identify of the database connection does not exist. ', + self::DB_CONN_EXIST => '\'$message\' The identify of the database connection is aleady exist.', + self::DB_CONNECT_NOT_EXIST => '\'$message\' The database connection does not exist.', + self::DB_QUERY_EMPTY => 'Query is empty. \'$message\'', + self::DB_QUERY_LINK_EMPTY => '\'$message\' Query link is not a validate resource.', + self::DB_QUERY_FIELD_EMPTY => '\'$message\' Query field is empty.', + self::DB_QUERY_FIELD_EXIST => '\'$message\' Query field is not exist.', + self::DB_QUERY_FIELD_FORMAT => 'Inside the field in the query not formatted correctly. \'$message\'', + self::DB_QUERY_INSERT_DATA => 'The new data is empty. \'$message\'', + self::DB_QUERY_UPDATE_DATA => 'The Updated data is empty. \'$message\'', + self::DB_QUERY_CONDTTION_FORMAT => 'The conditions of query are not right. \'$message\'', + self::DB_QUERY_GROUP_MATCH => '\'$message\' Query group does not match.', + self::DB_QUERY_LOGIC_MATCH => '\'$message\' Query logic does not match.', + self::DB_QUERY_FETCH_ERROR => 'The wrong way to obtain the result set. \'$message\'', + self::DB_QUERY_TRAN_BEGIN => 'Transaction has not started. \'$message\'', + self::DB_QUERY_COMPARESS_ERROR => 'Query comparison is incorrect conversion or assembly. \'$message\'', + self::DB_QUERY_COMPARESS_EXIST => 'Comparison does not exist query. \'$message\'', + self::DB_QUERY_WHERE_ERROR => 'Query where is Error. \'$message\'', + self::DB_QUERY_JOIN_TYPE_ERROR => 'The database is wrong type of join query. \'$message\'', + self::DB_TABLE_EMPTY => 'Table is empty. \'$message\'', + self::DB_EMPTY => 'Database is empty. \'$message\'', + self::DB_DRIVER_NOT_EXIST => 'The database driver does not exist. \'$message\'', + self::DB_DRIVER_EXIST => 'The database driver is aleady exist. \'$message\'', + self::DB_BUILDER_NOT_EXIST => 'The database builder does not exist. \'$message\'', + self::DB_BUILDER_EXIST => 'The database builder is aleady exist. \'$message\'', + self::DB_ADAPTER_NOT_EXIST => 'The database adapter does not exist. \'$message\'', + self::DB_ADAPTER_EXIST => 'The database adapter is aleady exist. \'$message\'', + self::DB_DRIVER_BUILDER_NOT_MATCH => '\'$message\' The database driver does not match with the builder. '); + return isset($messages[$code]) ? $messages[$code] : '$message'; + } +} +?> \ No newline at end of file diff --git a/wind/db/mysql/WindMysqlPdoAdapter.php b/wind/db/mysql/WindMysqlPdoAdapter.php new file mode 100644 index 00000000..719ab15f --- /dev/null +++ b/wind/db/mysql/WindMysqlPdoAdapter.php @@ -0,0 +1,82 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindMysqlPdoAdapter extends PDO { + + /** + * 创建表 + * @param $tableName + * @param $values + */ + public function createTable($tableName, $values, $engine, $charset, $autoIncrement) { + $_sql = "CREATE TABLE IF NOT EXISTS $tableName ($values)ENGINE="; + $_sql .= $engine ? $engine : 'MyISAM'; + $_sql .= $charset ? " DEFAULT CHARSET=$charset" : ''; + $_sql .= $autoIncrement ? " AUTO_INCREMENT=$autoIncrement" : ''; + return $this->query($_sql); + } + + /** + * 设置链接使用字符集 + * @param string $charset + */ + public function setCharset($charset) { + if (!$charset) $charset = 'gbk'; + $this->query("set names " . $this->quote($charset) . ";"); + } + + /** + * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组 + * example: + * array('a','b','c') => ('a','b','c') + * array(array('a1','b1','c1'),array('a2','b2','c2')) + * => ('a1','b1','c1'),('a2','b2','c2') + * @param array $variable + * @param string $result + */ + public function filterArray($variable, $result = '') { + if (empty($variable) || !is_array($variable)) return; + $_result = ''; + foreach ($variable as $key => $value) { + if (is_array($value)) + $result = $this->filterArray($value, $result); + else { + $_result .= $this->quote($value) . ','; + } + } + if ($_result) { + $result .= $result ? ',(' . trim($_result, ',') . ')' : '(' . trim($_result, ',') . ')'; + } + return $result; + } + + /** + * 组装单条 key=value 形式的SQL查询语句值 insert/update + * @param $array + * @param $strip + * @return string + */ + public function sqlSingle($array) { + if (!is_array($array)) return ''; + $str = ''; + foreach ($array as $key => $val) { + $str .= ($str ? ', ' : ' ') . $this->fieldMeta($key) . '=' . $this->quote($val); + } + return $str; + } + + /** + * 过滤SQL元数据,数据库对象(如表名字,字段等) + * @param $data 元数据 + * @return string 经过转义的元数据字符串 + */ + private function fieldMeta($data) { + $data = str_replace(array('`', ' '), '', $data); + return ' `' . $data . '` '; + } +} +?> \ No newline at end of file diff --git a/wind/ftp/AbstractWindFtp.php b/wind/ftp/AbstractWindFtp.php new file mode 100644 index 00000000..31ef366c --- /dev/null +++ b/wind/ftp/AbstractWindFtp.php @@ -0,0 +1,185 @@ + + * @author xiaoxiao + * @version 2011-8-1 xiaoxiao + */ +abstract class AbstractWindFtp { + protected $server = ''; + protected $port = 21; + protected $user = ''; + protected $pwd = ''; + protected $dir = ''; + protected $timeout = 10; + protected $rootPath = ''; + + protected $conn = null; + /** + * 初始化配置信息 + * @param array $config + * @return bool + */ + public function initConfig($config) { + if (!$config || !is_array($config)) return false; + isset($config['server']) && $this->server = $config['server']; + isset($config['port']) && $this->port = $config['port']; + isset($config['user']) && $this->user = $config['user']; + isset($config['pwd']) && $this->pwd = $config['pwd']; + isset($config['dir']) && $this->dir = $config['dir']; + isset($config['timeout']) && $this->timeout = $config['timeout']; + return true; + } + + /** + * 重命名文件 + * @param string $oldName + * @param string $newName + * @return boolean + */ + abstract public function rename($oldName, $newName); + /** + * 删除文件 + * @param string $filename + * @return boolean + */ + abstract public function delete($filename); + /** + * 上传文件 + * @param string $sourceFile + * @param string $desFile + * @param string $mode + * @return mixed + */ + abstract public function upload($sourceFile, $desFile, $mode); + /** + * 下载文件 + * @param string $filename + * @param string $localname + * @param string $mode + * @return string + */ + abstract public function download($filename); + /** + * 列出文件列表 + * @param string $dir + * @return array + */ + abstract public function fileList($dir = ''); + /** + * 关闭链接 + * @return boolean + */ + abstract public function close(); + + /** + * 传建文件夹 + * @param string $dir + * @return boolean + */ + abstract public function mkdir($dir); + + /** + * 更改当前目录 + * @param string $dir + * @return boolean + */ + abstract public function changeDir($dir); + + /** + * 获得文件大小 + * @param string $file + * @return boolean + */ + abstract public function size($file); + + /** + * 获得当前路径 + * @return string + */ + abstract protected function pwd(); + + /** + * 级联创建文件夹 + * @param string $dir + * @param string $permissions + * @return boolean + */ + public function mkdirs($dir, $permissions = 0777) { + $dir = explode('/', WindSecurity::escapeDir($dir)); + $dirs = ''; + $result = false; + $count = count($dir); + for ($i = 0; $i < $count; $i++) { + if (strpos($dir[$i], '.') === 0) continue; + $result = $this->mkdir($dir[$i], $permissions); + $this->changeDir($this->rootPath . $dirs . $dir[$i]); + $dirs .= "$dir[$i]/"; + } + $this->changeDir($this->rootPath); + return $result; + } + + + /** + * 检查文件是否存在 + * @param string $filename + * @return boolean + */ + public function file_exists($filename) { + $directory = substr($filename, 0, strrpos($filename, '/')); + $filename = str_replace("$directory/", '', $filename); + if ($directory) { + $directory = $this->rootPath . $directory . '/'; + } else { + $directory = $this->rootPath; + } + $this->changeDir($directory); + $list = $this->fileList(); + $this->changeDir($this->rootPath); + if (!empty($list) && in_array($filename, $list)) return true; + return false; + } + + /** + * 初始化根目录信息 + */ + protected function initRootPath() { + $this->rootPath = $this->pwd(); + if ($this->dir) { + $this->rootPath .= trim(str_replace('\\', '/', $this->dir), '/') . '/'; + } + $this->changeDir($this->rootPath); + } + + /** + * 检查文件 + * @param string $filename + * @return boolean + */ + protected function checkFile($filename) { + return (str_replace(array('..', '.php.'), '', $filename) != $filename || preg_match('/\.php$/i', $filename)); + } + + /** + * 获得文件后缀 + * + * @param string + * @return string + */ + protected function getExt($filename){ + if (false === strpos($filename, '.')) return 'txt'; + $x = explode('.', $filename); + return strtolower(end($x)); + } + + /** + * 显示错误信息 + * @param string $str + */ + protected function showError($str, $close = true) { + $close && $this->close(); + exit($str); + } +} \ No newline at end of file diff --git a/wind/ftp/WindFtp.php b/wind/ftp/WindFtp.php new file mode 100644 index 00000000..76959bc0 --- /dev/null +++ b/wind/ftp/WindFtp.php @@ -0,0 +1,186 @@ + + * author xiaoxiao + * version 2011-7-29 xiaoxiao + */ +class WindFtp extends AbstractWindFtp { + + /** + * 被动模式是否开启 + * var boolean + */ + private $isPasv = true; + + public function __construct($config = array()) { + $this->connection($config); + } + + private function connection($config = array()) { + $this->initConfig($config); + if (false === ($this->conn = ftp_connect($this->server, $this->port, $this->timeout))) { + $this->showError('The ftp ' . $this->server . ' cann\'t connection!'); + } + if (false == ftp_login($this->conn, $this->user, $this->pwd)) { + $this->showError('Login error: ' . $this->user); + } + if ($this->isPasv) { + ftp_pasv($this->conn, true); + } + $this->initRootPath(); + return true; + } + + /** + * 获得链接 + * return object + */ + private function getFtp() { + if (is_resource($this->conn)) return $this->conn; + $this->connection(); + return $this->conn; + } + + /** + * (non-PHPdoc) + * see AbstractWindFtp::rename() + */ + public function rename($oldName, $newName) { + return ftp_rename($this->getFtp(), $oldName, $newName); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::delete() + */ + public function delete($filename) { + return ftp_delete($this->getFtp(), $filename); + } + + /** + * (non-PHPdoc) + * see AbstractWindFtp::upload() + */ + public function upload($sourceFile, $desFile, $mode) { + $mode = $this->getMode($sourceFile, $mode); + if (!in_array(($savedir = dirname($desFile)), array('.', '/'))) { + $this->mkdirs($savedir); + } + $desFile = $this->rootPath . WindSecurity::escapeDir($desFile); + $result = ftp_put($this->getFtp(), $desFile, $sourceFile, $mode); + if (false === $result) return false; + $this->chmod($desFile, 0644); + return $this->size($desFile); + } + + /** + * 从服务器上将文件$filename读取到本地的localname文件中 + * (non-PHPdoc) + * see AbstractWindFtp::download() + */ + public function download($filename, $localname = '', $mode = 'auto') { + $mode = $this->getMode($filename, $mode); + return ftp_get($this->getFtp(), $localname, $filename, $mode); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::fileList() + */ + public function fileList($dir = '') { + return ftp_nlist($this->getFtp(), $dir); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::close() + */ + public function close() { + is_resource($this->conn) && ftp_close($this->conn); + $this->conn = null; + return true; + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::initConfig() + */ + public function initConfig($config) { + if (!$config || !is_array($config)) return false; + parent::initConfig($config); + isset($config['ispasv']) && $this->isPasv = $config['ispasv']; + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::mkdir() + */ + public function mkdir($dir, $permissions = 0777) { + $result = ftp_mkdir($this->getFtp(), $dir); + if (!$result) return false; + return $this->chmod($result, $permissions); + } + + /** + * 赋权限 + * param string $file + * param int $permissions + * return boolean + */ + private function chmod($file, $permissions = 0777) { + return ftp_chmod($this->getFtp(), $permissions, $file); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::pwd() + */ + protected function pwd() { + return ftp_pwd($this->getFtp()) . '/'; + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::changeDir() + */ + public function changeDir($dir) { + return ftp_chdir($this->getFtp(), $dir); + } + + /* + * (non-PHPdoc) + * see AbstractWindFtp::size() + */ + public function size($file) { + return ftp_size($this->getFtp(), $file); + } + + /** + * 获得后缀和模式 + * param string $filename + * param string $mode + * return string + */ + private function getMode($filename, $mode) { + $ext = $this->getExt($filename); + $mode = strtolower($mode); + if ($mode == 'auto') { + $ext = $this->getExt($filename); + $mode = $this->getModeMap($ext); + } + return (strtolower($mode) == 'ascii') ? FTP_ASCII : FTP_BINARY; + } + + /** + * 获得文件操作模式 + * param string + * return string + */ + private function getModeMap($ext){ + $exts = array('txt', 'text', 'php', 'phps', 'php4', 'js', 'css', + 'htm', 'html', 'phtml', 'shtml', 'log', 'xml'); + return (in_array($ext, $exts)) ? 'ascii' : 'binary'; + } +} \ No newline at end of file diff --git a/wind/ftp/WindSocketFtp.php b/wind/ftp/WindSocketFtp.php new file mode 100644 index 00000000..1719a0a9 --- /dev/null +++ b/wind/ftp/WindSocketFtp.php @@ -0,0 +1,274 @@ + + * author xiaoxiao + * version 2011-7-29 xiaoxiao + */ +@set_time_limit(1000); +class WindSocketFtp extends AbstractWindFtp { + private $tmpConnection; + + public function __construct($config = array()) { + $this->getConnection($config); + } + + /** + * 获得ftp链接 + * @param array $config + */ + private function getConnection($config) { + $this->initConfig($config); + $errno = 0; + $errstr = ''; + $this->conn = fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout); + if (!$this->conn || !$this->checkcmd()) { + $this->showError('ftp_connect_failed'); + } + stream_set_timeout($this->conn, $this->timeout); + + if (!$this->sendcmd('USER', $this->user)) { + $this->showError('ftp_user_failed'); + } + if (!$this->sendcmd('PASS', $this->pwd)) { + $this->showError('ftp_pass_failed'); + } + + $this->initRootPath(); + return true; + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::pwd() + */ + protected function pwd() { + $this->sendcmd('PWD', '', false); + if (!($path = $this->checkcmd(true)) || !preg_match("/^[0-9]{3} \"(.+?)\"/", $path, $matchs)) { + return '/'; + } + return $matchs[1] . ((substr($matchs[1], -1) == '/') ? '' : '/'); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::upload() + */ + public function upload($localfile, $remotefile, $mode) { + if ($this->checkFile($localfile)) { + $this->showError("Error:illegal file type!({$localfile})"); + } + if ($this->checkFile($remotefile)) { + $this->showError("Error:illegal file type!({$remotefile})"); + } + if (!in_array(($savedir = dirname($remotefile)), array('.', '/'))) { + $this->mkdirs($savedir); + } + $remotefile = $this->rootPath . WindSecurity::escapeDir($remotefile); + if (!($fp = fopen($localfile, 'rb'))) { + $this->showError("Error:Cannot read file \"$localfile\""); + } + // 'I' == BINARY mode + // 'A' == ASCII mode + $mode != 'I' && $mode = 'A'; + $this->delete($remotefile); + if (!$this->sendcmd('TYPE', $mode)) { + $this->showError('Error:TYPE command failed'); + } + $this->openTmpConnection(); + $this->sendcmd('STOR', $remotefile); + while (!feof($fp)) { + fwrite($this->tmpConnection, fread($fp, 4096)); + } + fclose($fp); + $this->closeTmpConnection(); + + if (!$this->checkcmd()) { + $this->showError('Error:PUT command failed'); + } else { + $this->sendcmd('SITE CHMOD', base_convert(0644, 10, 8) . " $remotefile"); + } + return $this->size($remotefile); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::download() + */ + public function download($localfile, $remotefile = '', $mode = 'I') { + if ($this->checkFile($localfile)) { + $this->showError("Error:illegal file type!({$localfile})"); + } + if ($this->checkFile($remotefile)) { + $this->showError("Error:illegal file type!({$remotefile})"); + } + $mode != 'I' && $mode = 'A'; + if (!$this->sendcmd('TYPE', $mode)) { + $this->showError('Error:TYPE command failed'); + } + $this->openTmpConnection(); + if (!$this->sendcmd('RETR', $remotefile)) { + $this->closeTmpConnection(); + return false; + } + if (!($fp = fopen($localfile, 'wb'))) { + $this->showError("Error:Cannot read file \"$localfile\""); + } + while (!feof($this->tmpConnection)) { + fwrite($fp, fread($this->tmpConnection, 4096)); + } + fclose($fp); + $this->closeTmpConnection(); + + if (!$this->checkcmd()) $this->showError('Error:GET command failed'); + return true; + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::size() + */ + public function size($file) { + $this->sendcmd('SIZE', $file, false); + if (!($size_port = $this->checkcmd(true))) { + $this->showError('Error:Check SIZE command failed'); + } + return preg_replace("/^[0-9]{3} ([0-9]+)\r\n/", "\\1", $size_port); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::delete() + */ + public function delete($file) { + return $this->sendcmd('DELE', $this->rootPath . WindSecurity::escapeDir($file)); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::rename() + */ + public function rename($oldname, $newname) { + if (!in_array(($savedir = dirname($newname)), array('.', '/'))) { + $this->mkdirs($savedir); + } + $oldname = $this->rootPath . WindSecurity::escapeDir($oldname); + $this->sendcmd('RNFR', $oldname); + return $this->sendcmd('RNTO', $newname); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::mkdir() + */ + public function mkdir($dir) { + $base777 = base_convert(0777, 10, 8); + $result = $this->sendcmd('MKD', $dir); + return $this->sendcmd('SITE CHMOD', "$base777 $dir"); + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::changeDir() + */ + public function changeDir($dir) { + $dir = (($dir[0] != '/') ? '/' : '') . $dir; + if ($dir !== '/' && substr($dir, -1) == '/') { + $dir = substr($dir, 0, -1); + } + if (!$this->sendcmd('CWD', $dir)) { + $this->showError('ftp_cwd_failed'); + } + return true; + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::fileList() + */ + public function fileList($dir = '') { + $this->openTmpConnection(); + $this->sendcmd('NLST', $dir); + $list = array(); + while (!feof($this->tmpConnection)) { + $list[] = preg_replace('/[\r\n]/', '', fgets($this->tmpConnection, 512)); + } + $this->closeTmpConnection(); + if (!$this->checkcmd(true)) $this->showError('Error:LIST command failed'); + return $list; + } + + /* + * (non-PHPdoc) + * @see AbstractWindFtp::close() + */ + public function close() { + if (!$this->conn) return false; + if (!$this->sendcmd('QUIT') || !fclose($this->conn)) $this->showError('Error:QUIT command failed', false); + return true; + } + + /** + * 发送命令 + * @param string $cmd + * @param string $args + * @param boolean $check + * @return boolean + */ + private function sendcmd($cmd, $args = '', $check = true) { + !empty($args) && $cmd .= " $args"; + fputs($this->conn, "$cmd\r\n"); + if ($check === true && !$this->checkcmd()) return false; + return true; + } + + /** + * 检查命令状态 + * @param boolean $return + * @return boolean + */ + private function checkcmd($return = false) { + $resp = $rcmd = ''; + $i = 0; + do { + $rcmd = fgets($this->conn, 512); + $resp .= $rcmd; + } while (++$i < 20 && !preg_match('/^\d{3}\s/is', $rcmd)); + + if (!preg_match('/^[123]/', $rcmd)) return false; + return $return ? $resp : true; + } + + /** + * 链接临时句柄 + * @return boolean + */ + private function openTmpConnection() { + $this->sendcmd('PASV', '', false); + if (!($ip_port = $this->checkcmd(true))) { + $this->showError('Error:Check PASV command failed'); + } + if (!preg_match('/[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+/', $ip_port, $temp)) { + $this->showError("Error:Illegal ip-port format($ip_port)"); + } + $temp = explode(',', $temp[0]); + $server_ip = "$temp[0].$temp[1].$temp[2].$temp[3]"; + $server_port = $temp[4] * 256 + $temp[5]; + if (!$this->tmpConnection = fsockopen($server_ip, $server_port, $errno, $errstr, $this->timeout)) { + $this->showError("Error:Cannot open data connection to $server_ip:$server_port
Error:$errstr ($errno)"); + } + stream_set_timeout($this->tmpConnection, $this->timeout); + return true; + } + + /** + * 关闭临时链接对象 + * @return boolean + */ + private function closeTmpConnection() { + return fclose($this->tmpConnection); + } +} +?> \ No newline at end of file diff --git a/wind/http/cookie/WindCookie.php b/wind/http/cookie/WindCookie.php new file mode 100644 index 00000000..7a32ef33 --- /dev/null +++ b/wind/http/cookie/WindCookie.php @@ -0,0 +1,94 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * cookie设置操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindCookie{ + + /** + * 设置cookie + * @param string $name cookie名称 + * @param string $value cookie值 + * @param string|int $expires 过期时间 + * @param string $path cookie路径 + * @param strint $domain cookie cookie域 + * @param boolean $encode 使用 MIME base64 对数据进行编码 + * @param boolean $serialize 是否序列化 + * @param string $prefix cookie前缀 + * @param boolean $secure 是否安全连接 + * @param boolean $httponly 是否可以访问脚本设置的cookie + * @return string|string + */ + public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ + if(empty($name)){ + return false; + } + $name = $prefix ? $prefix.$name : $name; + $value = $serialize ? serialize($value) : $value; + $value = $encode ? base64_encode($value) : $value; + $path = $path ? $path : '/'; + $expires = is_int($expires) ? time()+$expires : strtotime($expires); + setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); + return true; + } + + + /** + * 删除cookie + * @param string $name cookie名称 + * @param string $prefix cookie前缀 + * @return boolean + */ + public static function remove($name,$prefix=null){ + $name = $prefix ? $prefix.$name : $name; + if(self::exist($name)){ + self::set($name,'',time()-3600); + unset($_COOKIE[$name]); + } + return true; + } + + /** + * 取得指定名称的cookie + * @param string $name cookie名称 + * @param boolean $encode 是否对cookie值进行过转码 + * @param boolean $encode 是否对cookie值进行过序列化 + * @param string $prefix cookie前缀 + * @return string|boolean + */ + public static function get($name,$encode = false,$serialize = false,$prefix=null){ + $name = $prefix ? $prefix.$name : $name; + if(self::exist($name)){ + $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; + $value = $encode ? base64_decode($value):$value; + return $serialize ? unserialize($value) : $value; + } + return false; + } + + /** + *移除全部cookie + */ + public static function removeAll(){ + $_COOKIE = array(); + } + + /** + * 判断cookie是否存在 + * @param string $name cookie名称 + * @param string $prefix cookie前缀 + */ + public static function exist($name,$prefix=null){ + return isset($_COOKIE[$prefix ? $prefix.$name : $name]); + } +} \ No newline at end of file diff --git a/wind/http/cookie/WindCookieObject.php b/wind/http/cookie/WindCookieObject.php new file mode 100644 index 00000000..3b774ff1 --- /dev/null +++ b/wind/http/cookie/WindCookieObject.php @@ -0,0 +1,185 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 将cookie作为对象操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindCookieObject{ + + /** + * @var string cookie前缀 + */ + public $prefix; + /** + * Cookie 名称 + * + * @var string + */ + protected $name; + + /** + * Cookie 值 + * + * @var string + */ + protected $value; + + /** + * Cookie 过期时间 + * + * @var int + */ + protected $expires; + + /** + * Cookie 域 + * + * @var string + */ + protected $domain; + + /** + * Cookie 路径 + * + * @var string + */ + protected $path; + + /** + * 是否安全套接字 + * + * @var boolean + */ + protected $secure; + /** + * 是否启用编码 + * + * @var boolean + */ + protected $encode; + + /** + * @var string httponly + */ + protected $httponly; + + /** + * @param string $name + * @param string $value + * @param string $domain + * @param int $expires + * @param string $path + * @param bool $secure + * @param bool $httponly + * @param int $prefix + * @param bool $encode + */ + public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ + + $this->name = (string) $name; + $this->value = (string) $value; + $this->domain = (string) $domain; + $this->expires = (null === $expires ? null : (int) $expires); + $this->path = ($path ? $path : '/'); + $this->secure = $secure; + $this->httponly = $httponly; + $this->prefix = (string)$prefix; + $this->encode = $encode; + } + /** + * 获取cookie的名称 + * @return string + */ + public function getName(){ + return $this->prefix ? $this->prefix.$this->name : $this->prefix; + } + /** + *获取cookie值 + * @return string + */ + public function getValue(){ + return $this->value; + } + + /** + * 获取cookie的域 + * @return string + */ + public function getDomain(){ + return $this->domain; + } + /** + * 获取cookie的路径 + * @return string + */ + public function getPath(){ + return $this->path; + } + /** + *获取cookie的过期时间 + * @return int|null + */ + public function getExpirs(){ + return $this->expires; + } + /** + *是否是安全套接字 + * @return boolean + */ + public function isSecure(){ + return $this->secure; + } + /** + * 验证cookie是否过期 + * @param int|null $now 比较时间 + * @return boolean + */ + public function isExpired($now = null){ + return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; + } + + /** + *是否是session cookie + * @return boolean + */ + public function isSessionCookie(){ + return null === $this->expires; + } + + /** + * @return string + */ + public function __toString(){ + return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; + } + + public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ + $cookie = explode(';',$cookiestr); + list($name,$value) = explode('=',array_shift($cookie)); + if(empty($name)){ + return null; + } + $domain=$expires =$path = null; + $httponly = $secure = false; + foreach($cookie as $_cookie){ + list($key,$_value) = explode('=',$_cookie); + switch($key){ + case 'domain':$domain=$_value;break; + case 'path':$path=$_value;break; + case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; + case 'httponly':$httponly=(bool)$_value;break; + case 'secure':$secure=(bool)$_value;break; + } + } + return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); + } +} \ No newline at end of file diff --git a/wind/http/request/IWindRequest.php b/wind/http/request/IWindRequest.php new file mode 100644 index 00000000..aa657cbf --- /dev/null +++ b/wind/http/request/IWindRequest.php @@ -0,0 +1,25 @@ + 2010-11-3 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 处理请求抽象基类 + * 如http请求 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindRequest { + const INPUT_TYPE_GET = 'get'; + const INPUT_TYPE_POST = 'post'; + const INPUT_TYPE_COOKIE = 'cookie'; +} + + + + diff --git a/wind/http/request/WindHttpRequest.php b/wind/http/request/WindHttpRequest.php new file mode 100644 index 00000000..29608259 --- /dev/null +++ b/wind/http/request/WindHttpRequest.php @@ -0,0 +1,669 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHttpRequest implements IWindRequest { + /** + * 访问的端口号 + * @var int + */ + private $_port = null; + /** + * 客户端IP + * @var string + */ + private $_clientIp = null; + /** + * 语言信息 + * @var string + */ + private $_language = null; + /** + * 路径信息 + * @var string + */ + private $_pathInfo = null; + /** + * @var string + */ + private $_scriptUrl = null; + /** + * @var string + */ + private $_requestUri = null; + /** + * 基础路径信息 + * @var string + */ + private $_baseUrl = null; + private $_hostInfo = null; + /** + * 请求参数信息 + * @var array + */ + private $_attribute = array(); + /** + * @var WindHttpResponse + */ + private $_response = null; + + public function __construct() { + $this->normalizeRequest(); + } + + protected function normalizeRequest() { + if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { + if (isset($_GET)) + $_GET = $this->stripSlashes($_GET); + if (isset($_POST)) + $_POST = $this->stripSlashes($_POST); + if (isset($_REQUEST)) + $_REQUEST = $this->stripSlashes($_REQUEST); + if (isset($_COOKIE)) + $_COOKIE = $this->stripSlashes($_COOKIE); + } + } + + public function stripSlashes(&$data) { + return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( + $data); + } + + /** + * 设置属性数据 + * + * @param string|array|object $data + * @param string $key + * @return + */ + public function setAttribute($data, $key = '') { + if ($key) { + $this->_attribute[$key] = $data; + return; + } + if (is_object($data)) + $data = get_object_vars($data); + if (is_array($data)) + $this->_attribute = array_merge($this->_attribute, $data); + } + + /** + * 根据名称获得服务器和执行环境信息 + * + * @param string|null $name + * @return string|object|array| + */ + public function getAttribute($key, $defaultValue = '') { + if (isset($this->_attribute[$key])) + return $this->_attribute[$key]; + else if (isset($_GET[$key])) + return $_GET[$key]; + else if (isset($_POST[$key])) + return $_POST[$key]; + else if (isset($_COOKIE[$key])) + return $_COOKIE[$key]; + else if (isset($_REQUEST[$key])) + return $_REQUEST[$key]; + else if (isset($_ENV[$key])) + return $_ENV[$key]; + else if (isset($_SERVER[$key])) + return $_SERVER[$key]; + else + return $defaultValue; + } + + /** + * 返回$_GET,$_POST的值,未设置则返回default + * @param string $name | attribute name + */ + public function getRequest($key = null, $defaultValue = null) { + if (!$key) + return array_merge($_POST, $_GET); + if (isset($_GET[$key])) + return $_GET[$key]; + if (isset($_POST[$key])) + return $_POST[$key]; + return $defaultValue; + } + + /** + * 从query中取值 + * + * @param string $name + * @param string $default + * @return string|null + */ + public function getQuery($name = null, $defaultValue = null) { + return $this->getGet($name, $defaultValue); + } + + /** + * 获得post值 + * + * @param string $name + * @param string $defaultValue + * @return string|null + */ + public function getPost($name = null, $defaultValue = null) { + if ($name == null) + return $_POST; + return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; + } + + /** + * 获得get值 + * + * @param string $name + * @param string $defaultValue + * @return string|null + */ + public function getGet($name = '', $defaultValue = null) { + if ($name == null) + return $_GET; + return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; + } + + /** + * 返回cookie的值,如果$name=null则返回所有Cookie值 + * + * @param string $key + * @param string $defaultValue + * @return string|null|array + */ + public function getCookie($name = null, $defaultValue = null) { + if ($name == null) + return $_COOKIE; + return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; + } + + /** + * 返回session的值,如果$name=null则返回所有Cookie值 + * + * @param string $key + * @param string $defaultValue + * @return string|null|array + */ + public function getSession($name = null, $defaultValue = null) { + if ($name == null) + return $_SESSION; + return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; + } + + /** + * 返回Server的值,如果$name为空则返回所有Server的值 + * + * @param string $name + * @param string $defaultValue + * @return string|null|array + */ + public function getServer($name = null, $defaultValue = null) { + if ($name == null) + return $_SERVER; + return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; + } + + /** + * 返回env中的值,如果$name为null则返回所有env的值 + * + * @param string|null $name + * @param string $defaultValue + * @return string|null|array + */ + public function getEnv($name = null, $defaultValue = null) { + if ($name == null) + return $_ENV; + return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; + } + + /** + * 获取协议名称 + * + * @return string + */ + public function getScheme() { + return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; + } + + /** + * 返回请求页面时通信协议的名称和版本 + * @return string + */ + public function getProtocol() { + return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); + } + + /** + * 返回访问IP + * + * @return string|0.0.0.0 + */ + public function getClientIp() { + if (!$this->_clientIp) + $this->_getClientIp(); + return $this->_clientIp; + } + + /** + * 获得请求的方法 + */ + public function getRequestMethod() { + return strtoupper($this->getServer('REQUEST_METHOD')); + } + + /** + * 获得请求类型 + * + * @return string + */ + public function getRequestType() { + return IWindRequest::REQUEST_TYPE_WEB; + } + + /** + * 返回该请求是否为ajax请求 + * @return Boolean + */ + public function getIsAjaxRequest() { + return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); + } + + /** + * Returns a boolean indicating whether this request was made using a + * secure channel, such as HTTPS. + * @return Boolean + */ + public function isSecure() { + return !strcasecmp($this->getServer('HTTPS'), 'on'); + } + + /** + * 返回请求是否为GET请求类型 + * @return boolean + */ + public function isGet() { + return !strcasecmp($this->getRequestMethod(), 'GET'); + } + + /** + * 返回请求是否为POST请求类型 + * @return boolean + */ + public function isPost() { + return !strcasecmp($this->getRequestMethod(), 'POST'); + } + + /** + * 返回请求是否为PUT请求类型 + * @return boolean + */ + public function isPut() { + return !strcasecmp($this->getRequestMethod(), 'PUT'); + } + + /** + * 返回请求是否为DELETE请求类型 + * @return boolean + */ + public function isDelete() { + return !strcasecmp($this->getRequestMethod(), 'Delete'); + } + + /** + * 初始化请求的资源标识符 + * 这里的uri是去除协议名、主机名的 + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_requestUri = /example/index.php?a=test + * + * @return string + */ + public function getRequestUri() { + if (!$this->_requestUri) + $this->_initRequestUri(); + return $this->_requestUri; + } + + /** + * 返回当前执行脚本的绝对路径 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_scriptUrl = /example/index.php + * + * @throws WindException + * @return string + */ + public function getScriptUrl() { + if (!$this->_scriptUrl) + $this->_initScriptUrl(); + return $this->_scriptUrl; + } + + /** + * 返回执行脚本 + */ + public function getScript() { + if (($pos = strrpos($this->getScriptUrl(), '/')) === false) + $pos = -1; + return substr($this->getScriptUrl(), $pos + 1); + } + + /** + * 获取Http头信息 + * @param string $header 头部名称 + * @return string|null + */ + public function getHeader($header, $default = null) { + $temp = strtoupper(str_replace('-', '_', $header)); + if (substr($temp, 0, 5) != 'HTTP_') + $temp = 'HTTP_' . $temp; + if (($header = $this->getServer($temp)) != null) + return $header; + if (function_exists('apache_request_headers')) { + $headers = apache_request_headers(); + if ($headers[$header]) + return $headers[$header]; + } + return $default; + } + + /** + * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 + * + * @throws WindException + * @return string + */ + public function getPathInfo() { + if (!$this->_pathInfo) + $this->_initPathInfo(); + return $this->_pathInfo; + } + + /** + * 获取基础URL,这里是去除了脚本文件以及访问参数信息的URL地址信息 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_baseUrl = example + * return absolute url address when absolute is true + * 'example' will be return when absolute is false + * 'http://www.phpwind.net/example' will be return when absolute is true + * 'http://www.phpwind.net:80/example' will be return when absolute is true + * 'http://www.phpwind.net:443/example' will be return when absolute is true + * + * @param boolean $absolute + * @return string + */ + public function getBaseUrl($absolute = false) { + if ($this->_baseUrl === null) + $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); + return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; + } + + /** + * 获得主机信息,包含协议信息,主机名,访问端口信息 + * + * @return string + */ + public function getHostInfo() { + if ($this->_hostInfo === null) + $this->_initHostInfo(); + return $this->_hostInfo; + } + + /** + * 返回当前运行脚本所在的服务器的主机名。 + * 如果脚本运行于虚拟主机中 + * 该名称是由那个虚拟主机所设置的值决定 + * + * @return string|'' + */ + public function getServerName() { + return $this->getServer('SERVER_NAME', ''); + } + + /** + * 返回服务端口号 + * https链接的默认端口号为443 + * http链接的默认端口号为80 + * + * @return int + */ + public function getServerPort() { + if (!$this->_port) { + $_default = $this->isSecure() ? 443 : 80; + $this->setServerPort($this->getServer('SERVER_PORT', $_default)); + } + return $this->_port; + } + + /** + * 设置服务端口号 + * https链接的默认端口号为443 + * http链接的默认端口号为80 + * + * @param int $port + */ + public function setServerPort($port) { + $this->_port = (int) $port; + } + + /** + * 返回浏览当前页面的用户的主机名 + * DNS 反向解析不依赖于用户的 REMOTE_ADDR + * + * @return string|null + */ + public function getRemoteHost() { + return $this->getServer('REMOTE_HOST'); + } + + /** + * 返回浏览器发送Referer请求头,可以让服务器了解和追踪发出本次请求的起源URL地址 + * + * @return string|null + */ + public function getUrlReferer() { + return $this->getServer('HTTP_REFERER'); + } + + /** + * 获得用户机器上连接到 Web 服务器所使用的端口号 + * + * @return number|null + */ + public function getRemotePort() { + return $this->getServer('REMOTE_PORT'); + } + + /** + * 返回User-Agent头字段用于指定浏览器或者其他客户端程序的类型和名字 + * 如果客户机是一种无线手持终端,就返回一个WML文件;如果发现客户端是一种普通浏览器, + * 则返回通常的HTML文件 + * + * @return string + */ + public function getUserAgent() { + return $this->getServer('HTTP_USER_AGENT', ''); + } + + /** + * 返回当前请求头中 Accept: 项的内容, + * Accept头字段用于指出客户端程序能够处理的MIME类型,例如 text/html,image/* + * + * @return string|'' + */ + public function getAcceptTypes() { + return $this->getServer('HTTP_ACCEPT', ''); + } + + /** + * 返回客户端程序可以能够进行解码的数据编码方式,这里的编码方式通常指某种压缩方式 + * + * @return string|'' + */ + public function getAcceptCharset() { + return $this->getServer('HTTP_ACCEPT_ENCODING', ''); + } + + /** + * 返回客户端程序期望服务器返回哪个国家的语言文档 + * Accept-Language: en-us,zh-cn + * + * @return string + */ + public function getAcceptLanguage() { + if (!$this->_language) { + $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); + $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; + } + return $this->_language; + } + + /** + * @return WindHttpResponse + */ + public function getResponse($charset) { + $response = new WindHttpResponse(); + !$charset && $charset = 'utf-8'; + $response->setHeader('Content-type', 'text/html;charset=' . $charset); + $response->setCharset($charset); + return $response; + } + + /** + * 返回访问的IP地址 + * + * Example: + * $this->_clientIp = 127.0.0.1 + * + * @return string + */ + private function _getClientIp() { + if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { + $this->_clientIp = $ip; + } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { + $ip = strtok($_ip, ','); + do { + $ip = ip2long($ip); + if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { + $this->_clientIp = long2ip($ip); + return; + } + } while (($ip = strtok(','))); + } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { + $this->_clientIp = $ip; + } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { + $this->_clientIp = $ip; + } else { + $this->_clientIp = "0.0.0.0"; + } + } + + /** + * 初始化请求的资源标识符 + * 这里的uri是去除协议名、主机名的 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_requestUri = /example/index.php?a=test + * + * @throws WindException + */ + private function _initRequestUri() { + if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { + $this->_requestUri = $requestUri; + } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { + $this->_requestUri = $requestUri; + if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) + $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); + } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { + $this->_requestUri = $requestUri; + if (($query = $this->getServer('QUERY_STRING')) != null) + $this->_requestUri .= '?' . $query; + } else + throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); + } + + /** + * 初始化当前执行脚本的绝对路径 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_scriptUrl = /example/index.php + * + * @throws WindException + * @return + */ + private function _initScriptUrl() { + if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); + $scriptName = basename($scriptName); + if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( + $_scriptName) === $scriptName) { + $this->_scriptUrl = $_scriptName; + } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { + $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; + } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( + 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { + $this->_scriptUrl = str_replace('\\', '/', + str_replace($_documentRoot, '', $_scriptName)); + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } + + /** + * 获得主机信息,包含协议信息,主机名,访问端口信息 + * + * Example: + * http://www.phpwind.net/example/index.php?a=test + * $this->_hostInfo = http://www.phpwind.net/ + * $this->_hostInfo = http://www.phpwind.net:80/ + * $this->_hostInfo = https://www.phpwind.net:443/ + * + * @throws WindException + * @return + */ + private function _initHostInfo() { + $http = $this->isSecure() ? 'https' : 'http'; + if (($httpHost = $this->getServer('HTTP_HOST')) != null) + $this->_hostInfo = $http . '://' . $httpHost; + elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { + $this->_hostInfo = $http . '://' . $httpHost; + if (($port = $this->getServerPort()) != null) + $this->_hostInfo .= ':' . $port; + } else + throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); + } + + /** + * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 + * + * @throws WindException + * @return + */ + private function _initPathInfo() { + $requestUri = urldecode($this->getRequestUri()); + $scriptUrl = $this->getScriptUrl(); + $baseUrl = $this->getBaseUrl(); + if (strpos($requestUri, $scriptUrl) === 0) + $pathInfo = substr($requestUri, strlen($scriptUrl)); + elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) + $pathInfo = substr($requestUri, strlen($baseUrl)); + elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) + $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); + else + throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); + if (($pos = strpos($pathInfo, '?')) !== false) + $pathInfo = substr($pathInfo, $pos + 1); + $this->_pathInfo = trim($pathInfo, '/'); + } +} \ No newline at end of file diff --git a/wind/http/response/IWindResponse.php b/wind/http/response/IWindResponse.php new file mode 100644 index 00000000..0c437993 --- /dev/null +++ b/wind/http/response/IWindResponse.php @@ -0,0 +1,11 @@ + 2010-11-7 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +interface IWindResponse { + +} \ No newline at end of file diff --git a/wind/http/response/WindHttpResponse.php b/wind/http/response/WindHttpResponse.php new file mode 100644 index 00000000..a7016946 --- /dev/null +++ b/wind/http/response/WindHttpResponse.php @@ -0,0 +1,568 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHttpResponse implements IWindResponse { + + private $_body = array(); + + private $_bodyIndex = array(); + + private $_charset = 'utf-8'; + + private $_headers = array(); + + private $_isRedirect = false; + + private $_status = ''; + + private $_data = array('G' => array()); + + /* + * Server status codes; see RFC 2068. + * Status code (100) indicating the client can continue. + */ + const W_CONTINUE = 100; + + /** + * Status code (101) indicating the server is switching protocols + * according to Upgrade header. + */ + const W_SWITCHING_PROTOCOLS = 101; + + /** + * Status code (200) indicating the request succeeded normally. + */ + const W_OK = 200; + + /** + * Status code (201) indicating the request succeeded and created + * a new resource on the server. + */ + const W_CREATED = 201; + + /** + * Status code (202) indicating that a request was accepted for + * processing, but was not completed. + */ + const W_ACCEPTED = 202; + + /** + * Status code (203) indicating that the meta information presented + * by the client did not originate from the server. + */ + const W_NON_AUTHORITATIVE_INFORMATION = 203; + + /** + * Status code (204) indicating that the request succeeded but that + * there was no new information to return. + */ + const W_NO_CONTENT = 204; + + /** + * Status code (205) indicating that the agent SHOULD reset + * the document view which caused the request to be sent. + */ + const W_RESET_CONTENT = 205; + + /** + * Status code (206) indicating that the server has fulfilled + * the partial GET request for the resource. + */ + const W_PARTIAL_CONTENT = 206; + + /** + * Status code (300) indicating that the requested resource + * corresponds to any one of a set of representations, each with + * its own specific location. + */ + const W_MULTIPLE_CHOICES = 300; + + /** + * Status code (301) indicating that the resource has permanently + * moved to a new location, and that future references should use a + * new URI with their requests. + */ + const W_MOVED_PERMANENTLY = 301; + + /** + * Status code (302) indicating that the resource has temporarily + * moved to another location, but that future references should + * still use the original URI to access the resource. + * + * This definition is being retained for backwards compatibility. + * W_FOUND is now the preferred definition. + */ + const W_MOVED_TEMPORARILY = 302; + + /** + * Status code (302) indicating that the resource reside + * temporarily under a different URI. Since the redirection might + * be altered on occasion, the client should continue to use the + * Request-URI for future requests.(HTTP/1.1) To represent the + * status code (302), it is recommended to use this variable. + */ + const W_FOUND = 302; + + /** + * Status code (303) indicating that the response to the request + * can be found under a different URI. + */ + const W_SEE_OTHER = 303; + + /** + * Status code (304) indicating that a conditional GET operation + * found that the resource was available and not modified. + */ + const W_NOT_MODIFIED = 304; + + /** + * Status code (305) indicating that the requested resource + * MUST be accessed through the proxy given by the + * Location field. + */ + const W_USE_PROXY = 305; + + /** + * Status code (307) indicating that the requested resource + * resides temporarily under a different URI. The temporary URI + * SHOULD be given by the Location + * field in the response. + */ + const W_TEMPORARY_REDIRECT = 307; + + /** + * Status code (400) indicating the request sent by the client was + * syntactically incorrect. + */ + const W_BAD_REQUEST = 400; + + /** + * Status code (401) indicating that the request requires HTTP + * authentication. + */ + const W_UNAUTHORIZED = 401; + + /** + * Status code (402) reserved for future use. + */ + const W_PAYMENT_REQUIRED = 402; + + /** + * Status code (403) indicating the server understood the request + * but refused to fulfill it. + */ + const W_FORBIDDEN = 403; + + /** + * Status code (404) indicating that the requested resource is not + * available. + */ + const W_NOT_FOUND = 404; + + /** + * Status code (405) indicating that the method specified in the + * Request-Line is not allowed for the resource + * identified by the Request-URI. + */ + const W_METHOD_NOT_ALLOWED = 405; + + /** + * Status code (406) indicating that the resource identified by the + * request is only capable of generating response entities which have + * content characteristics not acceptable according to the accept + * headers sent in the request. + */ + const W_NOT_ACCEPTABLE = 406; + + /** + * Status code (407) indicating that the client MUST first + * authenticate itself with the proxy. + */ + const W_PROXY_AUTHENTICATION_REQUIRED = 407; + + /** + * Status code (408) indicating that the client did not produce a + * request within the time that the server was prepared to wait. + */ + const W_REQUEST_TIMEOUT = 408; + + /** + * Status code (409) indicating that the request could not be + * completed due to a conflict with the current state of the + * resource. + */ + const W_CONFLICT = 409; + + /** + * Status code (410) indicating that the resource is no longer + * available at the server and no forwarding address is known. + * This condition SHOULD be considered permanent. + */ + const W_GONE = 410; + + /** + * Status code (411) indicating that the request cannot be handled + * without a defined Content-Length. + */ + const W_LENGTH_REQUIRED = 411; + + /** + * Status code (412) indicating that the precondition given in one + * or more of the request-header fields evaluated to false when it + * was tested on the server. + */ + const W_PRECONDITION_FAILED = 412; + + /** + * Status code (413) indicating that the server is refusing to process + * the request because the request entity is larger than the server is + * willing or able to process. + */ + const W_REQUEST_ENTITY_TOO_LARGE = 413; + + /** + * Status code (414) indicating that the server is refusing to service + * the request because the Request-URI is longer + * than the server is willing to interpret. + */ + const W_REQUEST_URI_TOO_LONG = 414; + + /** + * Status code (415) indicating that the server is refusing to service + * the request because the entity of the request is in a format not + * supported by the requested resource for the requested method. + */ + const W_UNSUPPORTED_MEDIA_TYPE = 415; + + /** + * Status code (416) indicating that the server cannot serve the + * requested byte range. + */ + const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + + /** + * Status code (417) indicating that the server could not meet the + * expectation given in the Expect request header. + */ + const W_EXPECTATION_FAILED = 417; + + /** + * Status code (500) indicating an error inside the HTTP server + * which prevented it from fulfilling the request. + */ + const W_INTERNAL_SERVER_ERROR = 500; + + /** + * Status code (501) indicating the HTTP server does not support + * the functionality needed to fulfill the request. + */ + const W_NOT_IMPLEMENTED = 501; + + /** + * Status code (502) indicating that the HTTP server received an + * invalid response from a server it consulted when acting as a + * proxy or gateway. + */ + const W_BAD_GATEWAY = 502; + + /** + * Status code (503) indicating that the HTTP server is + * temporarily overloaded, and unable to handle the request. + */ + const W_SERVICE_UNAVAILABLE = 503; + + /** + * Status code (504) indicating that the server did not receive + * a timely response from the upstream server while acting as + * a gateway or proxy. + */ + const W_GATEWAY_TIMEOUT = 504; + + /** + * Status code (505) indicating that the server does not support + * or refuses to support the HTTP protocol version that was used + * in the request message. + */ + const W_HTTP_VERSION_NOT_SUPPORTED = 505; + + public function codeMap($code) { + $map = array(505 => 'http version not supported', 504 => 'gateway timeout', + 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', + 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', + 416 => 'requested range not satisfiable', 415 => 'unsupported media type', + 414 => 'request uri too long', 413 => 'request entity too large', + 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', + 408 => 'request timeout', 407 => 'proxy authentication required', + 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', + 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', + 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', + 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', + 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', + 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', + 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', + 206 => 'partial content'); + return isset($map[$code]) ? $map[$code] : ''; + } + + /** + * 设置响应头信息,如果已经设置过同名的响应头,该方法将用新的设置取代原来的头字段 + * + * @param string $name 响应头的名称 + * @param string $value 响应头的字段取值 + */ + public function setHeader($name, $value, $replace = false) { + if (!$name || !$value) + return; + $name = $this->_normalizeHeader($name); + $setted = false; + foreach ($this->_headers as $key => $one) { + if ($one['name'] == $name) { + $this->_headers[$key] = array('name' => $name, 'value' => $value, + 'replace' => $replace); + $setted = true; + break; + } + } + if ($setted === false) + $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); + } + + /** + * 设置响应头信息,如果已经设置过同名的响应头,该方法将增加一个同名的响应头 + * + * @param string $name 响应头的名称 + * @param string $value 响应头的字段取值 + */ + public function addHeader($name, $value, $replace = false) { + if ($name == '' || $value == '') + return; + $name = $this->_normalizeHeader($name); + $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); + } + + /** + * @return string + */ + public function getCharset() { + return $this->_charset; + } + + /** + * @param string $_charset + */ + public function setCharset($_charset) { + $this->_charset = $_charset; + } + + /** + * 设置响应头状态码 + * + * @param int $status + * @param string $message + */ + public function setStatus($status, $message = '') { + $status = intval($status); + if ($status < 100 || $status > 505) + return; + + $this->_status = (int) $status; + } + + /** + * 设置响应内容 + * + * @param string $content + * @param string $name + */ + public function setBody($content, $name = null) { + if (!$content) + return; + !$name && $name = 'default'; + array_push($this->_bodyIndex, $name); + $this->_body[$name] = $content; + } + + /** + * 添加cookie信息 + * + * @param Cookie $cookie + */ + public function addCookie(Cookie $cookie) { + + } + + /** + * 发送一个错误的响应信息 + * + * @param int $status + * @param string $message + */ + public function sendError($status = self::W_NOT_FOUND, $message = '') { + if (!is_int($status) || $status < 400 || $status > 505) + return; + $this->setBody($message, 'error'); + $this->setStatus($status); + $this->sendResponse(); + } + + /** + * 重定向一个响应信息 + * + * @param string $location + */ + public function sendRedirect($location, $status = 302) { + if (!is_int($status) || $status < 300 || $status > 399) + return; + + $this->addHeader('Location', $location, true); + $this->setStatus($status); + $this->_isRedirect = true; + $this->sendHeaders(); + exit(); + } + + /** + * 发送响应信息 + */ + public function sendResponse() { + $this->sendHeaders(); + $this->sendBody(); + } + + /** + * 发送响应头部信息 + */ + public function sendHeaders() { + if ($this->isSendedHeader()) + return; + foreach ($this->_headers as $header) { + header($header['name'] . ': ' . $header['value'], $header['replace']); + } + if ($this->_status) { + header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); + header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); + } + } + + /** + * 发送响应内容 + */ + public function sendBody() { + /*if ($this->_isAjax) echo "_bodyIndex as $key) + echo $this->_body[$key]; + /*if ($this->_isAjax) echo "]]>";*/ + } + + /** + * 获取内容 + * + * @param string $spec 内容的名称 + * @return string|null + */ + public function getBody($name = false) { + if ($name === false) { + ob_start(); + $this->sendBody(); + return ob_get_clean(); + } elseif ($name === true) { + return $this->_body; + } elseif (is_string($name) && isset($this->_body[$name])) + return $this->_body[$name]; + + return null; + } + + /** + * 是否已经发送了响应头部 + */ + public function isSendedHeader($throw = false) { + $sended = headers_sent($file, $line); + if ($throw && $sended) + throw new WindException( + __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); + + return $sended; + } + + /** + * 获取响应头信息 + * + * @return array + */ + public function getHeaders() { + return $this->_headers; + } + + /** + * 清理响应体信息 + */ + public function clearBody() { + $this->_body = array(); + } + + /** + * 清除响应头信息 + */ + public function clearHeaders() { + $this->_headers = array(); + } + + /** + * 格式化响应头信息 + * + * @param string $name + * @return string + */ + private function _normalizeHeader($name) { + $filtered = str_replace(array('-', '_'), ' ', (string) $name); + $filtered = ucwords(strtolower($filtered)); + $filtered = str_replace(' ', '-', $filtered); + return $filtered; + } + + /** + * @return array + */ + public function getData($key1 = '', $key2 = '') { + if (!$key1) + return $this->_data; + if (!$key2) + return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; + return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; + } + + /** + * @param $data + */ + public function setData($data, $key = '', $isG = false) { + if ($key) { + if ($isG) + $this->_data['G'][$key] = $data; + else + $this->_data[$key] = $data; + return; + } + if (is_object($data)) + $data = get_object_vars($data); + if (is_array($data)) { + if ($isG) + $this->_data['G'] += $data; + else + $this->_data += $data; + + } + } + +} \ No newline at end of file diff --git a/wind/http/session/AbstractWindUserSession.php b/wind/http/session/AbstractWindUserSession.php new file mode 100644 index 00000000..a3da2a70 --- /dev/null +++ b/wind/http/session/AbstractWindUserSession.php @@ -0,0 +1,57 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 用户定义session存储机制 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +abstract class AbstractWindUserSession { + + /** + * 打开会话存储机制 + * @param string $savePath + * @param string $sessionName + * @return bollean + */ + public static abstract function open($savePath, $sessionName); + /** + * 关闭会话存储存储机制 + * @return bollean + */ + public static abstract function close(); + /** + * 将sessionID对应的数据写到存储 + * @param string $name + * @param mixed $value + */ + public static abstract function write($name,$value); + /** + * 从存储中装载session数据 + * @param mixed $sessid + */ + public static abstract function read($name); + /** + * 对存储系统中的数据进行垃圾收集 + * @param mixed $maxlifetime + */ + public static abstract function gc($maxlifetime); + /** + * 破坏与指定的会话ID相关联的数据 + * @param mixed $name + */ + public static abstract function destroy($name); + + public static function callUserSessionHandler(){ + $className = get_class($this); + session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); + } +} + diff --git a/wind/http/session/WindDbSession.php b/wind/http/session/WindDbSession.php new file mode 100644 index 00000000..7c1591ae --- /dev/null +++ b/wind/http/session/WindDbSession.php @@ -0,0 +1,42 @@ + 2011-3-8 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.http.session.AbstractWindUserSession'); +/** + * 数据库会话存储机制,可以实现统一登陆 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindDbSession extends AbstractWindUserSession { + + public static function open($savePath, $sessionName){ + return true; + } + + public static function close(){ + return true; + } + + public static function write($name,$value){ + + } + + public static function read($name){ + + } + + public static function gc($maxlifetime){ + + } + + public static function destroy($name){ + + } +} + diff --git a/wind/http/session/WindSession.php b/wind/http/session/WindSession.php new file mode 100644 index 00000000..1a22ebbd --- /dev/null +++ b/wind/http/session/WindSession.php @@ -0,0 +1,370 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * Session会话操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSession implements IteratorAggregate, ArrayAccess, Countable { + /** + * @var boolean 是否自动启动session + */ + public $autostart = false; + /** + * @var int 没有启用cookie传用sessionid + */ + const COOKIE_MODE_NONE = 1; + /** + * @var int 仅仅启用cookiew传递sessionid + */ + const COOKIE_MODE_ONLY = 2; + /** + * @var int 启用cookie传用sessionid + */ + const COOKIE_MODE_ALLOW = 3; + + /** + * @var string 以files格式将session在服务端的保存 + */ + const SESSION_SAVE_FILES = 'files'; + /** + * @var string 以user(用户自定义)格式将session在服务端的保存 + */ + const SESSION_SAVE_USER = 'user'; + + /** + * @var array $read 只读session + */ + public static $read = array(); + /** + * @var array $write 只写session + */ + public static $write = array(); + + public function __construct($autostart = false) { + $this->autostart = $autostart; + } + + public function start() { + if (!$this->isStart() && !$this->getAutoStart()) { + $this->autostart ? $this->setAutoStart(1) : session_start(); + } + } + + /** + * session是否开启 + * @return boolean + */ + public function isStart() { + return '' !== $this->getSessionId(); + } + + /** + * 写入和结束session + */ + public function close() { + if ($this->isStart()) { + session_write_close(); + } + } + + /** + * 获取session + * @param string $name session名称 + * @return string + */ + public function get($name) { + return isset($_SESSION[$name]) ? $_SESSION[$name] : null; + } + + /** + * 设置一个会话 + * @param string $name session名称 + * @param string $value $name对应的值 + * @return string + */ + public function set($name, $value) { + if (empty($name) && empty($value)) { + return false; + } + $_SESSION[$name] = $value; + return true; + } + + /** + * 删除一个会话 + * @param string $name session名称 + * @return string + */ + public function remove($name) { + if (isset($_SESSION[$name])) { + $sessionValue = $_SESSION[$name]; + unset($_SESSION[$name]); + return $sessionValue; + } + return null; + } + + /** + * 判断一个session是否存在 + * @param string $name session名称 + * @return string + */ + public function exist($name) { + return isset($_SESSION[$name]); + } + + /** + * 销毁当前所有会话 + * @return string + */ + public function destroy() { + if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { + setcookie($name, '', time() - 3600); + } + session_unset(); + session_destroy(); + return true; + } + + /** + * 获取当前会话名称 + * @return string + */ + public function getSessionName() { + return session_name(); + } + /** + * 设置当前会话名称 + * @return string $name + */ + public function setSessionName($name) { + return session_name($name); + } + + /** + * 获取当前会话 id + * @return string + */ + public function getSessionId() { + return session_id(); + } + + /** + * 设置当前会话 id + * @param string $id + * @return string + */ + public function setSessionId($id) { + return session_id($id); + } + + /** + * 如果session在服务端的以files方式保存,获取session在服务器端存储路径 + * @return string + */ + public function getSavePath() { + return session_save_path(); + } + + /** + * 如果session在服务端的以files方式保存,设置session在服务器端存储路径 + * @param string $path + * @return string + */ + public function setSavePath($path) { + if (is_dir($path)) { + session_save_path($path); + return true; + } + return false; + } + + /** + * 获取session在服务端的保存方式 + * @return string + */ + public function getSessionSaveMode() { + return session_module_name(); + } + + /** + * 定义session在服务端的保存方式,files意为把sesion保存到一个临时文件里,如果我们想自定义别的方式保存(比如用数据库),则需要把该项设置为user; + * @param unknown_type $mode + * @return string + */ + public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { + return session_module_name($mode); + } + + /** + * 取得session相关的cookie参数 + * @return array + */ + public function getCookieParams() { + return session_get_cookie_params(); + } + + /** + * 设置session相关的cookie参数 + * @param array $cookie + * @return string + */ + public function setCookieParams($cookie = array()) { + extract($this->getCookieParams()); + extract($cookie); + if (isset($httponly)) { + session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); + } else { + session_set_cookie_params($lifetime, $path, $domain, $secure); + } + return true; + } + + /** + * 取得cookie传递sessionid的模式 + * @return number + */ + public function getCookieMode() { + if ('0' === ini_get('session.use_cookies')) { + self::COOKIE_MODE_NONE; + } else if ('0' === ini_get('session.use_only_cookies')) { + return self::COOKIE_MODE_ALLOW; + } else { + return self::COOKIE_MODE_ONLY; + } + return false; + } + + /** + * 设置cookie传递sessionid的模式 + * @param int $mode + * @return string + */ + public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { + if (self::COOKIE_MODE_NONE === $mode) { + ini_set('session.use_cookies', '0'); + } else if (self::COOKIE_MODE_ALLOW === $mode) { + ini_set('session.use_cookies', '1'); + ini_set('session.use_only_cookies', '0'); + } else if (self::COOKIE_MODE_ONLY === $mode) { + ini_set('session.use_cookies', '1'); + ini_set('session.use_only_cookies', '1'); + } else { + return false; + } + return true; + } + + /** + * 获取session进行清理的概率 + * @return number + */ + public function getGCProbability() { + return (int) ini_get('session.gc_probability'); + } + + /** + * 设置session进行清理的概率 + * @param int $probability 概率数 + * @return string|string + */ + public function setGCProbability($probability) { + if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { + return false; + } + ini_set('session.gc_probability', $probability); + ini_set('session.gc_divisor', '100'); + return true; + } + + /** + * 是否允许sessionid通过url参数传递 + * @return boolean + */ + public function getTransSessionID() { + return '1' === ini_get('session.use_trans_sid'); + } + + /** + * 设置是否允许sessionid通过url参数传递 + * @param int $ifTrans + * @return string + */ + public function setTransSessionID($ifTrans = 0) { + return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); + } + + /** + * 获取session存活时间 + * @return number + */ + public function getSessionLifeTime() { + return (int) ini_get('session.gc_maxlifetime'); + } + + /** + * 设置session存活时间 + * @param int $time + * @return number + */ + public function setSessionLifeTime($time = 0) { + return (int) ini_set('session.gc_maxlifetime', (int) $time); + } + + /** + * 是否自动启动session + * @return boolean + */ + public function getAutoStart() { + return '1' === ini_get('session.auto_start'); + } + + /** + * 设置自动启动 + * @param boolean $autostart 是否自动启动 + * @return string + */ + public function setAutoStart($autostart) { + return ini_set('session.auto_start', $autostart ? '1' : '0'); + } + + /** + * 获取当前session的文件名 + * @return string + */ + public function getCurrentSessionFileName(){ + return $this->getSavePath().'/sess_'.$this->getSessionId(); + } + + public function offsetExists($offset) { + $this->exist($offset); + } + + public function offsetSet($offset, $value) { + $this->set($offset, $value); + } + + public function offsetGet($offset) { + $this->get($offset); + } + public function offsetUnset($offset) { + $this->remove($offset); + } + + public function getIterator($name = null) { + return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); + } + + public function count() { + return count($_SESSION); + } +} \ No newline at end of file diff --git a/wind/http/transfer/AbstractWindHttp.php b/wind/http/transfer/AbstractWindHttp.php new file mode 100644 index 00000000..67996671 --- /dev/null +++ b/wind/http/transfer/AbstractWindHttp.php @@ -0,0 +1,280 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +abstract class AbstractWindHttp { + + /** + * @var WindHttp 单例 对象 + */ + protected static $instance = null; + + /** + * @var resource http连接句柄 + */ + protected $httpResource = null; + + /** + * @var string 发送的cookie + */ + protected $cookie = array(); + /** + * @var array 发送的http头 + */ + protected $header = array(); + /** + * @var array 访问的URL地址 + */ + protected $url = ''; + /** + * @var array 发送的数据 + */ + protected $data = array(); + + /** + * @var string 错误信息 + */ + protected $err = ''; + /** + * @var string 错误编码 + */ + protected $eno = 0; + + /** + * @var string 超时时间 + */ + protected $timeout = 0; + + /** + * @var strint 指向$cookie属性 + */ + const _COOKIE = 'cookie'; + /** + * @var string 指向$header属性 + */ + const _HEADER = 'header'; + /** + * @var string 指定$data属性 + */ + const _DATA = 'data'; + + const GET = 'GET'; + const POST = 'POST'; + /** + * 声明受保护的构造函数,避免在类的外界实例化 + * @param string $url + */ + protected function __construct($url = '', $timeout = 5) { + $this->url = $url; + $this->timeout = $timeout; + } + + /** + * 发送post请求 + * @param string $url 请求的url + * @param array $data 请求的数据 + * @param array $header 发送请求的头 + * @param array $cookie 发送的cookie + * @param array $options 额外的请求头 + * @return string 返回页根据请求的响应页面 + */ + public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); + /** + * get方式传值 + * @param string $url 请求的url + * @param array $data 请求的数据 + * @param array $header 发送请求的头 + * @param array $cookie 发送的cookie + * @param array $options 额外的请求头 + * @return string 返回页根据请求的响应页面 + */ + public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); + /** + * 发送请求底层操作 + * @param string $method 请求方式 + * @param array $options 额外的主求参数 + * @return string 返回页根据请求的响应页面 + */ + public abstract function send($method = self::GET, $options = array()); + + /** + * 打开一个http请求 + * @return httpResource http请求指针 + */ + public abstract function open(); + /** + * 发送请求 + * @param string $key 请求的名称 + * @param string $value 请求的值 + * @return boolean + */ + public abstract function request($key, $value = null); + /** + * 以数组格式请求 + * @param array $request + * @return boolean + */ + public abstract function requestByArray($request = array()); + /** + * 响应用户的请求 + * @return string 返回响应 + */ + public abstract function response(); + /** + *响应用户请求,只返回一行数据 + *@return string + */ + public abstract function resonseLine(); + /** + * + * 关闭请求 + */ + public abstract function close(); + /** + * 取得http通信中的错误 + */ + public abstract function getError(); + + /** + * 获取http单例对象,对象唯一访问入口 + * @param string $url 请求的url + * @return WindHttp + */ + public static abstract function getInstance($url = ''); + + /** + * 防止克隆 + */ + protected function __clone() {} + + /** + * 设置url + * @param string|array $url + */ + public function setUrl($url) { + $url && $this->url = $url; + } + /** + * 设置http头 + * @param string $key + * @param string $value + */ + public function setHeader($key, $value) { + $this->header[$key] = $value; + } + /** + * 批量设置http头 + * @param array $datas 实际的http头,数组的值基于key/value形式 + * @return boolean + */ + public function setHeaders($headers = array()) { + return $this->setPropertityValue(self::_HEADER, $headers); + } + /** + * 设置cookie + * @param string $key + * @param string $value + */ + public function setCookie($key, $value) { + $this->cookie[$key] = $value; + } + /** + * 批量设置要传送的cookie + * @param array $cookies 要传送的cookie,数组的值基于key/value形式 + * @return boolean + */ + public function setCookies($cookies = array()) { + return $this->setPropertityValue(self::_COOKIE, $cookies); + } + /** + * 设置data + * @param string $key + * @param string $value + */ + public function setData($key, $value) { + $this->data[$key] = $value; + } + /** + * 批量设置要传送的数据 + * @param array $datas 要传送的数据,数组的值基于key/value形式 + * @return boolean + */ + public function setDatas($datas = array()) { + return $this->setPropertityValue(self::_DATA, $datas); + } + /** + *请空数据,重新发送请求 + */ + public function clear() { + $this->url = array(); + $this->header = array(); + $this->cookie = array(); + $this->data = array(); + } + + /** + * 构请查询字符串 + * @param array $query 查询的关联数组 + * @param string $sep 分隔符 + * @return string + */ + public static function buildQuery($query, $sep = '&') { + if (!is_array($query)) { + return ''; + } + $_query = ''; + foreach ($query as $key => $value) { + $tmp = rawurlencode($key) . '=' . rawurlencode($value); + $_query .= $_query ? $sep . $tmp : $tmp; + } + return $_query; + } + /** + * 以指定分隔符的形式来将数组转化成字符串 + * @param array $array 关联数组 + * @param strin $sep 分隔符 + * @return string + */ + public static function buildArray($array, $sep = ':') { + if (!is_array($array)) { + return array(); + } + $_array = array(); + foreach ($array as $key => $value) { + $_array[] = $key . $sep . $value; + } + return $_array; + } + + /** + * 增量式设置对象的属性的值 + * @param string $propertity 要设置的对象的属性 + * @param array $value 要设置属性的值 + * @return boolean + */ + private function setPropertityValue($propertity, $value = array()) { + if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { + return false; + } + if (!is_array($value)) { + return false; + } + if (empty($this->$propertity)) { + $this->$propertity = $value; + } else { + foreach ($value as $key => $_value) { + $this->$propertity[$key] = $_value; + } + } + return true; + } +} \ No newline at end of file diff --git a/wind/http/transfer/WindHttpCurl.php b/wind/http/transfer/WindHttpCurl.php new file mode 100644 index 00000000..fe0b5ffd --- /dev/null +++ b/wind/http/transfer/WindHttpCurl.php @@ -0,0 +1,147 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +final class WindHttpCurl extends AbstractWindHttp { + + protected function __construct($url = '', $timeout = 5) { + parent::__construct($url, $timeout); + } + + /* + * @see wind/component/http/base/WindHttp#open() + */ + public function open() { + if (null === $this->httpResource) { + $this->httpResource = curl_init(); + } + return $this->httpResource; + } + + /* + * @see wind/component/http/base/WindHttp#request() + */ + public function request($name, $value = null) { + return curl_setopt($this->httpResource, $name, $value); + } + + /* + * @see wind/component/http/base/WindHttp#requestByArray() + */ + public function requestByArray($opt = array()) { + return curl_setopt_array($this->httpResource, $opt); + } + + /* + * @see wind/component/http/base/WindHttp#response() + */ + public function response() { + return curl_exec($this->httpResource); + } + + /** + * @see wind/component/http/base/WindHttp#resonseLine() + */ + public function resonseLine(){ + return ''; + } + + /** + * 释放资源 + */ + public function close() { + if ($this->httpResource) { + curl_close($this->httpResource); + $this->httpResource = null; + } + } + + /* + * @see wind/component/http/base/WindHttp#getError() + */ + public function getError() { + $this->err = curl_error($this->httpResource); + $this->eno = curl_errno($this->httpResource); + return $this->err ? $this->eno . ':' . $this->err : ''; + } + + /* + * @see wind/component/http/base/WindHttp#post() + */ + public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::POST, $option); + } + /* + * @see wind/component/http/base/WindHttp#get() + */ + public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::GET, $option); + } + /* + * @see wind/component/http/base/WindHttp#send() + */ + public function send($method = self::GET, $options = array()) { + if (null === $this->httpResource) { + $this->open(); + } + $this->request(CURLOPT_HEADER, 0); + $this->request(CURLOPT_FOLLOWLOCATION, 1); + $this->request(CURLOPT_RETURNTRANSFER, 1); + $this->request(CURLOPT_TIMEOUT, $this->timeout); + if ($options && is_array($options)) { + $this->requestByArray($options); + } + if (self::GET === $method && $this->data) { + $get = self::buildQuery($this->data, '&'); + $url = parse_url($this->url); + $sep = isset($url['query']) ? '&' : '?'; + $this->url .= $sep . $get; + } + if (self::POST === $method && $this->data) { + $this->request(CURLOPT_POST, 1); + $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); + } + if ($this->cookie && $this->cookie) { + $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); + } + if (empty($this->header)) { + $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); + } + $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); + $this->request(CURLOPT_URL, $this->url); + return $this->response(); + } + + /* + * @see wind/component/http/base/WindHttp#requestByArray() + */ + public static function getInstance($url = '') { + if (null === self::$instance || false === (self::$instance instanceof self)) { + self::$instance = new self($url); + } + return self::$instance; + } + + public function __destruct() { + $this->close(); + } +} + diff --git a/wind/http/transfer/WindHttpSocket.php b/wind/http/transfer/WindHttpSocket.php new file mode 100644 index 00000000..06c6d5f8 --- /dev/null +++ b/wind/http/transfer/WindHttpSocket.php @@ -0,0 +1,166 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +/** + * socket操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +final class WindHttpSocket extends AbstractWindHttp { + + private $host = ''; + private $port = 0; + private $path = ''; + private $query = ''; + + protected function __construct($url = '', $timeout = 5) { + parent::__construct($url, $timeout); + } + + /* + * @see wind/component/http/base/WindHttp#open() + */ + public function open() { + if (null === $this->httpResource) { + $url = parse_url($this->url); + $this->host = $url['host']; + $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; + $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; + $this->path .= $url['query'] ? '?' . $url['query'] : ''; + $this->query = $url['query']; + $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); + } + return $this->httpResource; + } + + /* + * @see wind/component/http/base/WindHttp#request() + */ + public function request($name, $value = null) { + return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); + } + + /* + * @see wind/component/http/base/WindHttp#requestByArray() + */ + public function requestByArray($request = array()) { + $_request = ''; + foreach ($request as $key => $value) { + if (is_string($key)) { + $_request .= $key . ': ' . $value; + } + if (is_int($key)) { + $_request .= $value; + } + $_request .= "\n"; + } + fputs($this->httpResource, $_request); + } + /* + * @see wind/component/http/base/WindHttp#resonseLine() + */ + public function response() { + $response = ''; + while (!feof($this->httpResource)) { + $response .= fgets($this->httpResource); + } + return $response; + } + + /** + * @see wind/component/http/base/WindHttp#response() + */ + public function resonseLine(){ + return feof($this->httpResource) ? '' : fgets($this->httpResource); + } + + /* + * @see wind/component/http/base/WindHttp#close() + */ + public function close() { + if ($this->httpResource) { + fclose($this->httpResource); + $this->httpResource = null; + } + } + + /* + * @see wind/component/http/base/WindHttp#getError() + */ + public function getError() { + return $this->err ? $this->eno . ':' . $this->err : ''; + } + /* + * @see wind/component/http/base/WindHttp#post() + */ + public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::POST, $option); + } + /* + * @see wind/component/http/base/WindHttp#get() + */ + public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::GET, $option); + } + /* + * @see wind/component/http/base/WindHttp#send() + */ + public function send($method = self::GET, $options = array()) { + if (self::GET === $method && $this->data) { + $url = parse_url($this->url); + $get = self::buildQuery($this->data, '&'); + $this->url .= ($url['query'] ? '&' : '?') . $get; + } + $this->open(); + $this->setHeader("Host", $this->host); + $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); + if ($this->cookie && $this->cookie) { + $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); + } + if (self::POST === $method && $this->data) { + $data = self::buildQuery($this->data, '&'); + $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); + $this->setHeader('Content-Length', strlen($data)); + } + if ($options) { + $this->setHeaders($options); + } + $this->setHeader('Connection', 'Close'); + $this->request($method . " " . $this->path . " HTTP/1.1"); + $this->requestByArray($this->header); + if ($data) { + $this->request("\n" . $data); + } + $this->request("\n"); + return $this->response(); + } + + /* + * @see wind/component/http/base/WindHttp#getInstance() + */ + public static function getInstance($url = '') { + if (null === self::$instance || false === (self::$instance instanceof self)) { + self::$instance = new self($url); + } + return self::$instance; + } + + public function __destruct() { + $this->close(); + } +} \ No newline at end of file diff --git a/wind/http/transfer/WindHttpStream.php b/wind/http/transfer/WindHttpStream.php new file mode 100644 index 00000000..abee1faa --- /dev/null +++ b/wind/http/transfer/WindHttpStream.php @@ -0,0 +1,178 @@ + 2010-12-23 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +final class WindHttpStream extends AbstractWindHttp { + const HTTP = 'http'; + const HTTPS = 'https'; + const FTP = 'ftp'; + const FTPS = 'ftp'; + const SOCKET = 'socket'; + + /** + * @var string 字节流对象 + */ + private $context = null; + /** + * @var string 通信协议 + */ + private $wrapper = self::HTTP; + protected function __construct($url = '', $timeout = 5) { + parent::__construct($url, $timeout); + $this->context = stream_context_create(); + } + + /** + * 设置通信协议 + * @param string $wrapper + */ + public function setWrapper($wrapper = self::HTTP) { + $this->wrapper = $wrapper; + } + + /* + * @see wind/component/http/base/WindHttp#open() + */ + public function open() { + if (null === $this->httpResource) { + $this->httpResource = fopen($this->url, 'r', false, $this->context); + } + return $this->httpResource; + } + + /* + * @see wind/component/http/base/WindHttp#request() + */ + public function request($name, $value = null) { + return stream_context_set_option($this->context, $this->wrapper, $name, $value); + } + + /* + * @see wind/component/http/base/WindHttp#requestByArray() + */ + public function requestByArray($opt = array()) { + foreach ($opt as $key => $value) { + if (false === $this->request($key, $value)) { + return false; + } + } + return true; + } + + /* + * @see wind/component/http/base/WindHttp#response() + */ + public function response() { + $response = ''; + while (!feof($this->httpResource)) { + $response .= fgets($this->httpResource); + } + return $response; + } + + /** + * @see wind/component/http/base/WindHttp#resonseLine() + */ + public function resonseLine(){ + return feof($this->httpResource) ? '' : fgets($this->httpResource); + } + + /** + * 释放资源 + */ + public function close() { + if ($this->httpResource) { + fclose($this->httpResource); + $this->httpResource = null; + $this->context = null; + } + } + + /* + * @see wind/component/http/base/WindHttp#getError() + */ + public function getError() { + return $this->err ? $this->eno . ':' . $this->err : ''; + } + + /* + * @see wind/component/http/base/WindHttp#post() + */ + public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::POST, $option); + } + /* + * @see wind/component/http/base/WindHttp#get() + */ + public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { + $url && $this->setUrl($url); + $header && is_array($header) && $this->setHeaders($header); + $cookie && is_array($cookie) && $this->setCookies($cookie); + $data && is_array($data) && $this->setDatas($data); + return $this->send(self::GET, $option); + } + /* + * @see wind/component/http/base/WindHttp#send() + */ + public function send($method = self::GET, $options = array()) { + $url = parse_url($this->url); + if (self::GET === $method && $this->data) { + $get = self::buildQuery($this->data, '&'); + $this->url .= ($url['query'] ? '&' : '?') . $get; + } + if (self::POST === $method && $this->data) { + $data = self::buildQuery($this->data, '&'); + $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); + $this->setHeader('Content-Length', strlen($data)); + } + $this->setHeader("Host", $url['host']); + $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); + if ($this->cookie) { + $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); + } + $this->setHeader('Connection', 'Close'); + $this->request('method', $method); + $this->request('timeout', $this->timeout); + + if ($this->header) { + $header = ''; + foreach ($this->header as $key => $value) { + $header .= $key . ': ' . $value . "\n"; + } + $this->request('header', $header); + } + $data && $this->request('content', $data); + $options && is_array($options) && $this->requestByArray($options); + $this->open(); + return $this->response(); + } + + /** + * @see wind/component/http/base/WindHttp#getInstance() + * + */ + public static function getInstance($url = '') { + if (null === self::$instance || false === (self::$instance instanceof self)) { + self::$instance = new self($url); + } + return self::$instance; + } + + public function __destruct() { + $this->close(); + } +} \ No newline at end of file diff --git a/wind/log/WindDebug.php b/wind/log/WindDebug.php new file mode 100644 index 00000000..6eb0963d --- /dev/null +++ b/wind/log/WindDebug.php @@ -0,0 +1,175 @@ + 2010-11-3 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +defined('RUNTIME_START') or define('RUNTIME_START', microtime(true)); +defined('USEMEM_START') or define('USEMEM_START', memory_get_usage()); +/** + * 调试工具 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindDebug { + + /** + * @var array 调试点 + */ + private static $breakpoint = array(); + /** + * @var int 保留的小数位数 + */ + const DECIMAL_DIGITS = 4; + + /** + * @var int 记录内存使用标记 + */ + const MEMORY = 'mem'; + /** + * @var int 记录程序运行时时间使用标记 + */ + const RUN_TIME = 'time'; + /** + * 设置调试点 + * @param string $point 调试点 + */ + public static function setBreakPoint($point = '') { + if (isset(self::$breakpoint[$point])) + return false; + self::$breakpoint[$point][self::RUN_TIME] = microtime(true); + self::$breakpoint[$point][self::MEMORY] = memory_get_usage(); + return true; + } + /** + * 移除调试点 + * @param string $point 调试点 + */ + public static function removeBreakPoint($point = '') { + if ($point) { + if (isset(self::$breakpoint[$point])) + unset(self::$breakpoint[$point]); + } else { + self::$breakpoint = array(); + } + } + + /** + * 取得系统运行所耗内存 + */ + public static function getMemUsage() { + $useMem = memory_get_usage() - USEMEM_START; + return $useMem ? round($useMem / 1024, self::DECIMAL_DIGITS) : 0; + } + + /** + * 取得系统运行所耗时间 + */ + public static function getExecTime() { + $useTime = microtime(true) - RUNTIME_START; + return $useTime ? round($useTime, self::DECIMAL_DIGITS) : 0; + } + + /** + * 获取调试点 + * @param $point + * @param $label + */ + public static function getBreakPoint($point, $label = '') { + if (!isset(self::$breakpoint[$point])) + return array(); + return $label ? self::$breakpoint[$point][$label] : self::$breakpoint[$point]; + } + + /** + * 调试点之间系统运行所耗内存 + * @param string $beginPoint 开始调试点 + * @param string $endPoint 结束调试点 + * @return float + */ + public static function getMemUsageOfp2p($beginPoint, $endPoint = '') { + if (!isset(self::$breakpoint[$beginPoint])) + return 0; + $endMemUsage = isset(self::$breakpoint[$endPoint]) ? self::$breakpoint[$endPoint][self::MEMORY] : memory_get_usage(); + $useMemUsage = $endMemUsage - self::$breakpoint[$beginPoint][self::MEMORY]; + return round($useMemUsage / 1024, self::DECIMAL_DIGITS); + } + + /** + * 调试点之间的系统运行所耗时间 + * @param string $beginPoint 开始调试点 + * @param string $endPoint 结束调试点 + * @return float + */ + public static function getExecTimeOfp2p($beginPoint, $endPoint = '') { + if (!isset(self::$breakpoint[$beginPoint])) + return 0; + $endTime = self::$breakpoint[$endPoint] ? self::$breakpoint[$endPoint][self::RUN_TIME] : microtime(true); + $useTime = $endTime - self::$breakpoint[$beginPoint][self::RUN_TIME]; + return round($useTime, self::DECIMAL_DIGITS); + } + + /** + * 堆栈情况 + * @param array $trace 堆栈引用,如异常 + * @return array + */ + public static function trace($trace = array()) { + $debugTrace = $trace ? $trace : debug_backtrace(); + $traceInfo = array(); + foreach ($debugTrace as $info) { + $info['args'] = self::traceArgs($info['args']); + $file = isset($info['file']) ? $info['file'] : ''; + $line = isset($info['line']) ? $info['line'] : ''; + $str = '[' . date("Y-m-d H:i:m") . '] ' . $file . ' (line:' . $line . ') '; + $str .= $info['class'] . $info['type'] . $info['function'] . '('; + $str .= implode(', ', $info['args']); + $str .= ")"; + $traceInfo[] = $str; + } + return $traceInfo; + } + /** + * 获取系统所加载的文件 + */ + public static function loadFiles() { + return get_included_files(); + } + + public static function debug($message = '', $trace = array(), $begin = '', $end = '') { + $runtime = self::getExecTime(); + $useMem = self::getMemUsage(); + $separate = "
"; + $trace = implode("{$separate}", self::trace($trace)); + $debug = ''; + $debug .= "{$message}{$separate}"; + $debug .= "Runtime:{$runtime}s{$separate}"; + $debug .= "Memory consumption:{$useMem}byte{$separate}"; + $debug .= "Stack conditions:{$separate}{$trace}{$separate}"; + if ($begin && $end) { + $PointUseTime = self::getExecTimeOfp2p($begin, $end); + $PointUseMem = self::getMemUsageOfp2p($begin, $end); + $debug .= "Between points {$begin} and {$end} debugging system conditions:{$separate}"; + $debug .= "Runtime:{$PointUseTime}s{$separate}"; + $debug .= "Memory consumption:{$PointUseMem}byte{$separate}"; + } + return $debug; + } + + private static function traceArgs($args = array()) { + foreach ($args as $key => $arg) { + if (is_array($arg)) + $args[$key] = 'array(' . implode(',', $arg) . ')'; + elseif (is_object($arg)) + $args[$key] = 'class ' . get_class($arg); + else + $args[$key] = $arg; + } + return $args; + } + +} +?> \ No newline at end of file diff --git a/wind/log/WindLogger.php b/wind/log/WindLogger.php new file mode 100644 index 00000000..60dac919 --- /dev/null +++ b/wind/log/WindLogger.php @@ -0,0 +1,386 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +class WindLogger extends WindModule { + const LEVEL_INFO = 1; + const LEVEL_TRACE = 2; + const LEVEL_DEBUG = 3; + const LEVEL_ERROR = 4; + const LEVEL_PROFILE = 5; + const WRITE_TYPE = 2; + const WRITE_LEVEL = 1; + const TOKEN_BEGIN = 'begin:'; + const TOKEN_END = 'end:'; + /** + * 每次当日志数量达到100的时候,就写入文件一次 + * @var int + */ + private $_autoFlush = 1000; + private $_logs = array(); + private $_logCount = 0; + private $_profiles = array(); + private $_logDir; + private $_maxFileSize = 100; + /** + * 0: 打印全部日志信息结果 + * 1: 按照level分文件存储日志记录 + * 2: 按照type分文件存储日志记录 + * @var int + */ + private $_writeType = 0; + private $_types = array(); + private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); + + /** + * @param string $logDir + * @param int $writeType + */ + public function __construct($logDir = '', $writeType = 0) { + $this->setLogDir($logDir); + $this->_writeType = $writeType; + } + + /** + * 添加info级别的日志信息 + * @param string $msg + */ + public function info($msg, $type = 'wind.system', $flush = false) { + $this->log($msg, self::LEVEL_INFO, $type, $flush); + } + + /** + * 添加trace级别的日志信息 + * @param string $msg + */ + public function trace($msg, $type = 'wind.system', $flush = false) { + $this->log($msg, self::LEVEL_TRACE, $type, $flush); + } + + /** + * 添加debug的日志信息 + * @param string $msg + */ + public function debug($msg, $type = 'wind.system', $flush = false) { + $this->log($msg, self::LEVEL_DEBUG, $type, $flush); + } + + /** + * 添加Error级别的日志信息 + * @param string $msg + */ + public function error($msg, $type = 'wind.core', $flush = false) { + $this->log($msg, self::LEVEL_ERROR, $type, $flush); + } + + /** + * @param $msg + * @param $type + */ + public function profileBegin($msg, $type = 'wind.core', $flush = false) { + $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); + } + + /** + * @param $msg + * @param $type + */ + public function profileEnd($msg, $type = 'wind.core', $flush = false) { + $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); + } + + /** + * 记录日志信息,但不写入文件 + * @param string $msg 日志信息 + * @param const $logType 日志类别 + */ + public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { + if (!$this->_logDir) + return; + if ($this->_writeType & self::WRITE_TYPE) + (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); + else + $this->_logCount >= $this->_autoFlush && $this->flush(); + if ($level === self::LEVEL_PROFILE) + $message = $this->_build($msg, $level, $type, microtime(true), + $this->getMemoryUsage(false)); + elseif ($level === self::LEVEL_DEBUG) + $message = $this->_build($msg, $level, $type, microtime(true)); + else + $message = $this->_build($msg, $level, $type); + $this->_logs[] = array($level, $type, $message); + $this->_logCount++; + if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) + $this->_types[] = $type; + if ($flush) + $this->flush(); + } + + /** + * 将记录的日志列表信息写入文件 + * @param string $dst 日志被记录于何处 + * @return boolean + */ + public function flush() { + if (empty($this->_logs)) + return false; + Wind::import('WIND:component.utility.WindFile'); + $_l = $_logTypes = $_logLevels = array(); + $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', + self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', + self::LEVEL_PROFILE => 'profile'); + + foreach ($this->_logs as $key => $value) { + $_l[] = $value[2]; + $_logTypes[$value[1]][] = $value[2]; + $_logLevels[$value[0]][] = $value[2]; + } + if ($this->_writeType & 1) { + foreach ($_logLevels as $key => $value) { + if (!$fileName = $this->_getFileName($key)) + continue; + WindFile::write($fileName, join("", $value), 'a'); + } + } + if ($this->_writeType & 2) { + foreach ($_logTypes as $key => $value) { + if (!$fileName = $this->_getFileName($key)) + continue; + WindFile::write($fileName, join("", $value), 'a'); + } + } + if ($fileName = $this->_getFileName()) { + WindFile::write($fileName, join("", $_l), 'a'); + } + $this->_logs = array(); + $this->_logCount = 0; + return true; + } + + /** + * 返回内存使用量 + * @param $peak | 是否是内存峰值 + * @return int + */ + public function getMemoryUsage($peak = true) { + if ($peak && function_exists('memory_get_peak_usage')) + return memory_get_peak_usage(); + elseif (function_exists('memory_get_usage')) + return memory_get_usage(); + $pid = getmypid(); + if (strncmp(PHP_OS, 'WIN', 3) === 0) { + exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); + return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; + } else { + exec("ps -eo%mem,rss,pid | grep $pid", $output); + $output = explode(" ", $output[0]); + return isset($output[1]) ? $output[1] * 1024 : 0; + } + } + + /** + * 组装日志信息 + * @param string $msg 日志信息 + * @param const $logType 日志类别 + * @return string + */ + private function _build($msg, $level, $type, $timer = 0, $mem = 0) { + $result = ''; + switch ($level) { + case self::LEVEL_INFO: + $result = $this->_buildInfo($msg); + break; + case self::LEVEL_ERROR: + $result = $this->_buildError($msg); + break; + case self::LEVEL_DEBUG: + $result = $this->_buildDebug($msg); + break; + case self::LEVEL_TRACE: + $result = $this->_buildTrace($msg); + break; + case self::LEVEL_PROFILE: + $result = $this->_buildProfile($msg, $type, $timer, $mem); + break; + default: + break; + } + return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; + } + + /** + * @param $msg + * @param $type + * @param $timer + * @param $mem + */ + private function _buildProfile($msg, $type, $timer, $mem) { + $_msg = ''; + if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { + $_token = substr($msg, strlen(self::TOKEN_BEGIN)); + $_token = substr($_token, 0, strpos($_token, ':')); + $this->_profiles[] = array($_token, + substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); + } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { + $_msg = "PROFILE! Message:"; + $_token = substr($msg, strlen(self::TOKEN_END)); + $_token = substr($_token, 0, strpos($_token, ':')); + foreach ($this->_profiles as $key => $profile) { + if ($profile[0] !== $_token) + continue; + if ($profile[1]) + $_msg .= "\r\n\t" . $profile[1]; + else + $_msg .= "\r\n\t" . substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1); + $_msg .= "\r\n\tTime:" . ($timer - $profile[3]) . "\r\n\tMem:" . ($mem - $profile[4]) . "\r\n\tType:$profile[2]"; + break; + } + unset($this->_profiles[$key]); + } + return $_msg; + } + + /** + * 组装info级别的信息输出格式 + * + * [2011-01-24 10:00:00] INFO! Message: $msg + * + * @param string $msg + * @return string + */ + private function _buildInfo($msg) { + return "INFO! Message: " . $msg; + } + + /** + * 组装堆栈trace的信息输出格式 + * + * [2011-01-24 10:00:00] TRACE! Message: $msg + * #1 trace1 + * #2 trace2 + * + * @param string $msg + * @return string + */ + private function _buildTrace($msg) { + return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); + } + + /** + * 组装debug信息输出 + * + * [2011-01-24 10:00:00] DEBUG! Message: $msg + * #1 trace1 + * #2 trace2 + * + * @param string $msg + * @return string + */ + private function _buildDebug($msg) { + return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); + } + + /** + *组装Error信息输出 + * + * [2011-01-24 10:00:00] ERROR! Message: $msg + * #1 trace1 + * #2 trace2 + * + * @param string $msg + * @return string + */ + private function _buildError($msg) { + return 'ERROR! Message: ' . $msg; + } + + /** + * 错误堆栈信息的获取及组装输出 + * + * #1 trace + * #2 trace + * + * @return string + */ + private function _getTrace() { + $num = 0; + $info[] = 'Stack trace:'; + $traces = debug_backtrace(); + foreach ($traces as $traceKey => $trace) { + if ($num >= 7) + break; + if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( + $trace['file'], __CLASS__ . '.php') !== false) + continue; + $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; + $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; + if ($function == 'WindBase::log') + continue; + $args = array_map(array($this, '_buildArg'), $trace['args']); + $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; + } + return $info; + } + + /** + * 组装输出的trace中的参数组装 + * @param mixed $arg + */ + private function _buildArg($arg) { + switch (gettype($arg)) { + case 'array': + return 'Array'; + break; + case 'object': + return 'Object ' . get_class($arg); + break; + default: + return "'" . $arg . "'"; + break; + } + } + + /** + * 取得日志文件名 + * @return string + */ + private function _getFileName($suffix = '') { + $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; + $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; + if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { + $counter = 0; + do { + $counter++; + $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); + } while (is_file($_newFile)); + @rename($_logfile, $_newFile); + } + return $_logfile; + } + + public function __destruct() { + $this->flush(); + } + + /** + * @param string $logFile + */ + public function setLogDir($logDir) { + if (!is_dir($logDir)) + $logDir = Wind::getRealDir($logDir); + $this->_logDir = $logDir; + } + + /** + * @param field_type $_maxFileSize + */ + public function setMaxFileSize($maxFileSize) { + $this->_maxFileSize = (int) $maxFileSize; + } +} + + \ No newline at end of file diff --git a/wind/mail/WindMail.php b/wind/mail/WindMail.php new file mode 100644 index 00000000..b4efd04b --- /dev/null +++ b/wind/mail/WindMail.php @@ -0,0 +1,898 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * 邮件发送类 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindMail { + + /** + * @var string 邮件内容仅文本 + */ + const ONLYTEXT = 1; + /** + * @var string 邮件内容仅HTML + */ + const ONLYHTML = 2; + /** + * @var string 邮件内容是文本和HTML + */ + const TEXTHTML = 3; + /** + * @var string 邮件内容有附件 + */ + const ATTACH = 4; + /** + * @var string 无邮件内容 + */ + const NONE = 5; + + /** + * @var array 邮件收件人 + */ + private $recipients = array(); + /** + * @var array 邮件头 + */ + private $mailHeader = array(); + /** + * @var array 邮件边界线 + */ + private $boundary = ''; + /** + * @var array 邮件附件 + */ + private $attachment = array(); + /** + * @var string 邮件字符集 + */ + private $charSet = 'gbk'; + + /** + * @var string 邮件mime类型 + */ + private $contentType = self::MIME_TEXT; + /** + * @var string 邮件消息体html展现方式 + */ + private $bodyHtml = ''; + /** + * @var string 邮件消息体文本展现方式 + */ + private $bodyText = ''; + /** + * @var string 是否是内嵌资源 + */ + private $embed = false; + /** + * @var string 邮件编码方式 + */ + private $encode = self::ENCODE_BASE64; + //常用邮件MIME + const CRLF = "\n"; + const TO = 'To'; + const CC = 'Cc'; + const BCC = 'Bcc'; + const FROM = 'From'; + const SUBJECT = 'Subject'; + const MESSAGEID = 'Message-Id'; + const CONTENTTYPE='Content-Type'; + const CONTENTENCODE = 'Content-Transfer-Encoding'; + const CONTENTID = 'Content-ID'; + const CONTENTPOSITION = 'Content-Disposition'; + const CONTENTDESCRIPT = 'Content-Description'; + const CONTENTLOCATION = 'Content-Location'; + const CONTENTLANGUAGE='Content-Language'; + const DATE = 'Date'; + //邮件MIME类型 + const MIME_OCTETSTREAM = 'application/octet-stream'; + const MIME_TEXT = 'text/plain'; + const MIME_HTML = 'text/html'; + const MIME_ALTERNATIVE = 'multipart/alternative'; + const MIME_MIXED = 'multipart/mixed'; + const MIME_RELATED = 'multipart/related'; + //邮件编码 + const ENCODE_7BIT = '7bit'; + const ENCODE_8BIT = '8bit'; + const ENCODE_QP = 'quoted-printable'; + const ENCODE_BASE64 = 'base64'; + const ENCODE_BINARY = 'binary'; + + const DIS_ATTACHMENT = 'attachment'; + const DIS_INLINE = 'inline'; + const LINELENGTH = 72; + + const SEND_SMTP = 'smtp'; + const SEND_PHP = 'php'; + const SEND_SEND = 'send'; + + public function send($type = self::SEND_SMTP,$config = array()){ + if(!in_array($type,array(self::SEND_SMTP,self::SEND_PHP,self::SEND_SEND))){ + throw new WindException('There is no way that you want to send e-mail'); + } + $class = Wind::import('Wind:component.mail.sender.Wind'.ucfirst($type).'Mail'); + /* @var $sender IWindSendMail */ + $sender = new $class($config); + $sender->send($this); + return true; + } + /** + * 创建邮件头 + * @return string + */ + public function createHeader(){ + $header = ''; + if(!isset($this->mailHeader[self::CONTENTTYPE])){ + $this->setContentType(null); + } + foreach($this->mailHeader as $key=>$value){ + $header .= $this->headerLine($key,$value); + } + return $header.self::CRLF; + } + + /** + * 创建邮件消息体 + * @return string + */ + public function createBody(){ + $mime = $this->getMimeType(); + if(self::ONLYTEXT === $mime){ + return self::encode($this->getBodyText(),$this->encode); + }elseif(self::ONLYHTML === $mime){ + return self::encode($this->getBodyHtml(),$this->encode).self::CRLF; + }elseif(self::TEXTHTML === $mime){ + $boundary = $this->boundaryLine(); + $body = $boundary.$this->getTextHeader().self::encode($this->getBodyText(),$this->encode).self::CRLF; + $body .= $boundary.$this->getHtmlHeader().self::encode($this->getBodyHtml(),$this->encode).self::CRLF; + return $body .= $this->boundaryEndLine(); + }elseif(self::ATTACH === $mime){ + $boundary = $this->boundaryLine(); + $body = ''; + if('' != ($text = $this->getBodyText())){ + $body .= $boundary.$this->getTextHeader().self::encode($text,$this->encode).self::CRLF; + } + if('' != ($html = $this->getBodyHtml())){ + $body .= $boundary.$this->getHtmlHeader().self::encode($html,$this->encode).self::CRLF; + } + $body .= $this->attach().self::CRLF; + return $body .= $this->boundaryEndLine(); + } + return ''; + } + + + + /** + * 设置邮件头 + * @param string $name 邮件头名称 + * @param string $value 邮件头对应的值 + * @param boolean $append 是否是追加 + * @return boolean + */ + public function setMailHeader($name, $value,$append = true) { + $value = is_array($value) ? $value : array($value); + if(false === $append){ + $this->mailHeader[$name] = $value; + return true; + } + if (!isset($this->mailHeader[$name])) { + $this->mailHeader[$name] = $value; + }else{ + foreach($value as $key=>$value){ + if(is_string($key)){ + $this->mailHeader[$name][$key]=$value; + }else{ + $this->mailHeader[$name][]=$value; + } + } + } + return true; + } + + /** + * 设置发件人 + * @param string $email 发件人邮箱 + * @param string $name 发件人姓名 + */ + public function setFrom($email, $name = null) { + $value = $name ? array($name => $email) : array($email); + $this->setMailHeader(self::FROM, $value,false); + } + + /** + * 设置收件人 + * @param string $email 收件人邮箱 + * @param string $name 收件人姓名 + */ + public function setTo($email, $name = null) { + $value = $name ? array($name => $email) : array($email); + $this->setMailHeader(self::TO, $value); + } + /** + * 设置抄送人 + * @param string $email 抄送人邮箱 + * @param string $name 抄送人姓名 + */ + public function setCc($email, $name = null) { + $value = $name ? array($name => $email) : array($email); + $this->setMailHeader(self::CC, $value); + } + /** + * 设置暗送人 + * @param string $email 暗送人邮箱 + * @param string $name 暗送人姓名 + */ + public function setBcc($email, $name = null) { + $value = $name ? array($name => $email) : array($email); + $this->setMailHeader(self::BCC, $value); + } + + /** + * 设置邮件主题 + * @param string $subject 主题 + */ + public function setSubject($subject) { + $this->setMailHeader(self::SUBJECT, $subject,false); + } + + /** + * 设置邮件日期 + * @param boolean $ifchinese 是否是中国日期 + */ + public function setDate($date = null,$ifchinese = true){ + if(!$date){ + Wind::import ( 'WIND:component.utility.date.WindDate' ); + $date = $ifchinese ? WindDate::getChinaDate() : WindDate::getRFCDate(); + } + $this->setMailHeader(self::DATE,$date ); + } + + /** + *设置邮件消息ID + */ + public function setMessageId() { + $this->setMailHeader(self::MESSAGEID, '<' . $this->createMessageId() . '>'); + } + + /** + * 设置邮件html展示内容 + * @param string $bodyHtml + */ + public function setBodyHtml($bodyHtml){ + $this->bodyHtml = $bodyHtml; + } + /** + * 设置邮件文本展示内容 + * @param string $bodyText + */ + public function setBodyText($bodyText){ + $this->bodyText = $bodyText; + } + + /** + * 设置邮件类型 + * @param string $type + */ + public function setContentType($type = null){ + if(!$type){ + $mime = $this->getMimeType(); + if(self::ONLYTEXT === $mime){ + $type = self::MIME_TEXT; + }elseif(self::ONLYHTML === $mime){ + $type = self::MIME_HTML; + }elseif(self::TEXTHTML === $mime){ + $type = self::MIME_ALTERNATIVE; + }elseif(self::ATTACH === $mime && $this->embed){ + $type = self::MIME_RELATED; + }elseif(self::ATTACH === $mime && !$this->embed){ + $type = self::MIME_MIXED; + }else{ + $type = self::MIME_TEXT; + } + } + if(self::MIME_TEXT == $type || self::MIME_HTML == $type){ + $contentType = sprintf("%s; charset=\"%s\"", $type, $this->charSet); + }elseif(self::MIME_RELATED == $type){ + $this->setBoundary(); + $contentType = sprintf("%s;%s type=\"text/html\";%s boundary=\"%s\"", self::MIME_RELATED, self::CRLF, self::CRLF, $this->getBoundary()); + }else{ + $this->setBoundary(); + $contentType = sprintf("%s;%s boundary=\"%s\"",$type,self::CRLF,$this->getBoundary()); + } + $this->contentType = $type; + $this->setMailHeader(self::CONTENTTYPE,$contentType,false); + } + + /** + * 设置是否是内嵌资源 + * @param boolean $embed + */ + public function setEmbed($embed = false){ + $this->embed = $embed; + } + + /** + * 设置邮件编码 + * @param string $encode + */ + public function setContentEncode($encode = self::ENCODE_BASE64){ + $this->encode = $encode; + $this->setMailHeader(self::CONTENTENCODE,$encode); + } + + /** + * 设置邮件字符 + * @param string $charset + */ + public function setCharset($charset){ + $this->charSet = $charset; + } + + /** + * 设置附件 + * @param string $stream 附件名或者附件内容 + * @param string $mime 附件类型 + * @param string $disposition 附件展现方式 + * @param string $encode 附件编码 + * @param string $filename 文件名 + * @param string $cid 内容ID + */ + public function setAttachment($stream, $mime = self::MIME_OCTETSTREAM, $disposition = self::DIS_ATTACHMENT, $encode = self::ENCODE_BASE64,$filename = null,$cid = 0){ + + $this->attachment[] = array( + $stream, + $mime, + $disposition, + $encode, + $filename, + $cid + ); + } + + /** + * 设置边界线 + */ + public function setBoundary() { + $this->boundary = '==_' . md5(microtime(true) . uniqid()); + } + + public function getMailHeader($name = null,$subname = null){ + if(!$name){ + return $this->mailHeader; + } + if(!isset($this->mailHeader[$name])){ + return ''; + } + $header = $this->mailHeader[$name]; + if(!$subname || !isset($header[$subname])){ + return $header; + } + return $header[$subname]; + } + + /** + * 取得发件人 + * @return array + */ + public function getFrom() { + if(isset($this->mailHeader[self::FROM])){ + $from = $this->mailHeader[self::FROM]; + return is_array($from) ? array_shift($from) : $from; + } + return ''; + } + /** + * 取得收件人 + * @return array + */ + public function getTo() { + return isset($this->mailHeader[self::TO]) ? $this->mailHeader[self::TO] : array(); + } + + /** + * 取得抄送的对象 + * @return array + */ + public function getCc() { + return isset($this->mailHeader[self::CC]) ? $this->mailHeader[self::CC] : array(); + } + + /** + * 取得暗送对象 + * @return array + */ + public function getBcc() { + return isset($this->mailHeader[self::BCC]) ? $this->mailHeader[self::BCC] : array(); + } + + /** + * 取得邮件主题 + * @return array + */ + public function getSubject() { + if(isset($this->mailHeader[self::SUBJECT])){ + $subject = $this->mailHeader[self::SUBJECT]; + return is_array($subject) ? array_shift($subject) : $subject; + } + return ''; + } + + /** + * 取得边界符 + * @return array + */ + public function getBoundary() { + return $this->boundary; + } + + /** + * 取得mime类型 + * @return string + */ + public function getMimeType(){ + if('' != $this->getBodyText() && '' == $this->getBodyHtml() && false == $this->hasAttachment()){ + return self::ONLYTEXT; + }elseif('' == $this->getBodyText() && '' != $this->getBodyHtml() && false == $this->hasAttachment()){ + return self::ONLYHTML; + }elseif('' != $this->getBodyText() && '' != $this->getBodyHtml() && false == $this->hasAttachment()){ + return self::TEXTHTML; + }elseif($this->hasAttachment()){ + return self::ATTACH; + }else{ + return self::NONE; + } + return 0; + } + + /** + * 取得真实的收件人 + * @return array + */ + public function getRecipients() { + $this->buildRecipients($this->getTo()); + $this->buildRecipients($this->getCc()); + $this->buildRecipients($this->getBcc()); + return $this->recipients; + } + + /** + * 取得消息中的html + * @return string + */ + public function getBodyHtml(){ + return trim($this->bodyHtml); + } + + /** + * 取得消息中的文本 + * @return string + */ + public function getBodyText(){ + return trim($this->bodyText); + } + + /** + * 取得文本头 + * @return string + */ + public function getTextHeader(){ + $textHeader = self::CONTENTTYPE.': text/plain; charset='.$this->charSet.self::CRLF; + return $textHeader .= self::CONTENTENCODE.': '.$this->encode.self::CRLF; + } + + /** + * 取得html头 + * @return string + */ + public function getHtmlHeader(){ + $htmlHeader = self::CONTENTTYPE.': text/html; charset='.$this->charSet.self::CRLF; + return $htmlHeader .= self::CONTENTENCODE.': '.$this->encode.self::CRLF.self::CRLF; + } + + /** + * 取得附件的头 + * @param string $mime mime头类型 + * @param string $name 文件名 + * @param string $encode 编码 + * @param string $disposition 附件展现方式 + * @param string $cid 内容ID + * @return string + */ + public function getAttachHeader($mime,$name,$encode = self::ENCODE_BASE64,$disposition = 'attachment',$cid = 0){ + $attachHeader = sprintf(self::CONTENTTYPE.": %s; name=\"%s\"%s", $mime, $name, self::CRLF); + $attachHeader .= sprintf(self::CONTENTENCODE.": %s%s", $encode, self::CRLF); + if($disposition == 'inline') { + $attachHeader .= sprintf(self::CONTENTID.": <%s>%s", $cid, self::CRLF); + } + return $attachHeader .= sprintf(self::CONTENTPOSITION.": %s; filename=\"%s\"%s%s", $disposition, $name, self::CRLF,self::CRLF); + } + + /** + * 获到文件中的内容 + * @param string $file 文件名 + * @param string $encode 编码方式 + * @return string + */ + public function getStreamFromFile ($file, $encode = self::ENCODE_BASE64) { + $fp = fopen($file, 'rb'); + $magic_quotes = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + $steam = fread($fp,filesize($file)); + fclose($fp); + set_magic_quotes_runtime($magic_quotes); + return $steam; + } + + /** + * 上传附件 + * @return string + */ + public function attach() { + $attach = ''; + foreach($this->attachment as $key => $value){ + list($stream,$mime,$disposition,$encode,$filename,$cid) = $value; + $filename = $filename ? $filename : (is_file($stream) ? $stream : 'attachment_'.$key); + $attachHeader = $this->getAttachHeader($mime,$filename,$encode,$disposition,$cid); + $boundary = $this->boundaryLine(); + if(is_file($stream)){ + $stream = $this->getStreamFromFile($stream); + } + $attach .= $boundary.$attachHeader.$this->encode($stream,$encode).self::CRLF; + } + return $attach; + } + + /** + * 过滤mime头 + * @param string $header + * @return string + */ + public function filterHeader($header) { + return strtr(trim($header),array("\r"=>'',"\n"=>'',"\r\n"=>'')); + } + + /** + * 获取边界线 + * @return string + */ + public function boundaryLine() { + return self::CRLF . '--' . $this->getBoundary() . self::CRLF; + } + + /** + * 获取结束边界线 + * @return string + */ + public function boundaryEndLine() { + return self::CRLF . '--' . $this->getBoundary() . '--' . self::CRLF; + } + + /** + * 对字符进行编码 + * @param string $string 要编码的字符串 + * @param string $encode 编码的方式 + * @return string + */ + public function encode($string,$encode = self::ENCODE_BASE64){ + switch($encode) { + case self::ENCODE_BASE64: return self::encodeBase64($string); + case self::ENCODE_7BIT: + case self::ENCODE_8BIT: + case self::ENCODE_BINARY:return $string; + case self::ENCODE_QP:return self::EncodeQP($string); + default:return $string; + } + return $string.self::CRLF; + } + + /** + * 对mime头进行编码 + * @param string $string 要编码的字符串 + * @param string $encode 编码的方式 + * @return string + */ + public function encodeHeader($header,$encode=self::ENCODE_BASE64){ + switch($encode) { + case self::ENCODE_BASE64: return self::encodeBase64Header($this->filterHeader($header),$this->charSet); + case self::ENCODE_7BIT: + case self::ENCODE_8BIT: + case self::ENCODE_BINARY:return $header; + case self::ENCODE_QP:return self::encodeQpHeader($this->filterHeader($header),$this->charSet); + default:return $header; + } + return $header; + } + /** + * 对mime头进行quoted-printable编码 + * @param string $string 要编码的字符串 + * @param string $chunklen 分割字符串中每块的长度 + * @param string $end 每个字符块后面的填充符 + * @return string + */ + public static function encodeQpHeader($string, $charset,$chunkLen = self::LINELENGTH,$end = self::CRLF){ + $prefix = sprintf('=?%s?Q?', $charset); + $chunkLen = $chunkLen-strlen($prefix)-3; + $string = self::_encodeQp($string); + $string = strtr($string,array('_'=>'5F',' '=>'=20','?'=>'=3F')); + $lines[] = $tmp = ''; + while(strlen($string) > 0) { + $culLen = max(count($lines)-1, 0); + $token = self::getNextQpToken($string); + $string = substr($string, strlen($token)); + $tmp .= $token; + if('=20' == $token) { + if(strlen($lines[$culLen].$tmp) > $chunkLen) { + $lines[$culLen+1] = $tmp; + } else { + $lines[$culLen] .= $tmp; + } + $tmp = ''; + } + if(0 == strlen($string)) { + $lines[$culLen] .= $tmp; + } + } + for($i = 0; $i < count($lines); $i++) { + $lines[$i] = ' '.$prefix.$lines[$i].'?='; + } + return trim(implode($end, $lines)); + } + /** + * 对mime头进行base64编码 + * @param string $string 要编码的字符串 + * @param string $chunklen 分割字符串中每块的长度 + * @param string $end 每个字符块后面的填充符 + * @return string + */ + public static function encodeBase64Header($string,$charset, $chunkLen = self::LINELENGTH,$end = self::CRLF){ + $prefix = '=?' . $charset . '?B?'; + $suffix = '?='; + $length = $chunkLen - strlen($prefix) - strlen($suffix); + $encodedString = self::encodeBase64($string, $length, $end); + $encodedString = $prefix . strtr($encodedString,array($end=>$suffix . $end . ' ' . $prefix)) . $suffix; + return $encodedString; + } + /** + * quoted-printable编码 + * @param string $string 要编码的字符串 + * @param string $chunklen 分割字符串中每块的长度 + * @param string $end 每个字符块后面的填充符 + * @return string + */ + public static function encodeQp($string, $chunklen = self::LINELENGTH,$end = self::CRLF){ + $endodeString = ''; + $string = self::_encodeQp($string); + while ($string) { + $plen = $chunklen < ($plen = strlen($string)) ? $chunklen : $plen; + if (false !== ($pos = strrpos(substr($string, 0, $plen), '=')) && $pos >= $plen - 2) { + $plen = $pos; + } + 0 < $plen && ' ' == $string[$plen - 1] && --$plen; + $endodeString .= substr($string, 0, $plen) . '=' . $end; + $string = substr($string, $plen); + } + $endodeString = rtrim($endodeString, $end); + $endodeString = rtrim($endodeString, '='); + return $endodeString; + } + /** + * base64编码 + * @param string $string 要编码的字符串 + * @param string $chunklen 分割字符串中每块的长度 + * @param string $end 每个字符块后面的填充符 + * @return string quoted-printable + */ + public static function encodeBase64($string,$chunklen = self::LINELENGTH,$end = self::CRLF){ + return chunk_split(base64_encode($string), $chunklen, $end); + } + /** + * quoted-printable 对照表 + * @return string + */ + public static function getQpTable(){ + return array( + "\x00"=>"=00","\x01"=>"=01","\x02"=>"=02","\x03"=>"=03", + "\x04"=>"=04","\x05"=>"=05","\x06"=>"=06","\x07"=>"=07", + "\x08"=>"=08","\x09"=>"=09","\x0A"=>"=0A","\x0B"=>"=0B", + "\x0C"=>"=0C","\x0D"=>"=0D","\x0E"=>"=0E","\x0F"=>"=0F", + "\x10"=>"=10","\x11"=>"=11","\x12"=>"=12","\x13"=>"=13", + "\x14"=>"=14","\x15"=>"=15","\x16"=>"=16","\x17"=>"=17", + "\x18"=>"=18","\x19"=>"=19","\x1A"=>"=1A","\x1B"=>"=1B", + "\x1C"=>"=1C","\x1D"=>"=1D","\x1E"=>"=1E","\x1F"=>"=1F", + "\x7F"=>"=7F","\x80"=>"=80","\x81"=>"=81","\x82"=>"=82", + "\x83"=>"=83","\x84"=>"=84","\x85"=>"=85","\x86"=>"=86", + "\x87"=>"=87","\x88"=>"=88","\x89"=>"=89","\x8A"=>"=8A", + "\x8B"=>"=8B","\x8C"=>"=8C","\x8D"=>"=8D","\x8E"=>"=8E", + "\x8F"=>"=8F","\x90"=>"=90","\x91"=>"=91","\x92"=>"=92", + "\x93"=>"=93","\x94"=>"=94","\x95"=>"=95","\x96"=>"=96", + "\x97"=>"=97","\x98"=>"=98","\x99"=>"=99","\x9A"=>"=9A", + "\x9B"=>"=9B","\x9C"=>"=9C","\x9D"=>"=9D","\x9E"=>"=9E", + "\x9F"=>"=9F","\xA0"=>"=A0","\xA1"=>"=A1","\xA2"=>"=A2", + "\xA3"=>"=A3","\xA4"=>"=A4","\xA5"=>"=A5","\xA6"=>"=A6", + "\xA7"=>"=A7","\xA8"=>"=A8","\xA9"=>"=A9","\xAA"=>"=AA", + "\xAB"=>"=AB","\xAC"=>"=AC","\xAD"=>"=AD","\xAE"=>"=AE", + "\xAF"=>"=AF","\xB0"=>"=B0","\xB1"=>"=B1","\xB2"=>"=B2", + "\xB3"=>"=B3","\xB4"=>"=B4","\xB5"=>"=B5","\xB6"=>"=B6", + "\xB7"=>"=B7","\xB8"=>"=B8","\xB9"=>"=B9","\xBA"=>"=BA", + "\xBB"=>"=BB","\xBC"=>"=BC","\xBD"=>"=BD","\xBE"=>"=BE", + "\xBF"=>"=BF","\xC0"=>"=C0","\xC1"=>"=C1","\xC2"=>"=C2", + "\xC3"=>"=C3","\xC4"=>"=C4","\xC5"=>"=C5","\xC6"=>"=C6", + "\xC7"=>"=C7","\xC8"=>"=C8","\xC9"=>"=C9","\xCA"=>"=CA", + "\xCB"=>"=CB","\xCC"=>"=CC","\xCD"=>"=CD","\xCE"=>"=CE", + "\xCF"=>"=CF","\xD0"=>"=D0","\xD1"=>"=D1","\xD2"=>"=D2", + "\xD3"=>"=D3","\xD4"=>"=D4","\xD5"=>"=D5","\xD6"=>"=D6", + "\xD7"=>"=D7","\xD8"=>"=D8","\xD9"=>"=D9","\xDA"=>"=DA", + "\xDB"=>"=DB","\xDC"=>"=DC","\xDD"=>"=DD","\xDE"=>"=DE", + "\xDF"=>"=DF","\xE0"=>"=E0","\xE1"=>"=E1","\xE2"=>"=E2", + "\xE3"=>"=E3","\xE4"=>"=E4","\xE5"=>"=E5","\xE6"=>"=E6", + "\xE7"=>"=E7","\xE8"=>"=E8","\xE9"=>"=E9","\xEA"=>"=EA", + "\xEB"=>"=EB","\xEC"=>"=EC","\xED"=>"=ED","\xEE"=>"=EE", + "\xEF"=>"=EF","\xF0"=>"=F0","\xF1"=>"=F1","\xF2"=>"=F2", + "\xF3"=>"=F3","\xF4"=>"=F4","\xF5"=>"=F5","\xF6"=>"=F6", + "\xF7"=>"=F7","\xF8"=>"=F8","\xF9"=>"=F9","\xFA"=>"=FA", + "\xFB"=>"=FB","\xFC"=>"=FC","\xFD"=>"=FD","\xFE"=>"=FE", + "\xFF"=>"=FF" + ); + } + /** + * 在quoted-printable编码中过滤等号 + * @param string $string 取得编码的字符串 + * @return string + */ + public static function _encodeQp($string){ + $string = strtr($string,array('='=>'=3D')); + return strtr($string,self::getQpTable()); + } + /** + * 生成mime邮件头的消息ID + * @return string + */ + public function createMessageId() { + if (array() != ($from = $this->getFrom())) { + $user = is_array($from) ? $from[0] : $from; + } elseif (isset($_SERVER['REMOTE_ADDR'])) { + $user = $_SERVER['REMOTE_ADDR']; + } else { + $user = getmypid(); + } + $rand = mt_rand(); + if ($this->recipients) { + $recipient = array_rand($this->recipients); + } else { + $recipient = 'No recipient'; + } + if (isset($_SERVER["SERVER_NAME"])) { + $host = $_SERVER["SERVER_NAME"]; + } else { + $host = php_uname('n'); + } + return sha1(time() . $user . $rand . $recipient) . '@' . $host; + } + + /** + * 清空邮件头 + * @param string $header + */ + public function clearMailHeader($header = null){ + if($header){ + if(isset($this->mailHeader[$header])){ + unset($this->mailHeader[$header]); + } + }else{ + $this->mailHeader = array(); + } + } + /** + * 清空附件 + */ + public function clearAttachment(){ + $this->attachment = array(); + } + + /** + * 清空收件人 + */ + public function clearRecipients(){ + $this->recipients = array(); + } + + /** + * 清空边界线 + */ + public function clearBoundary(){ + $this->boundary = ''; + } + + /** + * 清空html格式的邮件正文 + */ + public function clearBodyHtml(){ + $this->bodyHtml = ''; + } + + /** + * 清空text格式的邮件正文 + */ + public function clearBodyText(){ + $this->bodyText = ''; + } + + /** + * 清空邮件头、附件、收件人、边界线、html和text格式的邮件正文; + */ + public function clearAll(){ + $this->clearMailHeader(); + $this->clearRecipients(); + $this->clearAttachment(); + $this->clearBoundary(); + $this->clearBodyHtml(); + $this->clearBodyText(); + } + /** + * 构建收件人列表 + * @param string $data + * @return array(); + */ + private function buildRecipients($data = array()) { + if(empty($data) || !is_array($data)){ + return array(); + } + foreach ($data as $key => $value) { + if (is_string($key)) { + $this->recipients[] = $value.' '.$key; + } else { + $this->recipients[] = $value; + } + } + return $this->recipients; + } + + /** + * 生成mime邮件头 + * @param string $name mime头 + * @param string $value mime值 + * @return string + */ + private function headerLine($name,$value){ + if(is_array($value)){ + $tmp = ''; + foreach($value as $key=>$_value){ + $_value = is_string($key) ? $key.' '.$_value : $_value; + $tmp .= $tmp ? ','.$_value : $_value; + } + return $name.': '.$tmp.self::CRLF; + + }else{ + return $name .': '.$value.self::CRLF; + } + return ''; + } + + /** + * 判断邮件是否有附件 + * @return boolean + */ + private function hasAttachment(){ + return count($this->attachment) > 0; + } + + /** + * 取得下一个quoted-printable + * @param string $string + * @return string + */ + private static function getNextQpToken($string){ + return '=' == substr($string, 0, 1) ? substr($string, 0, 3) : substr($string, 0, 1); + } +} \ No newline at end of file diff --git a/wind/mail/protocol/WindImap.php b/wind/mail/protocol/WindImap.php new file mode 100644 index 00000000..2e0dd161 --- /dev/null +++ b/wind/mail/protocol/WindImap.php @@ -0,0 +1,663 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.mail.protocol.WindSocket'); +/** + * imap协议封装 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindImap { + const CRLF = "\r\n"; + /** + * @var string w命令标签 + */ + const TAG = 'Tag'; + + /*--------imap中邮件标记---------*/ + + /** + * @var string 已被阅读 + */ + const SEEN = '\seen'; + /** + * @var string 已被回复 + */ + const ANSWERED = '\Answered'; + + /** + * @var string 标识为紧急 + */ + const FLAGGED = '\Flagged'; + /** + * @var string 标识为已删除 + */ + const DELETED = '\Deleted'; + /** + * @var string 草稿 + */ + const DRAFT = '\Draft'; + /** + * @var string 新邮件 + */ + const RECENT = '\Recent'; + /*--------imap中邮件标记--------*/ + + /*---------imap中邮件标记类型(store/stripstore方法flags参数)--------*/ + /** + * @var string 邮件的一组标志 + */ + const FLAGS = 'FLAGS'; + /** + * @var string 表示一组邮件的标志 + */ + const SLIENT = 'FLAGS.SLIENT'; + /*---------imap中邮件标记类型(store/stripstore方法flags参数)--------*/ + + /*--------fetch函数中参数$dataname的值---------*/ + /** + * @var string 按照一定格式的邮件摘要,包括邮件标志、RFC822.SIZE、自身的时间和信封信息。 + */ + const ALL = 'ALL'; + /** + * @var string 返回邮件体文本格式和大小的摘要信息 + */ + const BODY = 'BODY'; + /** + * @var string 返回邮件的一些摘要,包括邮件标志、RFC822.SIZE、和自身的时间 + */ + const FAST = 'FAST'; + /** + * @var string 要信息,包括邮件标志、RFC822.SIZE、自身的时间和BODYSTRUCTURE的信息。 + */ + const FULL = 'FULL'; + + /** + * @var string 此邮件的标志 + */ + const FLAG = 'FLAGS'; + /** + * @var string 邮件的[MIME-IMB]的体结构。 + */ + const BODYSTRUCTUR = 'BODYSTRUCTUR'; + /** + * @var string 自身的时间。 + */ + const INTERNALDATE = 'INTERNALDATE'; + /** + * @var string 等同于BODY[]。 + */ + const RFC822 = 'RFC822'; + /** + * @var string 邮件的[RFC-2822]大小 + */ + const RFC822SIZE = 'RFC822.SIZE'; + /** + * @var string 等同于BODY.PEEK[HEADER], + */ + const RFC822HEADER = 'RFC822.HEADER'; + /** + * @var string 功能上等同于BODY[TEXT] + */ + const RFC822TEXT = 'RFC822.TEXT'; + /** + * @var string 返回邮件的UID号,UID号是唯一标识邮件的一个号码。 + */ + const UID = 'UID'; + /*--------fetch函数中参数$dataname的值---------*/ + + /*--------header中的field--------*/ + /** + * @var string 日期 + */ + const DATE = 'Date'; + /** + * @var string 发件人 + */ + const FROM = 'From'; + /** + * @var string 收件人 + */ + const TO = 'To'; + /** + * @var string 抄送地址 + */ + const CC = 'Cc'; + /** + * @var string 抄送地址 + */ + const BCC = 'Bcc'; + /** + * @var string 发送地址 + */ + const DELIVERED = 'Delivered-To'; + /** + * @var string 回复地址 + */ + const REPLY = 'Reply-To'; + /** + * @var string 主题 + */ + const SUBEJCT = 'Subject'; + /** + * @var string MIME内容的类型 + */ + const CONTENTTYPE = 'Content-Type'; + /** + * @var string 内容的传输编码方式 + */ + const CONTENTENCODE = 'Content-Transfer-Encoding'; + /** + * @var string MIME版本 + */ + const MIMEVERSION = 'MIME-Version'; + /** + * @var string 消息ID + */ + const MESSAGEID = 'Message-Id'; + + /** + * @var string 传输路径 + */ + const RECEIVED = 'Received'; + /** + * @var string 回复地址 + */ + const RETURNPATH = 'Return-Path'; + /*--------header中的field--------*/ + + /*--------status命令中所用参数--------*/ + /** + * @var string 邮箱中的邮件总数 + */ + const S_MESSAGES = 'MESSAGES'; + /** + * @var string 邮箱中标志为\RECENT的邮件数 + */ + const S_RECENT = 'RECENT'; + /** + * @var string 可以分配给新邮件的下一个UID + */ + const S_UIDNEXT = 'UIDNEXT'; + /** + * @var string 邮箱的UID有效性标志 + */ + const S_UIDVALIDITY = 'UIDVALIDITY'; + /** + * @var string 邮箱中没有被标志为\UNSEEN的邮件数 + */ + const S_UNSEEN = 'UNSEEN'; + /*--------status命令中所用参数--------*/ + + /*--------search命令中所用参数--------*/ + /** + * @var string 返回所有的匹配 + */ + CONST SH_ALL = 'ALL'; + /** + * @var string 返回新的邮件 + */ + CONST SH_NEW = 'NEW'; + /** + * @var string 返回邮件中打了\Answered标记的邮件 + */ + CONST SH_ANSWERED = 'ANSWERED'; + /** + * @var string 返回邮件中指字暗送的邮件 + */ + CONST SH_BCC = 'BCC'; + /** + * @var string 返回指定日期已前的邮件 + */ + CONST SH_BEFORE = 'BEFORE'; + /** + * @var string 返回有主体的邮件 + */ + CONST SH_BODY = 'BODY'; + /** + * @var string 返回邮件中打了\Deleted标记的邮件 + */ + CONST SH_DELETED = 'DELETED'; + /** + * @var string 返回邮件中打了\Flagged标记的邮件 + */ + CONST SH_FLAGGED = 'FLAGGED'; + /** + * @var string 返回指定发件人字段的邮件 + */ + CONST SH_FROM = 'FROM'; + /** + * @var string 返回邮件消息中指定keywork的邮件 + */ + CONST SH_KEYWORD = 'KEYWORD'; + /** + * @var string 返回邮件中打了\Recent标记的邮件 + */ + CONST SH_RECENT = 'RECENT'; + /** + * @var string 返回邮件中打了\Seen标记的邮件 + */ + CONST SH_SEEN = 'SEEN'; + /** + * @var string 返回指定日期之后的邮件 + */ + CONST SH_SINCE = 'SINCE'; + /** + * @var string 返回邮件中文本指定字符串的邮件 + */ + CONST SH_TEXT = 'TEXT'; + /** + * @var string 返回指定收件人字段的邮件 + */ + CONST SH_TO = 'TO'; + /** + * @var string 返回邮件中没有打\Answered标记的邮件 + */ + CONST SH_UNANSWERED = 'UNANSWERED'; + /** + * @var string 返回邮件中没有打\Deleted标记的邮件 + */ + CONST SH_UNDELETED = 'UNDELETED'; + /** + * @var string 返回邮件中没有指定关键字的邮件 + */ + CONST SH_UNKEYWORD = 'UNKEYWORD'; + /** + * @var string 返回邮件中没有打\Seen标记的邮件 + */ + CONST SH_UNSEEN = 'UNSEEN'; + /** + * @var string 返回邮件中没有打\UNFLAGGED标记的邮件 + */ + CONST SH_UNFLAGGED = 'UNFLAGGED'; + /*--------search命令中所用参数--------*/ + + /******body中的section********/ + const TEXT = 'TEXT'; + const HEADER = 'HEADER'; + /******body中的section********/ + /** + * @var WindSocket imap邮件服务器 + */ + protected $imap = null; + protected $seperate = ' '; + protected $request = array(); + protected $resonse = array(); + + private $tag = 0; + public function __construct($host, $port) { + $this->imap = new WindSocket($host, $port); + } + + /** + * 打开一个imap连接 + * @return string + */ + public function open() { + $this->imap->open(); + return $this->response('*'); + } + + /** + * 登陆 + * @param string $username + * @param string $password + * @return string + */ + public function login($username, $password) { + return $this->communicate("LOGIN {$username} {$password}"); + } + + /** + * 创建指定名字的新邮箱。邮箱名称通常是带路径的文件夹全名。 + * @param string $folder; + * @param string + */ + public function create($folder) { + return $this->communicate("CREATE {$folder}"); + } + + /** + * 除指定名字的文件夹。文件夹名字通常是带路径的文件夹全名, + * 当邮箱被删除后,其中的邮件也不复存在。 + * @param string $folder + * @return string + */ + public function delete($folder) { + return $this->communicate("DELETE {$folder}"); + } + + /** + * RENAME命令可以修改文件夹的名称,它使用两个参数:当前邮箱名和新邮箱名, + * 两个参数的命名符合标准路径命名规则。 + * @param string $old 当前邮箱名 + * @param string $new 新邮箱名, + * @return string + */ + public function rename($old, $new) { + return $this->communicate("RENAME {$old} {$new}"); + } + + /** + * LIST命令用于列出邮箱中已有的文件夹,有点像操作系统的列目录命令 + * @param string $base 用户登陆目录 + * @param string $template 显示的邮箱名。可以使用通配符"*"。 + * @return string + */ + public function folderOfmail($base = '', $template = '*') { + return $this->communicate("LIST {$base} {$template}"); + } + + /** + * 选定某个邮箱(Folder),表示即将对该邮箱(Folder)内的邮件作操作。 + * 邮箱标志的当前状态也返回给了用户,同时返回的还有一些关于邮件和邮箱的附加信息。 + * @param string $folder + */ + public function select($folder) { + return $this->communicate("SELECT $folder"); + } + /** + * 读取邮件的文本信息,且仅用于显示的目的。 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param string $datanames + */ + public function fetch($mail, $datanames = self::ALL) { + return $this->communicate("FETCH {$mail} {$datanames}"); + } + + /** + * 读取邮件的头信息 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @return string + */ + public function fetchHeader($mail) { + return $this->communicate("FETCH {$mail} BODY[HEADER]"); + } + /** + * 读取邮件的头的字段信息,可能造成不安全,慎用 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param string $field 头字段(DATE\SUBJECT\FROM\TO\MESSAGEID\CONTENTTYPE) + * @return string + */ + public function fetchHeaderFields($mail, $field = self::DATE) { + $field = is_array($field) ? implode(' ', $field) : $field; + return $this->communicate("FETCH {$mail} BODY[HEADER.FIELDS ({$field})]"); + } + /** + * 读取邮件的头已排除字段信息 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param string $field 头字段(DATE\SUBJECT\FROM\TO\MESSAGEID\CONTENTTYPE) + * @return string + */ + public function fetchHeaderNotFields($mail, $field = self::DATE) { + $field = is_array($field) ? implode(' ', $field) : $field; + return $this->communicate("FETCH {$mail} BODY[HEADER.FIELDS.NOT ({$field})]"); + } + /** + * 读取邮件的MIME + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @return string + */ + public function fetchMime($mail) { + return $this->communicate("FETCH {$mail} BODY[MIME]"); + } + /** + * 读取邮件的Text + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @return string + */ + public function fetchText($mail) { + return $this->communicate("FETCH {$mail} BODY[TEXT]"); + } + + /** + * 返回邮件的中的某一指定部分,返回的部分用section来表示, + * section部分包含的信息通常是代表某一部分的一个数字或者是下面的某一个部分: + * HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。 + * 如果section部分是空的话,那就代表返回全部的信息,包括头信息。 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param int|string $section 返回的部分 + * @return string + */ + public function fetchBySection($mail, $section = self::TEXT) { + return $this->communicate("FETCH {$mail} BODY[$section]"); + } + + /** + * 返回邮件的中的某一指定部分,返回的部分用section来表示, + * section部分包含的信息通常是代表某一部分的一个数字或者是下面的某一个部分: + * HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。 + * 如果section部分是空的话,那就代表返回全部的信息,包括头信息。 + * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 + * @param int $start 返回的部分的开始 + * @param int $end 返回的部分的结束 + * @param int:string $section 返回的部分 + * @return string + */ + public function fetchPartialOfSection($mail, $start, $end, $section = self::TEXT) { + return $this->communicate("FETCH {$mail} BODY[$section]<{$start}.{$end}>"); + } + + /** + * 修改指定邮件的属性,包括给邮件打上已读标记、删除标记等 + * @param INT|string $mail + * @param string $flags imap中的邮件标记,值为SLIENT和FLAGS两种类型 + * @param STRING|ARRAY $attribute 标记属性(DELETED\ANSWERED\RECENT\DRAFT\FLAGGED) + * @reutrn string + */ + public function store($mail, $flags = self::FLAGS, $attribute = self::ANSWERED) { + $attribute = is_array($attribute) ? implode(' ', $attribute) : $attribute; + return $this->communicate("STORE {$mail} +" . self::FLAGS . " ($attribute)"); + } + /** + * 修改指定邮件的属性,包括给邮件打上已读标记、删除标记等 + * @param INT|string $mail + * @param string $flags imap中的邮件标记,值为SLIENT和FLAGS两种类型 + * @param STRING|ARRAY $attribute 标记属性(DELETED\ANSWERED\RECENT\DRAFT\FLAGGED) + * @reutrn string + */ + public function stripStore($mail, $flags = self::FLAGS, $attribute = self::DELETED) { + $attribute = is_array($attribute) ? implode(' ', $attribute) : $attribute; + return $this->communicate("STORE {$mail} -" . self::FLAGS . " ($attribute)"); + } + /** + * 结束对当前Folder(文件夹/邮箱)的访问, + * 关闭邮箱该邮箱中所有标志为DELETED的邮件就被从物理上删除 + */ + public function close() { + return $this->communicate("CLOSE"); + } + + /** + * 不关闭邮箱的情况下删除所有的标志为、DELETED的邮件。 + * EXPUNGE删除的邮件将不可以恢复。 + */ + public function expunge() { + return $this->communicate("EXPUNGE"); + } + /** + * 以只读方式打开邮箱 + * @param string $mailbox 邮箱 + * @return string + */ + public function examine($mailbox) { + return $this->communicate("EXAMINE $mailbox"); + } + + /** + * 在客户机的活动邮箱列表中增加一个邮箱 + * @param string $mailbox 希望添加的邮箱名。 + */ + public function subscribe($mailbox) { + return $this->communicate("SUBSCRIBE $mailbox"); + } + + /** + * 来从活动列表中去掉一个邮箱 + * @param string $mailbox 希望去掉的邮箱名。 + */ + public function unsubscribe($mailbox) { + return $this->communicate("UNSUBSCRIBE $mailbox"); + } + + /** + * 修正了LIST命令,LIST返回用户$HOME目录下所有的文件, + * 但LSUB命令只显示那些使用SUBSCRIBE命令设置为活动邮箱的文件 + * @param string $folder 邮箱路径 + * @param string $mailbox 邮箱名。 + * @return string + */ + public function lsub($folder, $mailbox) { + return $this->communicate("LSUB {$mailbox} {$mailbox}"); + } + + /** + * 查询邮箱的当前状态 + * @param string $mailbox 需要查询的邮箱名 + * @param string $params 客户机需要查询的项目列表,S_MESSAGES\S_RECENT\S_UIDNEXT\S_UIDVALIDITY\S_UNSEEN + * @return string + */ + public function status($mailbox, $params = self::S_MESSAGES) { + + $params = is_array($params) ? implode(' ', $params) : $params; + return $this->communicate("STATUS {$mailbox} ({$params})"); + } + + /** + * 在邮箱设置一个检查点,确保内存中的磁盘缓冲数据都被写到了磁盘上。 + */ + public function check() { + return $this->communicate("CHECK"); + } + + /** + * 根据搜索条件在处于活动状态的邮箱中搜索邮件,然后显示匹配的邮件编号。 + * @param string $criteria 查询条件参数,明确查询的关键字 + * @param string $value 查询条件参数,明确查询的关键字的值 + * @param string $charset 字符集标志,缺省的标志符是US-ASCⅡ + * @return string + */ + public function search($criteria = self::SH_ALL, $value = null) { + $search = $criteria; + if ($value) { + $search .= ' ' . $value; + } + return $this->communicate("SEARCH {$search}"); + } + + /** + * UID号是唯一标识邮件系统中邮件的32位证书。 + * 通常这些命令都使用顺序号来标识邮箱中的邮件, + * 使用UID可以使IMAP客户机记住不同IMAP会话中的邮件。 + */ + public function uid() { + return $this->communicate("UID"); + } + + /** + * 把邮件从一个邮箱复制到另一个邮箱 + * @param int $soruce 希望从活动邮箱中复制的邮件的标号 + * @param string $dst 望邮件被复制到的邮箱 + * @return string + */ + public function copy($soruce, $dst) { + return $this->communicate("COPY {$soruce} {$dst}"); + } + + /** + * 返回IMAP服务器支持的功能列表, + * 服务器收到客户机发送的CAPABILITY命令后将返回该服务器所支持的功能。 + */ + public function capability() { + return $this->communicate("CAPABILITY"); + } + /** + * 结束本次IMAP会话。 + */ + public function logout() { + $this->communicate("LOGOUT"); + } + + /** + * 发送imap会话请求命令 + * @param string $request + */ + public function request($request) { + $this->request[] = $request; + $this->setTag(); + return $this->imap->request($this->getTag() . ' ' . $request . self::CRLF); + } + /** + * imap会话响应请求 + * @param int $timeout + */ + public function responseLine($timeout = null) { + if (null !== $timeout) { + $this->imap->setSocketTimeOut((int) $timeout); + } + return $this->imap->responseLine(); + } + + /** + * 验证请求 + * @param boolean $multi + * @param int $timeout + * @return string + */ + public function response($endTag = '*', $timeout = null) { + $response = ''; + while ('' != ($_response = $this->responseLine($timeout))) { + list($tag, $status, $info) = explode(' ', $_response, 3); + if (in_array($status, array('NO', "BAD"))) { + throw new WindException($_response); + } + $response .= $_response; + $this->resonse[] = $_response; + if ($endTag == $tag) { + break; + } + } + if (empty($response)) throw new WindException('No response'); + return $response; + } + + /** + * 一次imap会号 + * @param string $request 请求 + * @param string $response 响应 + * @return string + */ + public function communicate($request, &$response = null) { + $this->request($request); + return $response = $this->response($this->getTag()); + } + /** + * 在imap会话中设置新标答 + */ + public function setTag() { + $this->tag++; + } + /** + * 取得imap会号中的标签 + * @return string + */ + public function getTag() { + return self::TAG . $this->tag; + } + + public function __destruct() { + if ($this->imap) { + $this->logout(); + $this->imap->close(); + $this->imap = null; + } + } + +} \ No newline at end of file diff --git a/wind/mail/protocol/WindPop3.php b/wind/mail/protocol/WindPop3.php new file mode 100644 index 00000000..6a807a87 --- /dev/null +++ b/wind/mail/protocol/WindPop3.php @@ -0,0 +1,260 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import ( 'WIND:component.mail.protocol.WindSocket' ); +/** + * pop3协议 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPop3 { + const CRLF = "\r\n"; + /** + * @var WindSocket pop3邮件服务器 + */ + protected $pop3 = null; + protected $seperate = ' '; + protected $request = array(); + protected $resonse = array(); + + public function __construct($host, $port) { + $this->pop3 = new WindSocket($host, $port); + } + + /** + * 打开pop3服务器,建立连接 + * @return string + */ + public function open() { + $this->pop3->open(); + return $this->response(); + } + + /** + * 登陆pop3 + * @param string $username 用户名 + * @param string $password 密码 + * @return string + */ + public function login($username, $password) { + $this->communicate("USER $username"); + return $this->communicate("PASS $password"); + } + + /** + * 处理请求 server 回送邮箱统计资料,如邮件数、 邮件总字节数 + * @return string + */ + public function stat() { + return $this->communicate('STAT', false, true); + } + + /** + * 处理 server 返回用于该指定邮件的唯一标识, 如果没有指定,返回所有的。 + * @param int $n 指定邮件 + * @return string + */ + public function uidl($n = null) { + $request = $n ? "UIDL $n" : 'UIDL'; + $ifmulti = $n ? false : true; + return $this->communicate($request, $ifmulti, true); + } + + /** + * 处理 server 返回指定邮件的大小等 + * @param int $n 指定邮件 + * @return string + */ + public function getList($n = null) { + $request = $n ? "LIST $n" : 'LIST'; + $ifmulti = $n ? false : true; + return $this->communicate($request, $ifmulti, true); + } + + /** + * 处处理 server 返回邮件的全部文本 + * @param int $n 指定邮件 + * @return string + */ + public function retr($n) { + return $this->communicate("RETR $n", true); + } + /** + * 处理 server 标记删除,QUIT 命令执行时才真正删除 + * @param int $n 指定邮件 + * @return string + */ + public function dele($n) { + return $this->communicate("DELE $n"); + } + /** + * 处理撤消所有的 DELE 命令 + * @return string + */ + public function rset() { + return $this->communicate("RSET"); + } + + /** + * 处理 返回 n 号邮件的前 m 行内容,m 必须是自然数 + * @param int $n 指定邮件 + * @param int $m 指定邮件前多少行 + * @return string + */ + public function top($n, $m = null) { + $request = $m ? 'TOP ' . (int) $n . ' ' . (int) $m : 'TOP ' . (int) $n; + return $this->communicate($request, true); + } + + /** + * 处理 server 返回一个肯定的响应 + * @return string + */ + public function noop() { + return $this->communicate("NOOP"); + } + + /** + * 希望结束会话。如果 server 处于"处理" 状态, + * 则现在进入"更新"状态,删除那些标记成删除的邮件。 + * 如果 server 处于"认可"状态,则结束会话时 server + * 不进入"更新"状态 。 + * @return string + */ + public function quit() { + return $this->communicate("QUIT"); + } + + /** + * 结否会话,关闭pop3服务器 + */ + public function close() { + $this->quit(); + $this->pop3->close(); + $this->pop3 = null; + } + /** + * pop3响应请求 + * @param int $timeout + */ + public function responseLine($timeout = null) { + if (null !== $timeout) { + $this->pop3->setSocketTimeOut((int) $timeout); + } + return $this->pop3->responseLine(); + } + + /** + * 外理响应内容 + * @param string $response + * @return Array + */ + public function buildResponse($response) { + if (empty($response)) { + return array(); + } + $response = explode("\n", $response); + $_response = array(); + foreach ($response as $line) { + if (empty($line)) { + continue; + } + list($key, $value) = explode($this->seperate, trim($line), 2); + $key ? $_response[(int) $key] = $value : $_response[] = $value; + } + return $_response; + } + + /** + * 进行一次网络传输通信 + * @param string $request 发竤的请求命令 + * @param boolean $ifmulti 是否返回多行响应文本,否则为一行 + * @param baoolean $ifbuild 是否对响应进行处理 + * @return array + */ + public function communicate($request, $ifmulti = false, $ifbuild = false) { + $this->request($request); + return $ifbuild ? $this->buildResponse($this->response($ifmulti)) : $this->response($ifmulti); + } + + /** + * 发送pop3命令 + * @param string $request + */ + public function request($request) { + $this->request[] = $request; + return $this->pop3->request($request . self::CRLF); + } + + /** + * 验证请求 + * @param boolean $multi + * @param int $timeout + * @return string + */ + public function response($multi = false, $timeout = null) { + $ok = $this->responseLine($timeout); + if (empty($ok) || !is_string($ok)) { + throw new WindException('Read Failed'); + } + if ('+OK' !== substr($ok, 0, 3)) { + throw new WindException('Request Failed!Pleae See Failed Info:' . $ok); + } + if (true === $multi) { + $response = ''; + while ('' != ($_response = $this->responseLine($timeout))) { + if ('.' === trim($_response)) { + break; + } + $response .= $_response; + $this->resonse[] = $_response; + } + } else { + $this->resonse[] = $ok; + if (strpos($ok, $this->seperate)) { + list(, $response) = explode($this->seperate, $ok, 2); + } else { + $response = $ok; + } + } + if(empty($response)) throw new WindException('No response'); + return $response; + } + + /** + * 获取解析后的内容 + * @param $content + * @param $sep + */ + public function getMailContent($content,$sep = "\n\n"){ + $content = explode($sep,$content); + $content[0] = explode("\n",$content[0]); + $headers = array(); + foreach($content[0] as $value){ + $_value = explode(':',$value); + $headers[$_value[0]] = trim($_value[1]); + } + $encode = $headers['Content-Transfer-Encoding']; + if('base64' == $encode){ + $content = base64_decode($content[1]); + }else{ + $content = $content[1]; + } + return array($headers,$content); + } + + public function __destruct() { + if ($this->pop3) { + $this->close(); + } + } + +} +?> \ No newline at end of file diff --git a/wind/mail/protocol/WindSmtp.php b/wind/mail/protocol/WindSmtp.php new file mode 100644 index 00000000..895387b8 --- /dev/null +++ b/wind/mail/protocol/WindSmtp.php @@ -0,0 +1,211 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import ( 'WIND:component.mail.protocol.WindSocket' ); +/** + * 邮件传输协议操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSmtp { + const CRLF = "\r\n"; + /** + * @var WindSocket + */ + protected $smtp = null; + protected $request = array(); + protected $resonse = array(); + + public function __construct($host, $port,$timeout = 60) { + $this->smtp = new WindSocket($host, $port ,$timeout); + } + + /** + * 打开smtp服务器,建立连接 + * @return string + */ + public function open() { + $this->smtp->open(); + return $this->checkResponse(220); + } + + /** + * 向服务器标识用户身份 + * @param string $host 身份 + * @return string + */ + public function ehlo($host) { + $this->request('EHLO ' . $host); + return $this->checkResponse(250); + } + + /** + * 进行用户身份认证 + * @param string $username 用户名 + * @param string $password 密码 + * @return string + */ + public function authLogin($username, $password) { + $this->request('AUTH LOGIN'); + $this->checkResponse(array(334)); + $this->request(base64_encode($username)); + $this->checkResponse(array(334)); + $this->request(base64_encode($password)); + return $this->checkResponse(array(235)); + } + + /** + * 指定的地址是发件人地址 + * @param string $from 邮件发送者 + * @return string + */ + public function mailFrom($from) { + $this->request('MAIL FROM:' . '<' . $from . '>'); + return $this->checkResponse(250); + } + /** + * 指定的地址是收件人地址 + * @param string $to 邮件发送者 + * @return string + */ + public function rcptTo($to) { + $this->request('RCPT TO:' . '<' . $to . '>'); + return $this->checkResponse(array(250, 251)); + } + + /** + * 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令 + * @param string $user + * @return string + */ + public function very($user) { + $this->request('VRFY ' . $user); + return $this->checkResponse(array(250, 251, 252)); + } + /** + * 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用 + * @param string $name + * @return string + */ + public function expn($name) { + $this->request('EXPN ' . $name); + $response = $this->checkResponse(250); + $entries = explode(self::CRLF, $response); + while (list(, $l) = each($entries)) { + $list[] = substr($l, 4); + } + return $list; + } + + /** + * 无操作,服务器应响应 OK + * @return string + */ + public function noop() { + $this->request('NOOP'); + return $this->checkResponse(250); + } + + /** + * 在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以 CRLF.CRLF 结束 + * @param string $data 发送的数据 + * @return string + */ + public function data($data) { + $this->request('DATA'); + $this->checkResponse(354); + $data = str_replace("\r\n", "\n", $data); + $data = str_replace("\r", "\n", $data); + $lines = explode("\n", $data); + foreach ($lines as $line) { + if (0 === strpos($line, '.')) { + $line = '.' . $line; + } + $this->request($line); + } + $this->request('.'); + return $this->checkResponse(250); + } + /** + * 重置会话,当前传输被取消 + * @return string + */ + public function rset() { + $this->request('RSET'); + return $this->checkResponse(array(250, 220)); + } + /** + * 结束会话 + * @return string + */ + public function quit() { + $this->request('QUIT'); + return $this->checkResponse(221); + } + + /** + * 关闭smtp服务器 + */ + public function close() { + $this->smtp->close(); + $this->smtp = null; + } + + /** + * smtp响应请求 + * @param int $timeout + */ + public function responseLine($timeout = null) { + if (null !== $timeout) { + $this->smtp->setSocketTimeOut((int) $timeout); + } + return $this->smtp->responseLine(); + } + + /** + * 发送smtp命令 + * @param string $request + */ + public function request($request) { + $this->request[] = $request.self::CRLF; + return $this->smtp->request($request . self::CRLF); + } + + /** + * 验证请求 + * @param string $expect + * @param int $timeout + * @return string + */ + public function checkResponse($expect, $timeout = null) { + $response = ''; + $expect = is_array($expect) ? $expect : array($expect); + while ('' != ($_response = $this->responseLine($timeout))) { + $response .= $_response; + $this->resonse[] = $_response; + list($code, $info) = preg_split('/([\s-]+)/', $_response, 2); + if(null === $code || !in_array($code, $expect)) throw new WindException($info); + if (" " == substr($_response, 3, 1)) { + break; + } + } + if(empty($response)) throw new WindException('No response'); + return $response; + } + + + + public function __destruct() { + if ($this->smtp) { + $this->close(); + } + } + +} \ No newline at end of file diff --git a/wind/mail/protocol/WindSocket.php b/wind/mail/protocol/WindSocket.php new file mode 100644 index 00000000..c54a09af --- /dev/null +++ b/wind/mail/protocol/WindSocket.php @@ -0,0 +1,121 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ + +/** + * socket套接字操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSocket { + + protected $host = '127.0.0.1'; + protected $port = 80; + protected $timeout = 5; + protected $errno = 0; + protected $errstr = ''; + protected $socket = null; + + public function __construct($host = '127.0.0.1', $port = 80, $timeout = 5) { + $this->setHost($host); + $this->setPort($port); + $this->setTimeout($timeout); + } + + /** + * 打开一个连接 + */ + public function open() { + if (null == $this->socket) { + $this->socket = fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout); + } + } + + /** + * 发送请求 + * @param string $request + */ + public function request($request) { + return fputs($this->socket, $request); + } + + /** + * 响应请求 + * @return string + */ + public function response() { + $response = ''; + while (!feof($this->socket)) { + $response .= fgets($this->socket); + } + return $response; + } + + /** + * 响应请求,只返回一行 + * @return string + */ + public function responseLine() { + return feof($this->socket) ? '' : fgets($this->socket); + } + + /** + *关闭连接 + */ + public function close() { + if ($this->socket) { + fclose($this->socket); + $this->socket = null; + } + return true; + } + /** + * 获取请求中的错误 + * @return string + */ + public function getError() { + return $this->errstr ? $this->errno . ':' . $this->errstr : ''; + } + + /** + * 取得socket操作对象 + * @return resource + */ + public function getSocket(){ + return $this->socket; + } + + /** + * 设置主机 + * @param string $host + */ + public function setHost($host) { + $this->host = $host; + + } + /** + * 设置端口 + * @param string $port + */ + public function setPort($port) { + $this->port = $port; + } + /** + * 设置超时 + * @param int $timeout + */ + public function setTimeout($timeout) { + $this->timeout = $timeout; + } + + public function setSocketTimeOut($timeout) { + return stream_set_timeout($this->socket, $timeout); + } +} \ No newline at end of file diff --git a/wind/mail/sender/IWindSendMail.php b/wind/mail/sender/IWindSendMail.php new file mode 100644 index 00000000..2ca37f43 --- /dev/null +++ b/wind/mail/sender/IWindSendMail.php @@ -0,0 +1,15 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +interface IWindSendMail{ + /** + * 发送邮件 + * @param WindMail $mail 邮件消息封装对象 + */ + public function send(WindMail $mail); +} \ No newline at end of file diff --git a/wind/mail/sender/WindPhpMail.php b/wind/mail/sender/WindPhpMail.php new file mode 100644 index 00000000..04f69ade --- /dev/null +++ b/wind/mail/sender/WindPhpMail.php @@ -0,0 +1,34 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.mail.sender.IWindSendMail'); +/** + * 使用php内部函数发送邮件 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPhpMail implements IWindSendMail{ + + public function send(WindMail $mail){ + $recipients = $mail->getRecipients(); + $to = $this->getToAsString($recipients); + return mail($to,$mail->getSubject(),$mail->createBody(),$mail->createHeader()); + } + + public function getToAsString($recipients = array()){ + $to = ''; + foreach($recipients as $key=>$value){ + $_value = is_string($key) ? $key.' '.$_value : $_value; + $to .= $to ? ', '.$_value : $_value; + } + return $to; + + } +} \ No newline at end of file diff --git a/wind/mail/sender/WindSendMail.php b/wind/mail/sender/WindSendMail.php new file mode 100644 index 00000000..e6f98882 --- /dev/null +++ b/wind/mail/sender/WindSendMail.php @@ -0,0 +1,85 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.mail.sender.IWindSendMail'); +/** + * 使用sendmail发送邮件 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSendMail implements IWindSendMail{ + /** + * @var string sendmail命令路径 + */ + private $sendMail = '/usr/sbin/sendmail'; + /** + * @var string 发送者 + */ + private $sender = ''; + /** + * @var string 工作进程 + */ + private $process = null; + /** + * @param string $sendMail 工作进程 + * @param string $sender 发送者 + */ + public function __construct(array $config=null){ + if(isset($config['sendMail'])){ + $this->sendMail = $config['sendMail']; + } + if(isset($config['sender'])){ + $this->sender = $config['sender']; + } + } + /** + * 发送邮件 + * @param WindMail $mail mail信息封装对象 + * @return string + */ + public function send(WindMail $mail) { + $this->open(); + $this->transData($mail->createHeader()); + $this->transData($mail->createBody()); + return $this->close() ? false : true; + } + /** + * 开启一个sendmail进进程 + */ + public function open(){ + if($this->sender){ + $mailCmd = sprintf("%s -oi -f %s -t", escapeshellcmd($this->sendMail), escapeshellarg($this->sender)); + }else{ + $mailCmd = sprintf("%s -oi -t", escapeshellcmd($this->sendMail)); + } + $this->process = popen($mailCmd, 'w'); + } + + /** + * 传输数据 + * @param string $data 数据 + */ + public function transData($data){ + fputs($this->process,$data); + } + + + /** + * 关闭一个进程 + * @return number + */ + public function close(){ + return pclose($this->process); + } + + public function __destruct(){ + $this->process = null; + } +} \ No newline at end of file diff --git a/wind/mail/sender/WindSmtpMail.php b/wind/mail/sender/WindSmtpMail.php new file mode 100644 index 00000000..d645702d --- /dev/null +++ b/wind/mail/sender/WindSmtpMail.php @@ -0,0 +1,92 @@ + + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +Wind::import('WIND:component.mail.sender.IWindSendMail'); +Wind::import ( 'WIND:component.mail.protocol.WindSmtp' ); +/** + * 邮件发送 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSmtpMail implements IWindSendMail{ + /** + * @var WindSmtp 邮件发送服务器 + */ + protected $smtp = null; + /** + * @var boolean 是否启用验证 + */ + protected $auth = true; + /** + * @var string 邮件主机名 + */ + protected $name = 'localhost'; + /** + * @var string 邮件用户名 + */ + protected $username = ''; + /** + * @var string 邮件密码 + */ + protected $password = ''; + + public function __construct(array $config){ + $defautConfig = array('host'=>'127.0.0.1','port'=>'25','name'=>'localhost','auth'=>true); + $config = array_merge($defautConfig,$config); + if(!isset($config['host']) || !isset($config['port'])){ + throw new WindException('The mail host or port is not exist'); + } + if($config['auth'] && (!isset($config['user']) || !isset($config['password']))){ + throw new WindException('In the verification mode, the user name and password is blank or wrong'); + } + $this->auth = $config['auth']; + $this->name = $config['name']; + $this->smtp = new WindSmtp($config['host'],$config['port']); + $this->smtp->open(); + $this->setAuthParams($config['user'],$config['password']); + } + + /** + * 发送邮件 + * @param WindMail $mail 邮件消息封装对象 + */ + public function send(WindMail $mail){ + $this->smtp->ehlo($this->name); + if($this->auth){ + $this->smtp->authLogin($this->username,$this->password); + } + $this->smtp->mailFrom($mail->getFrom()); + foreach($mail->getRecipients() as $rcpt){ + $this->smtp->rcptTo($rcpt); + } + $header = $mail->createHeader(); + $body = $mail->createBody(); + $data = $header.$body; + $this->smtp->data($header.$body); + $this->smtp->quit(); + } + + /** + * 设置验证参数 + * @param string $username 用户名 + * @param string $password 密码 + */ + public function setAuthParams($username,$password){ + $this->username = $username; + $this->password = $password; + } + + + + public function __destruct(){ + $this->smtp->close(); + $this->smtp = null; + } +} \ No newline at end of file diff --git a/wind/parser/IWindConfigParser.php b/wind/parser/IWindConfigParser.php new file mode 100644 index 00000000..0695ad50 --- /dev/null +++ b/wind/parser/IWindConfigParser.php @@ -0,0 +1,27 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindConfigParser { + + /** + * 解析文件,保存缓存,返回解析结果 + * + * 1、缺省的配置文件,采用XML格式解析返回 + * 2、如果输入的配置文件格式没有提供支持,则抛出异常 + * 3、根据格式进行解析 + * 4、参数三$isApp 用来配置该解析式组件格式的解析还是应用配置的解析, + * 如果是应用解析需要进行merge操作,如果是组件解析则不用 + * + * @param string $name 解析后保存的文件名字 + * @param string $configPath 待解析文件的绝对路径 + * @param string $append 追加的文件 + * @param AbstractWindCache $cache 缓存策略 + * @return array 解析成功返回的数据 + */ + public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); + +} \ No newline at end of file diff --git a/wind/parser/WindConfigParser.php b/wind/parser/WindConfigParser.php new file mode 100644 index 00000000..624dae50 --- /dev/null +++ b/wind/parser/WindConfigParser.php @@ -0,0 +1,129 @@ + + * @author xiaoxia xu + * @version $Id$ + * @package + */ +class WindConfigParser implements IWindConfigParser { + /** + * 配置文件支持的格式白名单 + */ + const CONFIG_XML = '.XML'; + const CONFIG_PHP = '.PHP'; + const CONFIG_INI = '.INI'; + const CONFIG_PROPERTIES = '.PROPERTIES'; + + /** + * 配置解析对象队列 + * @var array object $configParser + */ + private $configParsers = array(); + + /** + * 解析组件的配置文件 + * + * 如果用户没有传入别名,则每次都执行解析 + * 如果用户传入别名,判断是否传入了追加的文件名 + * 如果传入了追加的文件名,则判断该文件的内容中是否存在以别名为key的值 + * 如果有该值则返回该值,否则继续 + * 如果没有传入追加的文件名,则判断该别名命名的缓存文件是否存在 + * 如果存在则返回该文件内容,否则继续 + * 如果没有传入别名,则继续 + * + * 如果该缓存文件不存在,则判断如果不是以追加的方式,并且已经存在该缓存文件,则返回该缓存文件 + * 如果都不存在,则执行解析,并根据是否追加的条件,进行追加或是新建。 + * + * @param string $configPath 待解析的文件路径 + * @param string $alias 解析后保存的key名 + * @param string $append 追加的文件 + * @param AbstractWindCache $cache 缓存策略 + * @return array 解析结果 + */ + public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { + if ($config = $this->getCache($alias, $append, $cache)) return $config; + $config = $this->doParser($configPath); + $this->setCache($alias, $append, $cache, $config); + return $config; + } + + /** + * 设置配置缓存 + * @param string $alias + * @param string $append + * @param AbstractWindCache $cache + */ + private function setCache($alias, $append, $cache, $data) { + if (!$alias || !$cache) return; + if ($append) { + $_config = (array) $cache->get($append); + $_config[$alias] = $data; + $cache->set($append, $_config); + } else { + $cache->set($alias, $data); + } + } + + /** + * 返回配置缓存 + * @param string alias + * @param string append + * @param AbstractWindCache cache + * @return array + */ + private function getCache($alias, $append, $cache) { + if (!$alias || !$cache) return array(); + if (!$append) return $cache->get($alias); + + $config = $cache->get($append); + return isset($config[$alias]) ? $config[$alias] : array(); + } + + /** + * 创建配置文件解析器 + * + * @access private + */ + private function createParser($type) { + switch ($type) { + case self::CONFIG_XML: + Wind::import("WIND:component.parser.WindXmlParser"); + return new WindXmlParser(); + break; + case self::CONFIG_INI: + Wind::import("WIND:component.parser.WindIniParser"); + return new WindIniParser(); + break; + case self::CONFIG_PROPERTIES: + Wind::import("WIND:component.parser.WindPropertiesParser"); + return new WindPropertiesParser(); + break; + default: + throw new WindException('\'ConfigParser\' failed to initialize.'); + break; + } + } + + /** + * 执行解析并返回解析结果 + * 接收一个配置文件路径,根据路径信息初始化配置解析器,并解析该配置 + * 以数组格式返回配置解析结果 + * + * @param string $configFile 解析的文件路径 + * @return array 返回解析结果 + */ + private function doParser($configFile) { + if (!is_file($configFile)) throw new WindException( + '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); + $ext = strtoupper(strrchr($configFile, '.')); + if ($ext == self::CONFIG_PHP) return @include ($configFile); + if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); + return $this->configParsers[$ext]->parse($configFile); + } +} \ No newline at end of file diff --git a/wind/parser/WindIniParser.php b/wind/parser/WindIniParser.php new file mode 100644 index 00000000..c9a8974d --- /dev/null +++ b/wind/parser/WindIniParser.php @@ -0,0 +1,147 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * ini 格式文件解析 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindIniParser { + + /** + * @var string 分割数组标识 + */ + protected $separator = '.'; + + /** + * 解析数据 + * @param string $filename ini格式文件 + * @param boolean $process 处理指令 + * @param boolean $build 是否按指定格式返回 + * @return boolean + */ + public function parse($filename, $process = true, $build = true) { + if (!is_file($filename)) { + return array(); + } + $data = parse_ini_file($filename, $process); + return $build ? $this->buildData($data) : $data; + } + + /** + * 构建数据 + * @param array $data + * @return array + */ + public function buildData(&$data) { + foreach ((array)$data as $key => $value) { + if (is_array($value)) { + $data[$key] = $this->formatDataArray($value); + } else { + $this->formatDataFromString($key, $value, $data); + } + } + return $data; + } + + /** + * 将每行ini文件转换成数组 + * @param string $key ini文件中的键 + * @param string $value ini文件中的值 + * @param array $data + * @return array + */ + public function toArray($key, $value, &$data = array()) { + if (empty($key) && empty($value)) return array(); + if (strpos($key, $this->separator)) { + $start = substr($key, 0, strpos($key, $this->separator)); + $end = substr($key, strpos($key, $this->separator) + 1); + $data[$start] = array(); + $this->toArray($end, $value, $data[$start]); + } else { + $data[$key] = $value; + } + return $data; + } + + /** + * 解析ini格式文件成数组 + * @param array $original 原始数组 + * @param array $data 解析后的数组 + * @return array + */ + public function formatDataArray(&$original, &$data = array()) { + foreach ((array)$original as $key => $value) { + $tmp = $this->toArray($key, $value); + foreach ($tmp as $tkey => $tValue) { + if (is_array($tValue)) { + if (!isset($data[$tkey])) { + $data[$tkey] = array(); + } + $this->formatDataArray($tValue, $data[$tkey]); + } else { + $data[$tkey] = $tValue; + } + } + } + return $data; + } + + /** + * 从字符串中合并数组 + * @param string $key + * @param string $value + * @param array $data + * return array + */ + public function formatDataFromString($key, $value, &$data) { + $tmp = $this->toArray($key, $value); + if(false == strpos($key, $this->separator)){ + return $tmp; + } + $start = substr($key, 0, strpos($key, $this->separator)); + if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { + $data[$start] = $tmp[$start]; + } else { + foreach ($data as $d_key => $d_value) { + if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { + continue; + } + foreach ($tmp[$d_key] as $a => $b) { + $this->merge($a, $b, $data[$start]); + } + } + } + unset($data[$key]); + return $data; + } + + /** + * 合并格式化的数组 + * @param string $key + * @param mixed $value + * @param array $data + * @return array + */ + private function merge($key, $value, &$data = array()) { + if (is_array($value)) { + $v_key = array_keys($value); + $c_key = $v_key[0]; + if (is_array($value[$c_key])) { + $this->merge($c_key, $value[$c_key], $data[$key]); + } else { + $data[$key][$c_key] = $value[$c_key]; + } + } else { + $data[$key] = $value; + } + return $data; + } +} \ No newline at end of file diff --git a/wind/parser/WindPropertiesParser.php b/wind/parser/WindPropertiesParser.php new file mode 100644 index 00000000..074119c6 --- /dev/null +++ b/wind/parser/WindPropertiesParser.php @@ -0,0 +1,214 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * properties格式文件解析 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPropertiesParser { + + const COMMENT = '#'; + const LPROCESS = '['; + const RPROCESS = ']'; + private $separator = '.'; + + public function __construct() { + + } + + /** + * 解析properties文件里的内容 + * @param string $filename 文件名 + * @param boolean $process 是否处理指令 + * @param boolean $build 是否按格式解析数据 + * @return array + */ + public function parse($filename, $process = true, $build = true) { + $data = $this->parse_properties_file($filename, $process); + return $build ? $this->buildData($data) : $data; + } + + private function delComment($filename, $process) { + + } + + /** + * 载入一个由 filename 指定的 properties 文件, + * 并将其中的设置作为一个联合数组返回。 + * 如果将最后的 process参数设为 TRUE, + * 将得到一个多维数组,包括了配置文件中每一节的名称和设置。 + * process_sections 的默认值是 true。 + * @param string $filename 文件名 + * @param unknown_type $process 是否处理指令 + * @return array + */ + public function parse_properties_file($filename, $process = true) { + if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { + return array(); + } + $fp = fopen($filename, 'r'); + $content = fread($fp, filesize($filename)); + fclose($fp); + $content = explode("\n", $content); + $data = array(); + $last_process = $current_process = ''; + foreach ($content as $key => $value) { + $value = str_replace(array("\n", "\r"), '', trim($value)); + if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { + continue; + } + $tmp = explode('=', $value, 2); + if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { + if ($process) { + $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); + $data[$current_process] = array(); + $last_process = $current_process; + } + continue; + } + $tmp[0] = trim($tmp[0]); + $tmp[1] = trim($tmp[1], '\'"'); + + if ($last_process) { + count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; + } else { + count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; + } + } + return $data; + + } + + /** + * 解析数据 + * @param array $data + * @return array + */ + public function buildData(&$data) { + foreach ((array)$data as $key => $value) { + if (is_array($value)) { + $data[$key] = $this->formatDataArray($value); + } else { + $this->formatDataFromString($key, $value, $data); + } + } + return $data; + } + + /** + * 将proterties文件每行转换成数组 + * @param string $key ini文件中的键 + * @param string $value ini文件中的值 + * @param array $data + * @return array + */ + public function toArray($key, $value, &$data = array()) { + if (empty($key) && empty($value)) return array(); + if (strpos($key, $this->separator)) { + $start = substr($key, 0, strpos($key, $this->separator)); + $end = substr($key, strpos($key, $this->separator) + 1); + $data[$start] = array(); + $this->toArray($end, $value, $data[$start]); + } else { + $data[$key] = $value; + } + return $data; + } + + /** + * 将原始数组合并成新的数组 + * @param array $original 原始数组 + * @param array $data 合并后的数组 + * @return array + */ + public function formatDataArray(&$original, &$data = array()) { + foreach ((array)$original as $key => $value) { + $tmp = $this->toArray($key, $value); + foreach ($tmp as $tkey => $tValue) { + if (is_array($tValue)) { + if (!isset($data[$tkey])) { + $data[$tkey] = array(); + } + $this->formatDataArray($tValue, $data[$tkey]); + } else { + $data[$tkey] = $tValue; + } + } + } + return $data; + } + + /** + * 从字符串中合并数组 + * @param string $key + * @param string $value + * @param array $data + * return array + */ + public function formatDataFromString($key, $value, &$data) { + $tmp = $this->toArray($key, $value); + if(false == strpos($key, $this->separator)){ + return $tmp; + } + $start = substr($key, 0, strpos($key, $this->separator)); + if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { + $data[$start] = $tmp[$start]; + } else { + foreach ($data as $d_key => $d_value) { + if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { + continue; + } + foreach ($tmp[$d_key] as $a => $b) { + $this->merge($a, $b, $data[$start]); + } + } + } + unset($data[$key]); + return $data; + } + + /** + * 合并格式化的数组 + * @param string $key + * @param mixed $value + * @param array $data + * @return array + */ + private function merge($key, $value, &$data = array()) { + if (is_array($value)) { + $v_key = array_keys($value); + $c_key = $v_key[0]; + if (is_array($value[$c_key])) { + $this->merge($c_key, $value[$c_key], $data[$key]); + } else { + $data[$key][$c_key] = $value[$c_key]; + } + } else { + $data[$key] = $value; + } + return $data; + } + + /** + * 去除字符串头和尾中指定字符 + * @param string $str + * @param mixed $char + * @return string + */ + private function trimChar($str, $char = ' ') { + $char = is_array($char) ? $char : array($char); + foreach ($char as $value) { + $str = trim($str, $value); + } + return $str; + } + +} \ No newline at end of file diff --git a/wind/parser/WindXmlParser.php b/wind/parser/WindXmlParser.php new file mode 100644 index 00000000..cee4d7a6 --- /dev/null +++ b/wind/parser/WindXmlParser.php @@ -0,0 +1,109 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * xml文件解析 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindXmlParser { + + /** + * @var string 节点名称 + */ + const NAME = 'name'; + + /** + * @var Domdocument DOM解析器 + */ + private $dom = null; + + /** + * @param string $version xml版本 + * @param string $encode xml编码 + */ + public function __construct($version = '1.0', $encode = 'utf-8') { + if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); + $this->dom = new DOMDocument($version, $encode); + } + + /** + * @param string $filename xml 文件名 + * @param int $option 解析选项 + * @return array + */ + public function parse($filename, $option = null) { + if (!is_file($filename)) return array(); + $this->dom->load($filename, $option); + return $this->getChilds($this->dom->documentElement); + } + + /** + * 获得节点的所有子节点 + * + * 子节点包括属性和子节点(及文本节点), + * 子节点的属性将会根据作为该节点的一个属性元素存放,如果该子节点中含有标签列表,则会进行一次合并。 + * 每个被合并的列表项都作为一个单独的数组元素存在。 + * + * @param DOMElement $node 要解析的XMLDOM节点 + * @return array 返回解析后该节点的数组 + */ + public function getChilds($node) { + if (!$node instanceof DOMElement) return array(); + $childs = array(); + foreach ($node->childNodes as $node) { + $tempChilds = $attributes = array(); + ($node->hasAttributes()) && $attributes = $this->getAttributes($node); + if (3 == $node->nodeType) { + $value = trim($node->nodeValue); + (is_numeric($value) || $value) && $childs[0] = $value;//值为0的情况 + } + if (1 !== $node->nodeType) continue; + + $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; + $tempChilds = $this->getChilds($node); + $tempChilds = array_merge($attributes, $tempChilds); + if (empty($tempChilds)) $tempChilds = ''; + + $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; + if (!isset($childs[$nodeName])) { + $childs[$nodeName] = $tempChilds; + continue; + } else { + $element = $childs[$nodeName]; + $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( + $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); + continue; + } + } + return $childs; + } + + /** + * 获得节点的属性 + * + * 该属性将不包含属性为name的值--规则(name的值将作为解析后数组的key值索引存在) + * + * @param DOMElement $node + * @return array 返回属性数组 + */ + public function getAttributes($node) { + if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); + $attributes = array(); + foreach ($node->attributes as $attribute) { + if (self::NAME != $attribute->nodeName) { + $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; + } + } + return $attributes; + } +} +?> diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php new file mode 100644 index 00000000..536b8458 --- /dev/null +++ b/wind/router/AbstractWindRouter.php @@ -0,0 +1,170 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindRouter extends WindHandlerInterceptorChain { + protected $moduleKey = 'm'; + protected $controllerKey = 'c'; + protected $actionKey = 'a'; + protected $module; + protected $controller = 'index'; + protected $action = 'run'; + + protected $currentRoute = null; + + /** + * 解析请求参数,并返回路由结果 + * @return string + */ + abstract public function route(); + + /** + * 创建Url,并返回 + * @return string + */ + abstract public function assemble(); + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + if ($this->_config) { + $this->module = $this->getConfig('module', 'default-value', $this->module); + $this->controller = $this->getConfig('controller', 'default-value', $this->controller); + $this->action = $this->getConfig('action', 'default-value', $this->action); + $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); + $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); + $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); + } + } + + /** + * 设置路由变量信息 + * + * @param string $params + */ + protected function setParams($params) { + foreach ($params as $key => $value) { + if ($this->actionKey === $key) + $this->setAction($value); + elseif ($this->controllerKey === $key) + $this->setController($value); + elseif ($this->moduleKey === $key) + $this->setModule($value); + else { + $this->getRequest()->setAttribute($value, $key); + } + } + } + + /** + * 添加路由协议对象,如果添加的路由协议已经存在则抛出异常 + * @param Object $routeInstance + * @throws WindException + * @return + */ + public function addRoute($routeInstance, $current = false) { + if ($current) + $this->currentRoute = $routeInstance; + $this->addInterceptors($routeInstance); + } + + /** + * 获得业务操作 + * @return string + */ + public function getAction() { + return $this->action; + } + + /** + * 获得业务对象 + * @return string + */ + public function getController() { + return $this->controller; + } + + /** + * 设置action信息 + * @param string $action + * @return + */ + public function setAction($action) { + $this->action = $action; + } + + /** + * 设置controller信息 + * @param string $controller + * @return + */ + public function setController($controller) { + $this->controller = $controller; + } + + /** + * @return the $module + */ + public function getModule() { + return $this->module; + } + + /** + * @param string $module + */ + public function setModule($module) { + $this->module = $module; + } + + /** + * @return the $moduleKey + */ + public function getModuleKey() { + return $this->moduleKey; + } + + /** + * @return the $controllerKey + */ + public function getControllerKey() { + return $this->controllerKey; + } + + /** + * @return the $actionKey + */ + public function getActionKey() { + return $this->actionKey; + } + + /** + * @param field_type $moduleKey + */ + public function setModuleKey($moduleKey) { + $this->moduleKey = $moduleKey; + } + + /** + * @param field_type $controllerKey + */ + public function setControllerKey($controllerKey) { + $this->controllerKey = $controllerKey; + } + + /** + * @param field_type $actionKey + */ + public function setActionKey($actionKey) { + $this->actionKey = $actionKey; + } + +} \ No newline at end of file diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php new file mode 100644 index 00000000..11c5dfa7 --- /dev/null +++ b/wind/router/WindRouter.php @@ -0,0 +1,40 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindRouter extends AbstractWindRouter { + + /* (non-PHPdoc) + * @see IWindRouter::route() + */ + public function route() { + $this->setCallBack(array($this, 'defaultRoute')); + $params = $this->getHandler()->handle(); + $this->setParams($params); + } + + /* (non-PHPdoc) + * @see AbstractWindRouter::assemble() + */ + public function assemble() { + // TODO Auto-generated method stub + } + + /** + * 默认路由规则 + */ + public function defaultRoute() { + $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); + $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, + $this->controller); + $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); + return $params; + } + +} + +?> \ No newline at end of file diff --git a/wind/router/WindUrlRewriteRouter.php b/wind/router/WindUrlRewriteRouter.php new file mode 100644 index 00000000..6481a873 --- /dev/null +++ b/wind/router/WindUrlRewriteRouter.php @@ -0,0 +1,346 @@ + + * @author xiaoxiao + * @version 2011-8-12 xiaoxiao + */ +class WindUrlRewriteRouter extends AbstractWindRouter { + private $urlPatttern = ''; + private $keyValueSep = ''; + private $separator = ''; + private $suffix = ''; + private $isRewrite = 0; + private $keyPrefix = ''; + private $baseUrl = ''; + private $patterns = array(); + + /** + * 是否开启重写 + * + * @return boolean + */ + public function isRewrite() { + return $this->isRewrite == '1' || $this->isRewrite == 'true'; + } + + /* + * (non-PHPdoc) + * @see AbstractWindRouter::parse() + */ + public function parse() { + $this->isRewrite() && $this->parseUrl(); + $this->setModule($this->getUrlParamValue('module', $this->getModule())); + $this->setController($this->getUrlParamValue('controller', $this->getController())); + $this->setAction($this->getUrlParamValue('action', $this->getAction())); + } + + /** + * 解析Url + * + * 没有配置解析规则,直接返回 + * 获得则匹配RequestUri,根据用户的配置分隔符分割信息 + * 同时设置到超全局变量$_GET中 + */ + public function parseUrl() { + if (!$this->isRewrite()) + return; + $url = array(); + if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { //http协议 + $pathInfo = $this->getRequest()->getServer('PATH_INFO'); + if ($pathInfo && !empty($pathInfo)) { + $url = rtrim($pathInfo, $this->suffix); + } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { + $scriptName = $this->getRequest()->getScriptUrl(); + if (0 === strpos($url, $scriptName)) { + $url = substr($url, strlen($scriptName)); + } + $url = rtrim($url, $this->suffix); + } + $url = trim($url, '?/'); + $url && $params = $this->doParserUrl($url); + } else { // 命令行下 + $i = 0; + $args = $this->getRequest()->getServer('argv', array()); + while (isset($args[$i]) && isset($args[$i + 1])) { + $params[$args[$i]] = $args[$i + 1]; + $i += 2; + } + } + foreach ($params as $k => $v) { + !isset($_GET[$k]) && $_GET[$k] = $v; + } + } + + /** + * 构造返回Url地址 + * + * 将根据是否开启url重写来分别构造相对应的url + * + * @param string $action 执行的操作 + * @param string $controller 执行的controller + * @param array $params 附带的参数 + * @return string + */ + public function buildUrl($action = '', $controller = '', $params = array()) { + list($module, $controller, $action) = $this->resolveMvc($action, $controller); + $m = $this->getConfig('module', 'url-param'); + $c = $this->getConfig('controller', 'url-param'); + $a = $this->getConfig('action', 'url-param'); + $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); + return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( + $params, '', '&'); + } + + /** + * 解析module, controller, action + * 如果不存在该值,则采用配置的默认值 + * + * @param AbstractWindRouter $urlRouter + * @param string $action + * @param string $controller + * @return array + */ + private function resolveMvc($action, $controller) { + list($controller, $module) = WindHelper::resolveController($controller); + !$module && $module = $this->getConfig('module', 'default-value'); + !$controller && $controller = $this->getConfig('controller', 'default-value'); + !$action && $action = $this->getConfig('action', 'default-value'); + return array($module, $controller, $action); + } + + /** + * 构造重写的url + * @param string $m + * @param string $c + * @param string $action + * @param string $params + * @return string + */ + private function buildRewriteUrl($params) { + $url = $this->urlPatttern; + foreach ($this->patterns as $key => $value) { + if ('*' == $value[0]) { + $url = str_replace($value, $this->buildNomalKeys($params), $url); + } else { + $url = $this->buildVars($value, $params, $url); + } + } + return $this->baseUrl . '/' . $url . $this->suffix; + } + + /** + * 构建变量 不是* + * + * @param string $value + * @param array $params + * @param string $url + * @return string + */ + private function buildVars($value, &$params, $url) { + $keys = explode($this->keyValueSep, $value); + $values = array(); + foreach ($keys as $v) { + if (!isset($params[$v])) + continue; + $values[] = $params[$v]; + unset($params[$v]); + } + return str_replace($keys, $values, $url); + } + + /** + * 构建rewriteurl的参数部分 + * @param array $params + * @param string $parentKey + * @param boolean $first 只有第一级的变量才加前缀 + * @return string + */ + private function buildNomalKeys($params, $parentKey = '', $first = true) { + $tmp = array(); + foreach ($params as $k => $v) { + if (is_int($k) && $this->keyPrefix != null && $first) { + $k = urlencode($this->keyPrefix . $k); + } + if (!empty($parentKey)) + $k = $parentKey . '[' . $k . ']'; + if (is_array($v)) { + array_push($tmp, $this->buildNomalKeys($v, $k, false)); + } else { + array_push($tmp, $k . $this->keyValueSep . urlencode($v)); + } + } + return implode($this->separator, $tmp); + } + + /** + * 执行匹配 + * patterns中的匹配模式去匹配url中的信息 + * urlPatterns中可以根据需求将mca进行组合配置。 + * + * + htm + / + - + myvar_ + 1 + + * url-pattern中:*匹配表示其他的变量信息 + * 用户也可以将自己的其他信息添加到格式中比如m/c-a/tid/* + * suffix : url的后缀 + * separator: 变量分隔符 + * key-value-sep: key和value的分隔符,默认和separator一致 + * key-prefix: 数字索引的前缀 + * is-rewrite: 是否采用rewrite机制 + * + * 遍历url模式:采用separator配置的分隔符获得该模式数组 + * 如果模式是*,则代表该位置开始往后为为传递的变量信息 + * 如果模式不是*,则代表该位置为特殊模式。 + * 如果含有key-value-sep配置的分隔符: 则分别对url中相同key下的值和模式中的值分别做分割,对应的模式下获得的数组作为key,url中获得数组作为value + * 如果不含:则该值就作为Key,url对应位置上的值作为value + * + * @param string 待分析匹配的路径信息 + * @return array + */ + private function doParserUrl($url) { + if (!$url) + return array(); + if (is_string($url)) { + $url = explode($this->separator, trim($url, $this->separator)); + } + $vars = array(); + foreach ($this->patterns as $key => $value) { + if ('*' == $value[0]) + $this->parseNomalKeys($key, $url, $vars); + else { + if (!isset($url[$key])) + continue; + if (false === strrpos($value, $this->keyValueSep)) { + $vars[$value] = $url[$key]; + continue; + } + $keys = explode($this->keyValueSep, $value); + $values = explode($this->keyValueSep, $url[$key]); + foreach ($keys as $pos => $key) { + isset($values[$pos]) && $vars[$key] = $values[$pos]; + } + } + } + return $vars; + } + + /** + * 解析url普通参数 + * 如果separator和key-value-sep配置相同:则采用每两个元素为一对key-value的规则获得变量 + * 如果不相同:则将会以每个元素为key-value的组合,之间的分隔符以key-value-sep划分,如果没有该分隔符,则默认该值的索引为数字索引。 + * 如果为没有分隔符:则该值索引以数字索引给出,同时该数字索引将会根据用户是否配置key前缀key-prefix来给出key。 + * 如果有分隔符:则该值将会用分隔符分割获得的两个值来分别作为key和value. + * @param int $key + * @param array $urlParams + * @param array $params + */ + private function parseNomalKeys($key, $urlParams, &$params) { + $pos = 0; + while (isset($urlParams[$key])) { + if ($this->separator == $this->keyValueSep) { + if (isset($urlParams[$key + 1])) { + $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); + $key += 2; + } + continue; + } + if (false === strrpos($urlParams[$key], $this->keyValueSep)) { + $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); + $pos++; + } else { + list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); + $this->parseKey($params, $k, urldecode($v)); + } + $key += 1; + } + } + + /** + * 解析url的parama信息中的key值 + * + * 如果key值不存在'[',']'字符,则该key为字符串,直接返回 + * 如果key值存在,并且'['和']'之前没有字符,则表示该key是将是一个数组,并且键值自增,返回array($key) + * 如果key值存在,并且'['和']'之前有字符,则表示该key是一个数组,并且'['和']'其中的字符是该数组中的键值,返回array(key值, 键值) + * + * //TODO 需要考虑多维数组的情况 + * @param string $key + * @return string|array 返回匹配的结果 + */ + private function parseKey(&$params, $key, $value) { + if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { + $params[$key] = $value; + return; + } + $name = substr($key, 0, $pos); + if ($pos2 === $pos + 1) { + $params[$name][] = $value; + return; + } else { + $key = substr($key, $pos + 1, $pos2 - $pos - 1); + $params[$name][$key] = $value; + return; + } + } + + /* + * (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); + $usrConfig && $config = array_merge($config, $usrConfig); + parent::setConfig($config); + $this->urlPatttern = $this->getConfig('url-pattern'); + $this->separator = $this->getConfig('separator'); + $this->keyValueSep = $this->getConfig('key-value-sep'); + $this->keyValueSep == "" && $this->keyValueSep = $this->separator; + $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); + $this->isRewrite = $this->getConfig('is-rewrite'); + $this->keyPrefix = $this->getConfig('key-prefix'); + $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); + $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); + if (!$this->isRewrite()) + $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); + } + + /** + * 返回路由的配置信息 + * + * @param urlParam + * @param defaultValue + * @return string + */ + private function getUrlParamValue($type, $defaultValue = '') { + if ($_param = $this->getConfig($type, 'url-param')) { + $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); + $tmp = $this->getRequest()->getRequest($_param, $defaultValue); + return !$tmp ? $defaultValue : $tmp; + } + return $defaultValue; + } + + /* (non-PHPdoc) + * @see AbstractWindRouter::route() + */ + public function route() { + // TODO Auto-generated method stub + + } + + /* (non-PHPdoc) + * @see AbstractWindRouter::assemble() + */ + public function assemble() { + // TODO Auto-generated method stub + + + } + +} diff --git a/wind/router/route/AbstractWindRoute.php b/wind/router/route/AbstractWindRoute.php new file mode 100644 index 00000000..a01947a9 --- /dev/null +++ b/wind/router/route/AbstractWindRoute.php @@ -0,0 +1,42 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindRoute extends WindModule { + + /** + * 根据匹配的路由规则,构建Url + * + * @return string + */ + abstract public function build(); + + /** + * 路由规则匹配方法,返回匹配到的参数列表 + * + * @return array + */ + abstract public function match(); + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::handle() + */ + public function handle() { + $args = func_get_args(); + $this->result = call_user_func_array(array($this, 'match'), $args); + if ($this->result !== null) { + return $this->result; + } + if (null !== ($handler = $this->interceptorChain->getHandler())) { + $this->result = call_user_func_array(array($handler, 'handle'), $args); + } else { + $this->result = $this->interceptorChain->execute(); + } + return $this->result; + } +} + +?> \ No newline at end of file diff --git a/wind/router/route/WindRewriteRoute.php b/wind/router/route/WindRewriteRoute.php new file mode 100644 index 00000000..3a9eeb86 --- /dev/null +++ b/wind/router/route/WindRewriteRoute.php @@ -0,0 +1,31 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindRewriteRoute extends AbstractWindRoute { + + /* (non-PHPdoc) + * @see AbstractWindRoute::build() + */ + public function build() { + // TODO Auto-generated method stub + + + } + + /* (non-PHPdoc) + * @see AbstractWindRoute::match() + */ + public function match() { + // TODO Auto-generated method stub + + + } + +} + +?> \ No newline at end of file diff --git a/wind/router/route/WindRoute.php b/wind/router/route/WindRoute.php new file mode 100644 index 00000000..98a44499 --- /dev/null +++ b/wind/router/route/WindRoute.php @@ -0,0 +1,53 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindRoute extends AbstractWindRoute { + /** + * 属性名称 + * + * @var array + */ + protected $params = array(); + /** + * 正则表达式 + * + * @var string + */ + protected $pattern; + /** + * 用于反响生成Url的表达式 + * + * @var string + */ + protected $reverse; + + /* (non-PHPdoc) + * @see IWindRoute::match() + */ + public function match() { + //TODO + } + + /* (non-PHPdoc) + * @see IWindRoute::build() + */ + public function build() { + // TODO Auto-generated method stub + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->setParams($this->getConfig('params')); + $this->setPattern($this->getConfig('pattern')); + $this->setReverse($this->getConfig('reverse')); + } + +} +?> \ No newline at end of file diff --git a/wind/upload/AbstractWindUpload.php b/wind/upload/AbstractWindUpload.php new file mode 100644 index 00000000..baf5a346 --- /dev/null +++ b/wind/upload/AbstractWindUpload.php @@ -0,0 +1,249 @@ + 2010-12-13 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +Wind::import('WIND:component.utility.Security'); +Wind::import('WIND:component.utility.WindFile'); +/** + * the last known user to change this file in the repository <$LastChangedBy: yishuo $> + * @author Qian Su + * @version $Id: AbstractWindUpload.php 1994 2011-06-16 04:19:05Z yishuo $ + * @package + */ +abstract class AbstractWindUpload { + + /** + * 是否有错误产生 + * @var boolean + */ + protected $hasError = false; + + /** + * 错误信息 + * @var array + */ + protected $errorInfo = array('type' => array(), 'size' => array(), 'upload' => array()); + + /** + * 允许的类型 + * @var array + */ + protected $allowType = array();//允许上传的类型及对应的大小,array(ext=>size); + + /** + * 上传文件 + * @param string $saveDir + * @param string $fileName + * @param array $allowType 格式为 array(ext=>size) size单位为b + * @return array|string + */ + public function upload($saveDir, $preFileName = '', $allowType = array()) { + $this->setAllowType($allowType); + $uploaddb = array(); + foreach ($_FILES as $key => $value) { + if (is_array($value['name'])) { + $temp = $this->multiUpload($key, $saveDir, $preFileName); + $uploaddb[$key] = isset($uploaddb[$key]) ? array_merge((array)$uploaddb[$key], $temp) : $temp; + } else { + $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName); + } + } + return 1 == count($uploaddb) ? array_shift($uploaddb) : $uploaddb; + } + + /** + * 单个控件 + * 一个表单中只有一个上传文件的控件 + */ + private function simpleUpload($key, $saveDir, $preFileName = '') { + return $this->doUp($key, $_FILES[$key], $saveDir, $preFileName); + } + + /** + * 多个控件 + * 一个表单中拥有多个上传文件的控件 + */ + private function multiUpload($key, $saveDir, $preFileName = '') { + $uploaddb = array(); + $files = $_FILES[$key]; + $num = count($files['name']); + for($i = 0; $i < $num; $i ++) { + $one = array(); + $one['name'] = $files['name'][$i]; + $one['tmp_name'] = $files['tmp_name'][$i]; + $one['error'] = $files['error'][$i]; + $one['size'] = $files['size'][$i]; + $one['type'] = $files['type'][$i]; + if (!($upload = $this->doUp($key, $one, $saveDir, $preFileName))) continue; + $uploaddb[] = $upload; + } + return $uploaddb; + } + + /** + * 执行上传操作 + * @param string $tmp_name + * @param string $filename + * @return bool + */ + abstract protected function postUpload($tmp_name, $filename); + + /** + * 返回是否含有错误 + * @return boolean + */ + public function hasError() { + return $this->hasError; + } + + /** + * 返回错误信息 + * @param string $errorType + * @return string|mixed + */ + public function getErrorInfo($errorType = '') { + return isset($this->errorInfo[$errorType]) ? $this->errorInfo[$errorType] : $this->errorInfo; + } + + /** + * 设置允许上传的类型 + * @param array $allowType + * @return + */ + public function setAllowType($allowType) { + $allowType && $this->allowType = $allowType; + } + + /** + * 檢查文件是否允許上傳 + * @param string $ext + * @return bool + */ + protected function checkAllowType($ext) { + $allowType = array_keys((array)$this->allowType); + return $allowType ? in_array($ext, $allowType) : true; + } + + /** + * 检查上传文件的大小 + * @param string $type + * @param string $uploadSize + * @return bool + */ + protected function checkAllowSize($type, $uploadSize) { + if ($uploadSize < 0) return false; + if (!$this->allowType || !$this->allowType[$type]) return true; + return $uploadSize < $this->allowType[$type]; + } + + + /** + * 获得文件名字 + * @param array $attInfo + * @param string $preFileName + * @return string + */ + protected function getFileName($attInfo, $preFileName = '') { + $fileName = mt_rand(1, 10) . time() . substr(md5(time() . $attInfo['attname'] . mt_rand(1, 10)), 10, 15) . '.' . $attInfo['ext']; + return $preFileName ? $preFileName . $fileName : $fileName; + } + + /** + * 获得保存路径 + * @param string $fileName + * @param string $saveDir + * @return string + */ + protected function getSavePath($fileName, $saveDir) { + return $saveDir ? rtrim($saveDir, '\\/') . '/' . $fileName : $fileName; + } + + /** + * 判断是否有上传文件 + * @param string $tmp_name + * @return boolean + */ + protected function isUploadFile($tmp_name) { + if (!$tmp_name || $tmp_name == 'none') { + return false; + } elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmp_name) && !is_uploaded_file(str_replace('\\\\', '\\', $tmp_name))) { + return false; + } else { + return true; + } + } + + /** + * 初始化上传的文件信息 + * @param string $key + * @param string $value + * @param string $preFileName 前缀 + */ + protected function initUploadInfo($key, $value, $preFileName, $saveDir) { + $arr = array('attname' => $key, 'name' => $value['name'], 'size' => $value['size'], 'type' => $value['type'], 'ifthumb' => 0, 'fileuploadurl' => ''); + $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1)); + $arr['filename'] = $this->getFileName($arr, $preFileName); + $arr['fileuploadurl'] = $this->getSavePath($arr['filename'], $saveDir); + return $arr; + } + + + /** + * 判断是否使图片,如果使图片则返回 + * @param string $ext; + * @return boolean + */ + protected function isImage($ext) { + return in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'swf')); + } + + + /** + * 创建文件夹 + * @param string $path + * @return boolean + */ + protected function createFolder($path) { + if (!is_dir($path)) { + $this->createFolder(dirname($path)); + @mkdir($path); + @chmod($path, 0777); + @fclose(@fopen($path . '/index.html', 'w')); + @chmod($path . '/index.html', 0777); + } + return true; + } + + /** + * 执行上传操作 + * + * @param array $value + * @return array + */ + protected function doUp($key, $value, $saveDir, $preFileName) { + if (!$this->isUploadFile($value['tmp_name'])) return array(); + $upload = $this->initUploadInfo($key, $value, $preFileName, $saveDir); + + if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'])) { + $this->errorInfo['type'][$key][] = $upload; + $this->hasError = true; + return array(); + } + if (!$this->checkAllowSize($upload['ext'], $upload['size'])) { + $upload['maxSize'] = $this->allowType[$upload['ext']]; + $this->errorInfo['size'][$key][] = $upload; + $this->hasError = true; + return array(); + } + if (!($uploadSize = $this->postUpload($value['tmp_name'], $upload['fileuploadurl']))) { + $this->errorInfo['upload'][$key][] = $upload; + $this->hasError = true; + return array(); + } + $upload['size'] = intval($uploadSize); + return $upload; + } +} \ No newline at end of file diff --git a/wind/upload/WindCurlUpload.php b/wind/upload/WindCurlUpload.php new file mode 100644 index 00000000..65931c06 --- /dev/null +++ b/wind/upload/WindCurlUpload.php @@ -0,0 +1,32 @@ + + * @author Qian Su + * @version $Id: WindCurlUpload.php 1710 2011-03-08 12:09:38Z weihu $ + * @package + * tags + */ +class WindCurlUpload extends AbstractWindUpload { + + public function upload($newName, $path) { + + } + + public function hasError() { + + } + + public function getErrorInfo($type = '') { + + } + + /* (non-PHPdoc) + * @see AbstractWindUpload::postUpload() + */ + protected function postUpload($tmp_name, $filename) { + // TODO Auto-generated method stub + + + } + +} \ No newline at end of file diff --git a/wind/upload/WindFormUpload.php b/wind/upload/WindFormUpload.php new file mode 100644 index 00000000..1d7d1445 --- /dev/null +++ b/wind/upload/WindFormUpload.php @@ -0,0 +1,45 @@ + 2011-7-18 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + * @package + */ +class WindFormUpload extends AbstractWindUpload { + + public function __construct($allowType = array()) { + $this->setAllowType($allowType); + } + + /* + * (non-PHPdoc) + * @see AbstractWindUpload::postUpload() + */ + protected function postUpload($tmp_name, $filename) { + if (strpos($filename, '..') !== false || strpos($filename, '.php.') !== false || preg_match('/\.php$/', $filename)) { + exit('illegal file type!'); + } + $this->createFolder(dirname($filename)); + if (function_exists("move_uploaded_file") && @move_uploaded_file($tmp_name, $filename)) { + @unlink($tmp_name); + @chmod($filename, 0777); + return filesize($filename); + } elseif (@copy($tmp_name, $filename)) { + @unlink($tmp_name); + @chmod($filename, 0777); + return filesize($filename); + } elseif (is_readable($tmp_name)) { + Wind::import('WIND:component.utility.WindFile'); + WindFile::write($filename, WindFile::read($tmp_name)); + @unlink($tmp_name); + if (file_exists($filename)) { + @chmod($filename, 0777); + return filesize($filename); + } + } + return false; + } + +} \ No newline at end of file diff --git a/wind/upload/WindFtpUpload.php b/wind/upload/WindFtpUpload.php new file mode 100644 index 00000000..a44f712c --- /dev/null +++ b/wind/upload/WindFtpUpload.php @@ -0,0 +1,56 @@ + + * @author xiaoxiao + * @version 2011-7-29 xiaoxiao + */ +class WindFtpUpload extends AbstractWindUpload { + private $config = array(); + + private $ftp = null; + + public function __construct($config) { + $this->setConfig($config); + } + + /** + * (non-PHPdoc) + * @see AbstractWindUpload::postUpload() + */ + protected function postUpload($tmp_name, $filename) { + $ftp = $this->getFtpConnection(); + if (!($size = $ftp->upload($tmp_name, $filename))) return false; + @unlink($tmp_name); + return $size; + } + + /** + * 设置配置文件 + * @param array $config + * @return bool + */ + public function setConfig($config) { + if (!is_array($config)) return false; + $this->config = $config; + return true; + } + + /** + * 获得ftp链接对象 + * @return AbstractWindFtp + */ + private function getFtpConnection() { + if (is_object($this->ftp)) return $this->ftp; + if (function_exists('ftp_connect')) { + Wind::import("COM:ftp.WindFtp"); + $this->ftp = new WindFtp($this->config); + return $this->ftp; + } + Wind::import("COM:ftp.WindSocketFtp"); + $this->ftp = new WindSocketFtp($this->config); + return $this->ftp; + } +} \ No newline at end of file diff --git a/wind/utility/WindArray.php b/wind/utility/WindArray.php new file mode 100644 index 00000000..6f8fe1ce --- /dev/null +++ b/wind/utility/WindArray.php @@ -0,0 +1,83 @@ + 2010-11-7 + *@link http://www.phpwind.com + *@copyright Copyright © 2003-2110 phpwind.com + *@license + */ + +/** + * 数组工具类 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Su Qian + * @version $Id$ + * @package + */ +class WindArray { + + /** + * 按指定key合并两个数组 + * @param string key 合并数组的参照值 + * @param array $array1 要合并数组 + * @param array $array2 要合并数组 + * @return array 返回合并的数组 + */ + public static function mergeArrayWithKey($key, array $array1, array $array2) { + if (!$key || !$array1 || !$array2) { + return array(); + } + $array1 = self::rebuildArrayWithKey($key, $array1); + $array2 = self::rebuildArrayWithKey($key, $array2); + $tmp = array(); + foreach ($array1 as $key => $array) { + if (isset($array2[$key])) { + $tmp[$key] = array_merge($array, $array2[$key]); + unset($array2[$key]); + } else { + $tmp[$key] = $array; + } + } + return array_merge($tmp, (array) $array2); + } + + /** + * 按指定key合并两个数组 + * @param string key 合并数组的参照值 + * @param array $array1 要合并数组 + * @param array $array2 要合并数组 + * @return array 返回合并的数组 + */ + public static function filterArrayWithKey($key, array $array1, array $array2) { + if (!$key || !$array1 || !$array2) { + return array(); + } + $array1 = self::rebuildArrayWithKey($key, $array1); + $array2 = self::rebuildArrayWithKey($key, $array2); + $tmp = array(); + foreach ($array1 as $key => $array) { + if (isset($array2[$key])) { + $tmp[$key] = array_merge($array, $array2[$key]); + } + } + return $tmp; + } + + /** + * 按指定KEY重新生成数组 + * @param string key 重新生成数组的参照值 + * @param array $array 要重新生成的数组 + * @return array 返回重新生成后的数组 + */ + public static function rebuildArrayWithKey($key, array $array) { + if (!$key || !$array) { + return array(); + } + $tmp = array(); + foreach ($array as $_array) { + if (isset($_array[$key])) { + $tmp[$_array[$key]] = $_array; + } + } + return $tmp; + } +} \ No newline at end of file diff --git a/wind/utility/WindFile.php b/wind/utility/WindFile.php new file mode 100644 index 00000000..80e8b9c3 --- /dev/null +++ b/wind/utility/WindFile.php @@ -0,0 +1,254 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +class WindFile { + + /** + * @var string 以读的方式打开文件,具有较强的平台移植性 + */ + const READ = 'rb'; + + /** + * @var string 以读写的方式打开文件,具有较强的平台移植性 + */ + const READWRITE = 'rb+'; + + /** + * @var string 以写的方式打开文件,具有较强的平台移植性 + */ + const WRITE = 'wb'; + + /** + * @var string 以读写的方式打开文件,具有较强的平台移植性 + */ + const WRITEREAD = 'wb+'; + + /** + * @var string 以追加写入方式打开文件,具有较强的平台移植性 + */ + const APPEND_WRITE = 'ab'; + + /** + * @var string 以追加读写入方式打开文件,具有较强的平台移植性 + */ + const APPEND_WRITEREAD = 'ab+'; + + /** + * 保存文件 + * @param string $fileName 保存的文件名 + * @param mixed $data 保存的数据 + * @param boolean $isBuildReturn 是否组装保存的数据是return $params的格式,如果没有则以变量声明的方式保存 + * @param string $method 打开文件方式 + * @param boolean $ifLock 是否对文件加锁 + */ + public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { + $temp = " $value) { + if (!preg_match('/^\w+$/', $key)) + continue; + $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; + } + $temp .= "\r\n?>"; + } else { + ($isBuildReturn) && $temp .= " return "; + $temp .= WindString::varToString($data) . ";\r\n?>"; + } + return self::write($fileName, $temp, $method, $ifLock); + } + + /** + * 写文件 + * + * @param string $fileName 文件绝对路径 + * @param string $data 数据 + * @param string $method 读写模式 + * @param bool $ifLock 是否锁文件 + * @param bool $ifCheckPath 是否检查文件名中的“..” + * @param bool $ifChmod 是否将文件属性改为可读写 + * @return int 返回写入的字节数 + */ + public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { + $fileName = WindSecurity::escapePath($fileName); + touch($fileName); + if (!$handle = fopen($fileName, $method)) + return false; + $ifLock && flock($handle, LOCK_EX); + $writeCheck = fwrite($handle, $data); + $method == self::READWRITE && ftruncate($handle, strlen($data)); + fclose($handle); + $ifChmod && chmod($fileName, 0777); + return $writeCheck; + } + + /** + * 读取文件 + * + * @param string $fileName 文件绝对路径 + * @param string $method 读取模式 + * @return string + */ + public static function read($fileName, $method = self::READ) { + $fileName = WindSecurity::escapePath($fileName); + $data = ''; + if (false !== ($handle = fopen($fileName, $method))) { + flock($handle, LOCK_SH); + $data = fread($handle, filesize($fileName)); + fclose($handle); + } + return $data; + } + + /** + * 按目录删除文件 + * @param string $dir 目录 + * @param boolean $ifexpiled 是否过期 + * @deprecated + * @return boolean + */ + public static function clearDir($dir, $ifexpiled = false) { + //TODO 删除掉是否过期相关处理,不要将外部业务需求,耦合进工具库方法 + if (!$handle = @opendir($dir)) + return false; + while (false !== ($file = readdir($handle))) { + if ('.' === $file[0] || '..' === $file[0]) + continue; + $fullPath = $dir . DIRECTORY_SEPARATOR . $file; + if (is_dir($fullPath)) { + self::clearDir($fullPath, $ifexpiled); + } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { + self::delFile($fullPath); + } + } + closedir($handle); + false === $ifexpiled && rmdir($dir); + return true; + } + + /** + * 批量删除文件 + * @param string $path + * @param string $delDir + * @param int $level + * @return string + */ + public static function delFiles($path, $delDir = false, $level = 0) { + $path = rtrim($path, DIRECTORY_SEPARATOR); + if (!$handler = opendir($path)) { + return false; + } + while (false !== ($filename = readdir($handler))) { + if ("." != $filename && ".." != $filename) { + if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { + if (substr($filename, 0, 1) != '.') { + self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); + } + } else { + self::delFile($path . DIRECTORY_SEPARATOR . $filename); + } + } + } + closedir($handler); + true == $delDir && $level > 0 && rmdir($path); + return true; + } + + /** + * 取得文件的mime类型 + * @param string $fileName 文件名 + * @return string + */ + public static function getMimeType($fileName) { + //TODO WindMimeTypes.php 被删掉了,有bug + $suffix = self::getFileSuffix($fileName); + $mimes = require WIND_PATH . '/component/utility/WindMimeTypes.php'; + if (isset($mimes[$suffix])) { + return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; + } else { + throw new WindException('Sorry, can not find the corresponding mime type of the file'); + } + return false; + } + + /** + * 取得目录的迭代 + * @param string $dir 目录名 + * @return DirectoryIterator + */ + public static function getDirectoryIterator($dir) { + return new DirectoryIterator($dir); + } + + /** + * 取得文件信息 + * @param unknown_type $fileName + * @return string|number + */ + public static function getFileInfo($fileName) { + if (false === is_file($fileName)) { + return array(); + } + $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); + $fileInfo['path'] = $fileName; + $fileInfo['size'] = filesize($fileName); + $fileInfo['ctime'] = filectime($fileName); + $fileInfo['atime'] = fileatime($fileName); + $fileInfo['mtime'] = filemtime($fileName); + $fileInfo['readable'] = is_readable($fileName); + $fileInfo['writable'] = is_writable($fileName); + $fileInfo['executable'] = is_executable($fileName); + $fileInfo['right'] = fileperms($fileName); + $fileInfo['group'] = filegroup($fileName); + $fileInfo['owner'] = fileowner($fileName); + $fileInfo['mime'] = self::getMimeType($fileName); + return $fileInfo; + } + + /** + * 取得目录信息 + * @param unknown_type $dir + * @return string|multitype: + */ + public static function getDirectoryInfo($dir) { + if (false !== is_dir($dir)) { + return array(); + } + return stat($dir); + } + + /** + * 删除文件 + * @param string $filename + * @return boolean + */ + public static function delFile($filename) { + return @unlink($filename); + } + + /** + * 取得文件后缀 + * @param string $filename + * @return string + */ + public static function getFileSuffix($filename) { + $filename = explode($filename, '.'); + return $filename[count($filename) - 1]; + } + + /** + * 取得真实的目录 + * @param string $path 路径名 + * @return string + */ + public static function appendSlashesToDir($path) { + return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; + } + +} \ No newline at end of file diff --git a/wind/utility/WindHtmlHelper.php b/wind/utility/WindHtmlHelper.php new file mode 100644 index 00000000..a2850db7 --- /dev/null +++ b/wind/utility/WindHtmlHelper.php @@ -0,0 +1,43 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHtmlHelper { + + /** + * Convert special characters to HTML entities + * + * @param string $text | + * @return string | string The converted string + */ + public static function encode($text) { + return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); + } + + /** + * Convert special characters to HTML entities + * + * @param array $data + * @return array + */ + public static function encodeArray($data) { + $_tmp = array(); + $_charset = Wind::getApp()->getRequest()->getCharset(); + foreach ($data as $key => $value) { + if (is_string($key)) + $key = htmlspecialchars($key, ENT_QUOTES, $_charset); + if (is_string($value)) + $value = htmlspecialchars($value, ENT_QUOTES, $_charset); + elseif (is_array($value)) + $value = self::encodeArray($value); + $_tmp[$key] = $value; + } + return $_tmp; + } + +} + +?> \ No newline at end of file diff --git a/wind/utility/WindImage.php b/wind/utility/WindImage.php new file mode 100644 index 00000000..25935081 --- /dev/null +++ b/wind/utility/WindImage.php @@ -0,0 +1,303 @@ + + * @author xiaoxiao + * @version 2011-8-10 xiaoxiao + */ +class WindImage { + + /** + * 生成略缩图 + * + * @param string $srcFile 源图片 + * @param string $dstFile 略缩图保存位置 + * @param int $dstW 略缩图宽度 + * @param string $dstH 略缩图高度 + * @param string $isProportion 略缩图是否等比略缩 + * @return array|boolean + */ + public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { + if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; + list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); + if (!$imagecreate) return false; + $imgwidth = $minitemp['width']; + $imgheight = $minitemp['height']; + + $srcX = $srcY = $dstX = $dstY =0; + if (!$isProportion) { + $dsDivision = $imgheight / $imgwidth; + $fixDivision = $dstH / $dstW; + if ($dsDivision > $fixDivision) { + $tmp = $imgwidth * $fixDivision; + $srcY = round(($imgheight - $tmp) / 2); + $imgheight = $tmp; + } else { + $tmp = $imgheight / $fixDivision; + $srcX = round(($imgwidth - $tmp) / 2); + $imgwidth = $tmp; + } + } + $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); + + if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { + $black = imagecolorallocate($thumb, 0, 0, 0); + imagecolortransparent($thumb, $black); + } + $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); + self::makeImg($minitemp['type'], $thumb, $dstFile); + imagedestroy($thumb); + return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); + } + + /** + * 给图片制作水印 + * 水印的位置可以为: + * array(0 => '随机位置', 1 => '顶部居左', 2 => '顶部居中', 3 => '顶部居右', 4 => '底部居左', 5 => '底部居中', 6 => '底部居右', 7 => '中心位置') + * + * @param string $source + * @param int|array $waterPos 水印的位置 + * @param string $waterImg 图片水印:水印图片的位置 + * @param string $waterText 水印的文字 + * @param array $attribute 文字水印的属性,只对文字水印有效 + * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小') + * + * @param string $waterPct 水印透明度,从0到100,0完全透明,100完全不透明 + * @param string $waterQuality 图片质量--jpeg + * @param string $dstsrc 目标文件位置 + * @return boolean + */ + public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { + $sourcedb = $waterdb = array(); + if (false === ($sourcedb = self::getImgInfo($source))) return false; + if (!$waterImg && !$waterText) return false; + imagealphablending($sourcedb['source'], true); + if ($waterImg) { + $waterdb = self::getImgInfo($waterImg); + list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); + if ($waterdb['type'] == 'png') { + $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); + imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); + imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); + $sourcedb['source'] = $tmp; + } else { + imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); + } + } elseif ($waterText) { + list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); + empty($waterFont) && $waterFont = 12; + $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); //取得使用 TrueType 字体的文本的范围 + $waterdb['width'] = $temp[2] - $temp[6]; + $waterdb['height'] = $temp[3] - $temp[7]; + unset($temp); + list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); + if (strlen($color) != 7) return false; + $R = hexdec(substr($color, 1, 2)); + $G = hexdec(substr($color, 3, 2)); + $B = hexdec(substr($color, 5)); + self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); + imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); + } + $dstsrc && $source = $dstsrc; + self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); + isset($waterdb['source']) && imagedestroy($waterdb['source']); + imagedestroy($sourcedb['source']); + return true; + } + + /** + * 文字水印的属性设置过滤 + * 返回为: + * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小') + * @param array $attribute + * @return array + */ + private static function checkAttribute($attribute) { + $attribute = is_string($attribute) ? array($attribute) : $attribute; + if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; + if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; + if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; + return $attribute; + } + + /** + * 判断是否需要转编码, + * 判断依据为,编码格式为utf-8 + * + * @param string $charset + * @return boolean + */ + private static function changeCharset($charset) { + $charset = strtolower($charset); + return !in_array($charset, array('utf8', 'utf-8')); + } + + /** + * 获得打水印的位置 + * 如果传入的是数组,则两个元素分别为水印的宽度x和高度y + * + * @param int|array $pos + * @param array $sourcedb + * @param array $waterdb + * @param int $markType 水印类型,1为图片水印,2为文字水印 + * @return array + */ + private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { + if (is_array($waterPos)) return $waterPos; + $wX = $wY = 0; + switch (intval($waterPos)) { + case 0 : + $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); + $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); + break; + case 1 : + $wX = 5; + $wY = $markType == 1 ? 5 : $waterdb['height']; + break; + case 2: + $wX = ($sourcedb['width'] - $waterdb['width']) / 2; + $wY = $markType == 1 ? 5 : $waterdb['height']; + break; + case 3: + $wX = $sourcedb['width'] - $waterdb['width'] - 5; + $wY = $markType == 1 ? 5 : $waterdb['height']; + break; + case 4: + $wX = 5; + $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; + break; + case 5: + $wX = ($sourcedb['width'] - $waterdb['width']) / 2; + $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; + break; + case 6: + $wX = $sourcedb['width'] - $waterdb['width'] - 5; + $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; + break; + default: + $wX = ($sourcedb['width'] - $waterdb['width']) / 2; + $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; + break; + } + return array($wX, $wY); + } + + /** + * 获得略缩图的信息 + * + * @param string $srcFile 源文件 + * @param int $dstW 目标文件的宽度 + * @param int $dstH 目标文件的高度 + * @param boolean $isProportion 是否定比略缩 + * @return array|boolean + */ + private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { + if (false === ($imgdata = self::getImgInfo($srcFile))) return false; + if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; + + $imgdata['dstW'] = $dstW; + $imgdata['dstH'] = $dstH; + if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { + $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); + } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { + $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); + } elseif ($dstW > 0 && $dstH > 0) { + if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { + $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); + } + if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { + $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); + } + } else { + $imgdata = false; + } + return $imgdata; + } + + /** + * 获得图片的信息,返回图片的源及图片的高度和宽度 + * + * @param string $srcFile 图像地址 + * @return array|boolean + */ + public static function getImgInfo($srcFile) { + if (false === ($imgdata = self::getImgSize($srcFile))) return false; + $imgdata['type'] = self::getTypes($imgdata['type']); + if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; + $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; + $imgdata['source'] = $imagecreatefromtype($srcFile); + !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); + !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); + return $imgdata; + } + + /** + * 获得图片的类型及宽高 + *
+	 * 图片type:
+	 * 1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,
+	 * 11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
+	 * 
+ * @param string $srcFile 图像地址 + * @param string $srcExt 图像后缀 + * @return array|boolean 返回图像的类型及高度和宽度 + */ + private static function getImgSize($srcFile, $srcExt = null) { + empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); + $srcdata = array(); + $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); + in_array($srcExt, $exts) && $srcdata['type'] = 2; + if (false === ($info = getimagesize($srcFile))) return false; + list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; + if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; + return $srcdata; + } + + /** + * 获得创建图像的方法 + * + * @param string $imagetype 图片类型 + * @return array + */ + private static function getImgcreate($imagetype) { + if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { + return array('imagecreatetruecolor', 'imagecopyresampled'); + } + if (function_exists('imagecreate') && function_exists('imagecopyresized')) { + return array('imagecreate', 'imagecopyresized'); + } + return array('', ''); + } + + /** + * 创建图像 + * + * @param string $type 图像类型 + * @param resource $image 图像源 + * @param string $filename 图像保存名字 + * @param int $quality 创建jpeg的时候用到 + * @return boolean + */ + private static function makeImg($type, $image, $filename, $quality = '75') { + $makeimage = 'image' . $type; + if (!function_exists($makeimage)) return false; + if ($type == 'jpeg') { + $makeimage($image, $filename, $quality); + } else { + $makeimage($image, $filename); + } + return true; + } + + /** + * 图片的对应类型 + * + * @param int $id 图片类型ID + * @return string + */ + private static function getTypes($id) { + $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); + return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; + } +} \ No newline at end of file diff --git a/wind/utility/WindPack.php b/wind/utility/WindPack.php new file mode 100644 index 00000000..e0b7aa6a --- /dev/null +++ b/wind/utility/WindPack.php @@ -0,0 +1,397 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +class WindPack { + /** + * @var string 使用正则打包 + */ + const STRIP_SELF = 'stripWhiteSpaceBySelf'; + /** + * @var string 利用php自身的函数打包 + */ + const STRIP_PHP = 'stripWhiteSpaceByPhp'; + /** + * @var string 通过token方式打包 + */ + const STRIP_TOKEN = 'stripWhiteSpaceByToken'; + private $packList = array(); + private $contentInjectionPosition; + private $contentInjectionCallBack = ''; + + /** + * 将指定文件类型且指定文件夹下的所指定文件打包成一个易阅读的文件, + * @param mixed $dir 要打包的目录 + * @param string $dst 文件名 + * @param string $packMethod 打包方式 + * @param boolean $compress 是否压缩 + * @param string $absolutePath 文件路径 + * @param array $ndir 不须要打包的目录 + * @param array $suffix 不永许打包的文件类型 + * @return string + */ + public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { + if (empty($dst) || empty($dir)) { + return false; + } + $suffix = is_array($suffix) ? $suffix : array( + $suffix); + if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { + return false; + } + $fileSuffix = WindFile::getFileSuffix($dst); + $replace = $compress ? ' ' : "\n"; + $content = implode($replace, $content); + $content = $this->callBack($content, $replace); + $content = $this->stripNR($content, $replace); + $content = $this->stripPhpIdentify($content, ''); + $content = $this->stripImport($content, ''); + $content = $this->getContentBySuffix($content, $fileSuffix, $replace); + WindFile::write($dst, $content); + return true; + } + + /** + * @param mixed $fileList + * @param string $dst + * @param method $packMethod + * @param boolean $compress + * @param string $absolutePath + * @return string|string + */ + public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { + if (empty($dst) || empty($fileList)) { + return false; + } + $content = array(); + $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); + $fileSuffix = WindFile::getFileSuffix($dst); + $replace = $compress ? ' ' : "\n"; + $content = implode($replace, $content); + $content = $this->callBack($content, $replace); + $content = $this->stripNR($content, $replace); + $content = $this->stripPhpIdentify($content, ''); + //$content = $this->stripImport($content, ''); + $content = $this->getContentBySuffix($content, $fileSuffix, $replace); + WindFile::write($dst, $content); + return true; + } + + /** + * 通过php自身方式去除指定文件的注释及空白 + * @param string $filename 文件名 + */ + public function stripWhiteSpaceByPhp($filename) { + return php_strip_whitespace($filename); + } + + /** + * 通过正则方式去除指定文件的注释及空白 + * @param string $filename + * @param boolean $compress + * @return string + */ + public function stripWhiteSpaceBySelf($filename, $compress = true) { + $content = $this->getContentFromFile($filename); + $content = $this->stripComment($content, ''); + return $this->stripSpace($content, ' '); + } + + /** + * 通过token方式去除指定文件的注释及空白 + * @param string $filename + * @return string + */ + public function stripWhiteSpaceByToken($filename) { + $content = $this->getContentFromFile($filename); + $compressContent = ''; + $lastToken = 0; + foreach (token_get_all($content) as $key => $token) { + if (is_array($token)) { + if (in_array($token[0], array( + T_COMMENT, + T_WHITESPACE, + T_DOC_COMMENT))) { + continue; + } + $compressContent .= ' ' . $token[1]; + } else { + $compressContent .= $token; + } + $lastToken = $token[0]; + } + return $compressContent; + } + + /** + * 从各个目录中取得对应的每个文件的内容 + * @param string $packMethod 打包方式 + * @param mixed $dir 目录名 + * @param string $absolutePath 绝对路径名 + * @param array $ndir 不须要打包的文件夹 + * @param array $suffix 不须要打包的文件类型 + * @param array $nfile 不须要打包的文件 + * @return array + */ + public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { + static $content = array(); + if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { + return false; + } + $dir = is_array($dir) ? $dir : array( + $dir); + foreach ($dir as $_dir) { + $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; + if (is_dir($_dir)) { + $handle = dir($_dir); + while (false != ($tmp = $handle->read())) { + $name = WindFile::appendSlashesToDir($_dir) . $tmp; + if (is_dir($name) && !in_array($tmp, $ndir)) { + $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); + } + if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { + $content[] = $this->$packMethod($name); + $this->setPackList($file, $name); + } + } + $handle->close(); + } + } + return $content; + } + + /** + * 从文件列表中取得对应的每个文件的内容 + * @param mixed $fileList + * @param method $packMethod + * @param string $absolutePath + * @return array: + */ + public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { + if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { + return array(); + } + $fileList = is_array($fileList) ? $fileList : array( + $fileList); + foreach ($fileList as $key => $value) { + if (is_array($value) && isset($value[1])) { + $parents = class_parents($value[1]); + $_fileList = $this->buildFileList($parents, $fileList); + $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); + $implements = class_implements($value[1]); + $_fileList = $this->buildFileList($implements, $fileList); + $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); + if (key_exists($key, $this->getPackList())) continue; + $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; + if (is_file($file)) { + $content[] = $this->$packMethod($file); + $this->setPackList($key, $value); + } + } + } + } + + /** + * 去除注释 + * @param string $content 要去除的内容 + * @param mixed $replace 要替换的文本 + * @return string + */ + public function stripComment($content, $replace = '') { + return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); + } + + /** + * 去除换行 + * @param string $content 要去除的内容 + * @param mixed $replace 要替换的文本 + * @return string + */ + public function stripNR($content, $replace = array('\n','\r\n','\r')) { + return preg_replace('/[\n\r]+/', $replace, $content); + } + + /** + * 去除空格符 + * @param string $content 要去除的内容 + * @param mixed $replace 要替换的文本 + * @return string + */ + public function stripSpace($content, $replace = ' ') { + return preg_replace('/[ ]+/', $replace, $content); + } + + /** + * 去除php标识 + * @param string $content + * @param mixed $replace + * @return string + */ + public function stripPhpIdentify($content, $replace = '') { + return preg_replace('/(?:<\?(?:php)*)|(\?>)/i', $replace, $content); + } + + /** + * 根据指定规则替换指定内容中相应的内容 + * @param string $content + * @param string $rule + * @param $mixed $replace + * @return string + */ + public function stripStrByRule($content, $rule, $replace = '') { + return preg_replace("/$rule/", $replace, $content); + } + + /** + * 去除多余的文件导入信息 + * @param string $content + * @param mixed $replace + * @return string + */ + public function stripImport($content, $replace = '') { + $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); + if ($matchs[1]) { + foreach ($matchs[1] as $key => $value) { + $name = substr($value, strrpos($value, '.') + 1); + if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { + $strip = str_replace(array( + '(', + ')'), array( + '\(', + '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; + $content = $this->stripStrByRule($content, $strip, $replace); + } + } + } + return $content; + } + + /** + * 取得被打包的文件列表 + * @return array: + */ + public function getPackList() { + return $this->packList; + } + + /** + *从文件读取内容 + * @param string $filename 文件名 + * @return string + */ + public function getContentFromFile($filename) { + if (is_file($filename)) { + $content = ''; + $fp = fopen($filename, "r"); + while (!feof($fp)) { + $line = fgets($fp); + if (in_array(strlen($line), array( + 2, + 3)) && in_array(ord($line), array( + 9, + 10, + 13))) continue; + $content .= $line; + } + fclose($fp); + return $content; + } + return false; + } + + /** + * 根据文件后缀得取对应的mime内容 + * @param string $content 要打包的内容内容 + * @param string $suffix 文件后缀类型 + * @param string $replace + * @return string + */ + public function getContentBySuffix($content, $suffix, $replace = ' ') { + switch ($suffix) { + case 'php': + $content = ''; + break; + default: + $content = ''; + break; + } + return $content; + } + + private function buildFileList($list, $fileList) { + $_temp = array(); + foreach ($list as $fileName) { + foreach ($fileList as $key => $value) { + if ($value[1] == $fileName) { + $_temp[$key] = $value; + break; + } + } + } + return $_temp; + } + + /** + * @param $contentInjectionCallBack the $contentInjectionCallBack to set + * @param string $position 调用位置(before|after) + * @author Qiong Wu + */ + public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { + if (!in_array($position, array( + 'before', + 'after'))) $position = 'before'; + $this->contentInjectionPosition = $position; + $this->contentInjectionCallBack = $contentInjectionCallBack; + } + + /** + * 回调函数调用 + * @param string $content + * @param string $replace + * @return string + */ + public function callBack($content, $replace = '') { + if ($this->contentInjectionCallBack !== '') { + $_content = call_user_func_array($this->contentInjectionCallBack, array( + $this->getPackList())); + if ($this->contentInjectionPosition == 'before') { + $content = $replace . $_content . $content; + } elseif ($this->contentInjectionPosition == 'after') { + $content .= $replace . $_content . $replace; + } + } + return $content; + } + + private function isValidatePackMethod($packMethod) { + return method_exists($this, $packMethod) && in_array($packMethod, array( + WindPack::STRIP_PHP, + WindPack::STRIP_SELF, + WindPack::STRIP_TOKEN)); + } + + /** + * 添加被打包的文件到列表 + * @param string $key + * @param string $value + */ + private function setPackList($key, $value) { + if (isset($this->packList[$key])) { + if (is_array($this->packList[$key])) { + array_push($this->packList[$key], $value); + } else { + $tmp_name = $this->packList[$key]; + $this->packList[$key] = array( + $tmp_name, + $value); + } + } else { + $this->packList[$key] = $value; + } + } +} diff --git a/wind/utility/WindSecurity.php b/wind/utility/WindSecurity.php new file mode 100644 index 00000000..2048283f --- /dev/null +++ b/wind/utility/WindSecurity.php @@ -0,0 +1,300 @@ + + * @author Qian Su + * @version $Id$ + * @package + */ +class WindSecurity { + + /** + * Convert special characters to HTML entities + * @param array $data + * @return array + */ + public static function escapeHTMLForArray($data) { + $_tmp = array(); + $_charset = Wind::getApp()->getRequest()->getCharset(); + foreach ($data as $key => $value) { + if (is_string($key)) + $key = htmlspecialchars($key, ENT_QUOTES, $_charset); + if (is_string($value)) + $value = htmlspecialchars($value, ENT_QUOTES, $_charset); + elseif (is_array($value)) + $value = self::escapeHTMLForArray($value); + $_tmp[$key] = $value; + } + return $_tmp; + } + + /** + * Convert special characters to HTML entities + * @param string $str + * @return string + */ + public static function escapeHTML($str) { + if (is_array($str)) + return self::escapeHTMLForArray($str); + return htmlspecialchars($str, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); + } + + /** + * 过滤标签 + * @param $param + * @return string + */ + public static function stripTags($str, $allowTags = "") { + return strip_tags($str, $allowTags); + } + + /** + * 路径转换 + * @param $fileName + * @param $ifCheck + * @return string + */ + public static function escapePath($fileName, $ifCheck = true) { + if (!self::_escapePath($fileName, $ifCheck)) { + throw new WindException('file name is illegal'); + } + return $fileName; + } + + /** + * 目录转换 + * @param string $dir + * @return string + */ + public static function escapeDir($dir) { + $dir = strtr($dir, + array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', + ';' => '')); + return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); + } + + /** + * 通用多类型转换 + * @param mixed $value + * @return mixed + */ + public static function escapeChar($value) { + if (is_array($value)) { + foreach ($value as $key => $sub) { + $value[$key] = self::escapeChar($sub); + } + } elseif (is_int($value)) { + $value = (int) $value; + } elseif (is_string($value)) { + $value = self::escapeString($value); + } + return $value; + } + + /** + * 字符转换 + * @param string $string + * @return string + */ + public static function escapeString($string) { + $string = strtr($string, + array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', + "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', + '>' => '>', '"' => '"', "'" => ''')); + return preg_replace( + array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), + array('', '&'), $string); + } + + /** + * 该函数可用于转义拥有特殊意义的字符,比如 SQL 中的 ( )、[ ] 以及 *。 + * @param string $string + * @return string + */ + public static function quotemeta($string) { + return quotemeta($string); + } + + /** + * 对字符串转义 + * @param string $value + * @return string + */ + public function checkInputValue($value, $key = '') { + if (is_int($value)) { + $value = (int) $value; + } elseif (is_string($value)) { + $value = "'" . addslashes($value) . "'"; + } elseif (is_float($value)) { + $value = (float) $value; + } elseif (is_object($value) || is_array($value)) { + $value = "'" . addslashes(serialize($value)) . "'"; + } + return $value; + } + + /** + * 对cookie/post/get方式的值添加反斜线 + * @param string $str + * @return string + */ + public static function addSlashesForInput($str) { + if (!get_magic_quotes_gpc()) { + $str = addslashes($str); + } + return $str; + } + + /** + * 对从db或者file里面读取的内容添加反斜线 + * @return string + */ + public static function addSlashesForOutput($str) { + if (!get_magic_quotes_runtime()) { + $str = addslashes($str); + } + return $str; + } + + /** + * 添加反斜线,转义字符 + * @param mixed $value 要处理的数组 + * @param boolean $gpc 是否是get/cookie/post传递过来的值 + * @param boolean $df 是否是database/file传递过来的值 + * @return string + */ + public static function addSlashes($value, $gpc = false, $df = false) { + if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable))) { + return $value; + } + if (is_string($value)) { + if (false === $gpc && true === $df) { + return self::addSlashesForOutput($value); + } + if (false === $df && true === $gpc) { + return self::addSlashesForInput($value); + } + return addslashes($value); + } + foreach ($value as $key => $_value) { + $value[$key] = self::addSlashes($_value, $gpc, $df); + } + return $value; + } + + /** + * 去除反 斜线 + * @param mixed $array + * @return string + */ + public static function stripSlashes($value) { + if (!$value) + return $value; + if (is_string($value)) + return stripslashes($value); + if (!is_array($value) && !($value instanceof Traversable)) + return $value; + foreach ($value as $key => $_value) { + $value[$key] = self::stripSlashes($_value); + } + return $value; + } + + /** + * 通用多类型混合转义函数 + * @param $var + * @param $strip + * @param $isArray + * @return mixture + */ + public static function sqlEscape($var, $strip = true, $isArray = false) { + if (is_array($var)) { + if (!$isArray) + return " '' "; + foreach ($var as $key => $value) { + $var[$key] = trim(self::sqlEscape($value, $strip)); + } + return $var; + } elseif (is_numeric($var)) { + return " '" . $var . "' "; + } else { + return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; + } + } + + /** + * 通过","字符连接数组转换的字符 + * @param $array + * @param $strip + * @return string + */ + public static function sqlImplode($array, $strip = true) { + return implode(',', self::sqlEscape($array, $strip, true)); + } + + /** + * 组装单条 key=value 形式的SQL查询语句值 insert/update + * @param $array + * @param $strip + * @return string + */ + public static function sqlSingle($array, $strip = true) { + if (!is_array($array)) + return ''; + $array = self::sqlEscape($array, $strip, true); + $str = ''; + foreach ($array as $key => $val) { + $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; + } + return $str; + } + + /** + * 组装多条 key=value 形式的SQL查询语句 insert + * @param $array + * @param $strip + * @return string + */ + public static function sqlMulti($array, $strip = true) { + if (!is_array($array)) { + return ''; + } + $str = ''; + foreach ($array as $val) { + if (!empty($val) && is_array($val)) { + $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; + } + } + return $str; + } + + /** + * 过滤SQL元数据,数据库对象(如表名字,字段等) + * @param $data 元数据 + * @param $tlists 白名单 + * @return string 经过转义的元数据字符串 + */ + public static function sqlMetadata($data, $tlists = array()) { + if (empty($tlists) || !in_array($data, $tlists)) { + $data = str_replace(array('`', ' '), '', $data); + } + return ' `' . $data . '` '; + } + + /** + * 私用路径转换 + * @param string $fileName + * @param boolean $ifCheck + * @return boolean + */ + private static function _escapePath($fileName, $ifCheck = true) { + $tmpname = strtolower($fileName); + $tmparray = array('://' => '', "\0" => ''); + $ifCheck && $tmparray['..'] = ''; + if (strtr($tmpname, $tmparray) != $tmpname) { + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/wind/utility/WindString.php b/wind/utility/WindString.php new file mode 100644 index 00000000..eb41cd5e --- /dev/null +++ b/wind/utility/WindString.php @@ -0,0 +1,242 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 字符串格式化 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindString { + const UTF8 = 'utf8'; + const GBK = 'gbk'; + /** + * 截取字符串 + * @param string $string 要截取的字符串编码 + * @param int $start 开始截取 + * @param int $length 截取的长度 + * @param string $charset 原妈编码 + * @param boolean $dot 是否显示省略号 + * @return string 截取后的字串 + */ + public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { + return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( + $string, $start, $length, $dot); + } + + /** + * 求取字符串长度 + * @param string $string 要计算的字符串编码 + * @param string $charset 原始编码 + * @return int + */ + public static function strlen($string, $charset = self::UTF8) { + $len = strlen($string); + $i = $count = 0; + while ($i < $len) { + ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; + $count++; + } + return $count; + } + + /** + * 将变量的值转换为字符串 + * + * @param mixed $input 变量 + * @param string $indent 缩进 + * @return string + */ + public static function varToString($input, $indent = '') { + switch (gettype($input)) { + case 'string': + return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; + case 'array': + $output = "array(\r\n"; + foreach ($input as $key => $value) { + $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( + $value, $indent . "\t"); + $output .= ",\r\n"; + } + $output .= $indent . ')'; + return $output; + case 'boolean': + return $input ? 'true' : 'false'; + case 'NULL': + return 'NULL'; + case 'integer': + case 'double': + case 'float': + return "'" . (string) $input . "'"; + } + return 'NULL'; + } + + public static function jsonEncode($value) { + if (!function_exists('json_encode')) { + Wind::import('Wind:component.utility.json.WindEncoder'); + return WindDecoder::decode($value); + } + return json_encode($value); + } + + public static function jsonDecode($value) { + if (!function_exists('json_decode')) { + Wind::import('Wind:component.utility.json.WindEncoder'); + return WindEncoder::encode($value); + } + return json_decode($value); + } + + public static function jsonSimpleEncode($var) { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + case 'NULL': + return 'null'; + case 'integer': + return (int) $var; + case 'double': + case 'float': + return (float) $var; + case 'string': + return '"' . addslashes( + str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; + case 'array': + if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array(); + foreach ($var as $name => $value) { + $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( + $value); + } + return '{' . join(',', $properties) . '}'; + } + $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); + return '[' . join(',', $elements) . ']'; + } + return false; + } + + /** + * 以utf8格式截取的字符串编码 + * @param string $string 要截取的字符串编码 + * @param int $start 开始截取 + * @param int $length 截取的长度 + * @param boolean $dot 是否显示省略号 + * @return string + */ + public static function utf8_substr($string, $start, $length = null, $dot = false) { + if (empty($string) || !is_int($start) || ($length && !is_int($length))) { + return ''; + } + $strlen = strlen($string); + $length = $length ? $length : $strlen; + $substr = ''; + $chinese = $word = 0; + for ($i = 0, $j = 0; $i < $start; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $chinese++; + $j += 2; + } else { + $word++; + } + $j++; + } + $start = $word + 3 * $chinese; + for ($i = $start, $j = $start; $i < $start + $length; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $substr .= substr($string, $j, 3); + $j += 2; + } else { + $substr .= substr($string, $j, 1); + } + $j++; + } + (strlen($substr) < $strlen) && $dot && $substr .= "..."; + return $substr; + } + + /** + * 以utf8求取字符串长度 + * @param string $str 要计算的字符串编码 + * @return number + */ + public static function utf8_strlen($str) { + $i = $count = 0; + $len = strlen($str); + while ($i < $len) { + $chr = ord($str[$i]); + $count++; + $i++; + if ($i >= $len) + break; + if ($chr & 0x80) { + $chr <<= 1; + while ($chr & 0x80) { + $i++; + $chr <<= 1; + } + } + } + return $count; + } + + /* 以gbk格式截取的字符串编码 + * @param string $string 要截取的字符串编码 + * @param int $start 开始截取 + * @param int $length 截取的长度 + * @param boolean $dot 是否显示省略号 + * @return string + */ + public static function gbk_substr($string, $start, $length = null, $dot = false) { + if (empty($string) || !is_int($start) || ($length && !is_int($length))) { + return ''; + } + $strlen = strlen($string); + $length = $length ? $length : $strlen; + $substr = ''; + $chinese = $word = 0; + for ($i = 0, $j = 0; $i < $start; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $chinese++; + $j++; + } else { + $word++; + } + $j++; + } + $start = $word + 2 * $chinese; + for ($i = $start, $j = $start; $i < $start + $length; $i++) { + if (0xa0 < ord(substr($string, $j, 1))) { + $substr .= substr($string, $j, 2); + $j++; + } else { + $substr .= substr($string, $j, 1); + } + $j++; + } + (strlen($substr) < $strlen) && $dot && $substr .= "..."; + return $substr; + } + + /** + * 以gbk求取字符串长度 + * @param string $str 要计算的字符串编码 + * @return number + */ + public static function gbk_strlen($string) { + $len = strlen($string); + $i = $count = 0; + while ($i < $len) { + ord($string[$i]) > 129 ? $i += 2 : $i++; + $count++; + } + return $count; + } +} \ No newline at end of file diff --git a/wind/utility/WindUtility.php b/wind/utility/WindUtility.php new file mode 100644 index 00000000..c6edf86c --- /dev/null +++ b/wind/utility/WindUtility.php @@ -0,0 +1,82 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindUtility { + + /** + * 递归合并两个数组 + * + * @param array $array1 + * @param array $array2 + * @return array + */ + public static function mergeArray($array1, $array2) { + foreach ($array2 as $key => $value) { + if (!isset($array1[$key]) || !is_array($array1[$key])) { + $array1[$key] = $value; + continue; + } + $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); + } + return $array1; + } + + /** + * 将字符串首字母小写 + * + * @param string $str + * @return string + */ + public static function lcfirst($str) { + if (function_exists('lcfirst')) + return lcfirst($str); + + $str[0] = strtolower($str[0]); + return $str; + } + + /** + * 获得随机数字符串 + * + * @param int $length + * @return string + */ + public static function generateRandStr($length) { + $randstr = ""; + for ($i = 0; $i < (int) $length; $i++) { + $randnum = rand(0, 61); + if ($randnum < 10) { + $randstr .= chr($randnum + 48); + } else if ($randnum < 36) { + $randstr .= chr($randnum + 55); + } else { + $randstr .= chr($randnum + 61); + } + } + return $randstr; + } + + /** + * 通用组装测试验证规则 + * + * @param string $field | 验证字段名称 + * @param string $validator | 验证方法 + * @param array $args | 参数 + * @param string $default | 默认值 + * @param string $message | 错误信息 + * @return array + */ + public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { + return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, + 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); + } + +} + +?> \ No newline at end of file diff --git a/wind/utility/WindValidator.php b/wind/utility/WindValidator.php new file mode 100644 index 00000000..67523f58 --- /dev/null +++ b/wind/utility/WindValidator.php @@ -0,0 +1,344 @@ + 2010-12-22 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindValidator { + + /** + * 验证是否是电话号码 + * 国际区号-地区号-电话号码的格式(在国际区号前可以有前导0和前导+号), + * 国际区号支持0-4位 + * 地区号支持0-6位 + * 电话号码支持4到12位 + * + * @param string $phone 被验证的电话号码 + * @return boolean + */ + public static function isTelPhone($phone) { + return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); + } + + /** + * 验证是否是手机号码 + * 国际区号-手机号码 + * + * @param string $number + * @return boolean + */ + public static function isTelNumber($number) { + return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); + } + + /** + * 验证是否是QQ号码 + * + * @param string $qq + * @return boolean + */ + public static function isQQ($qq) { + return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); + } + + /** + * 验证是否是邮政编码 + * + * @param string $zipcode + * @return boolean + */ + public static function isZipcode($zipcode) { + return 0 < preg_match('/^\d{4,8}$/', $zipcode); + } + + /** + * 验证是否是有合法的email + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasEmail($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的email + * @param string $string + * @return boolean + */ + public static function isEmail($string) { + return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); + } + + /** + * 验证是否有合法的身份证号 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasIdCard($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的身份证号 + * @param string $string + * @return boolean + */ + public static function isIdCard($string) { + return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); + } + + /** + * 验证是否有合法的URL + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasUrl($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的url + * @param string $string + * @return boolean + */ + public static function isUrl($string) { + return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); + } + + /** + * 验证是否有中文 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasChinese($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); + } + + /** + * 验证是否是中文 + * @param string $string + * @return boolean + */ + public static function isChinese($string) { + return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); + } + + /** + * 验证是否有html标记 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasHtml($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的html标记 + * @param string $string + * @return boolean + */ + public static function isHtml($string) { + return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); + } + + /** + * 验证是否有合法的ipv4地址 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasIpv4($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的IP + * @param string $string + * @return boolean + */ + public static function isIpv4($string) { + return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); + } + + /** + * 验证是否有合法的ipV6 + * + * @param string $string + * @param array $matches + * @param boolean $ifAll + * @return boolean + */ + public static function hasIpv6($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| + ::([a-f0-9]{1,4}:){5}| + ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| + (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| + (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| + (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| + (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: + )([a-f0-9]{1,4}:[a-f0-9]{1,4}| + (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} + ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) + )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| + (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: + ) + )\Z/ix', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的ipV6 + * + * @param string $string + * @return boolean + */ + public static function isIpv6($string) { + return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| + ::(?:[a-f0-9]{1,4}:){5}| + (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| + (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| + (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| + (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| + (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: + )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| + (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} + (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) + )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| + (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: + ) + )\Z/ix', $string); + } + + /** + * 验证是否有客户端脚本 + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return boolean + */ + public static function hasScript($string, &$matches = array(), $ifAll = false) { + return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); + } + + /** + * 验证是否是合法的客户端脚本 + * @param string $string + * @return boolean + */ + public static function isScript($string) { + return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); + } + + /** + * 判断是否为空 + * @param string $value + * @return boolean + */ + public static function isEmpty($value) { + return empty($value); + } + + /** + * 验证是否是非负整数 + * @param int $number + * @return boolean + */ + public static function isNonNegative($number) { + return 0 <= (int) $number; + } + + /** + * 验证是否是正数 + * @param int $number + * @return boolean + */ + public static function isPositive($number) { + return 0 < (int) $number; + } + + /** + * 验证是否是负数 + * @param int $number + * @return boolean + */ + public static function isNegative($number) { + return 0 > (int) $number; + } + + /** + * 判断一个元素是否是数组 + * @param mixed $array + * @return boolean + */ + public static function isArray($array) { + return is_array($array); + } + + /** + * 验证是否是不能为空 + * + * @param mixed $value + * @return boolean + */ + public static function isRequired($value) { + return !self::isEmpty($value); + } + + /** + * 判断一个值是否在指定数组中 + * + * @param mixed $needle + * @param array $array + * @param boolean $strict + * @return boolean + */ + public static function inArray($needle, array $array, $strict = true) { + return in_array($needle, $array, $strict); + } + + /** + * 验证字符串的长度 + * @param string $string 要验证的字符串 + * @param string $length 指定的合法的长度 + * @param string $charset 字符编码 + * @return boolean + */ + public static function isLegalLength($string, $length, $charset = 'utf8') { + Wind::import('WIND:component.utility.WindString'); + return WindString::strlen($string, $charset) > (int) $length; + } + + /** + * 在 $string 字符串中搜索与 $regExp 给出的正则表达式相匹配的内容。 + * @param string $regExp 搜索的规则(正则) + * @param string $string 被搜索的 字符串 + * @param array $matches 会被搜索的结果 + * @param boolean $ifAll 是否进行全局正则表达式匹配 + * @return number + */ + private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { + if (true === $ifAll) { + return preg_match_all($regExp, $string, $matches); + } + return preg_match($regExp, $string, $matches); + } + +} \ No newline at end of file diff --git a/wind/utility/date/WindDate.php b/wind/utility/date/WindDate.php new file mode 100644 index 00000000..7c714a28 --- /dev/null +++ b/wind/utility/date/WindDate.php @@ -0,0 +1,272 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * 日期的换算与计算 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + */ +class WindDate { + /** + * 获取时区 + * @return string + */ + public static function getTimeZone() { + return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); + } + /** + * 设置时区 + * @param string $timezone 时区 + */ + public static function setTimezone($timezone) { + function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); + } + /** + * 格式化输出 + * @param string $format 格式化 + * @param int $dateTime unix时间戳 + * @return string + */ + public static function format($format = null, $dateTime = null) { + return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); + } + /** + * 获取日期的某部分 + * @param string $interval 字符串表达式 ,时间间隔类型 + * @param mixed $dateTime 表示日期的文字 + * @return string 返回日期的某部分 + */ + public static function datePart($interval, $dateTime = null) { + return date($interval, self::getTimeStamp($dateTime)); + } + /** + * 获取两个日期的差 + * @param string $interval 返回两个日期差的间隔类型 + * @param mixed $startDateTime 开始日期 + * @param mixed $endDateTime 结束日期 + * @return string + */ + public static function dateDiff($interval, $startDateTime, $endDateTime) { + $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); + $retval = 0; + switch ($interval) { + case "y": + $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; + case "m": + $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; + case "w": + $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; + case "d": + $retval = bcdiv($diff, (60 * 60 * 24));break; + case "h": + $retval = bcdiv($diff, (60 * 60));break; + case "n": + $retval = bcdiv($diff, 60);break; + case "s": + default:$retval = $diff;break; + } + return $retval; + } + /** + * 返回向指定日期追加指定间隔类型的一段时间间隔后的日期 + * @param string $interval 字符串表达式,是所要加上去的时间间隔类型。 + * @param int $value 数值表达式,是要加上的时间间隔的数目。其数值可以为正数(得到未来的日期),也可以为负数(得到过去的日期)。 + * @param string $dateTime 表示日期的文字,这一日期还加上了时间间隔。 + * @param mixed $format 格式化输出 + * @return string 返回追加后的时间 + */ + public static function dateAdd($interval, $value, $dateTime, $format = null) { + $date = getdate(self::getTimeStamp($dateTime)); + switch ($interval) { + case "y": + $date["year"] += $value;break; + case "q": + $date["mon"] += ($value * 3);break; + case "m": + $date["mon"] += $value;break; + case "w": + $date["mday"] += ($value * 7);break; + case "d": + $date["mday"] += $value;break; + case "h": + $date["hours"] += $value;break; + case "n": + $date["minutes"] += $value;break; + case "s": + default:$date["seconds"] += $value;break; + } + return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); + } + /** + * 得到一年中每个月真实的天数 + * @param string $year 需要获得的月份天数的年份 + * @return array 每月的天数组成的数组 + */ + public static function getRealDaysInMonthsOfYear($year) { + $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + if (self::isLeapYear($year)) { + $months[1] = 29; + } + return $months; + } + /** + * 获取该月的天数 + * @param int $month 月份 + * @param int $year 年份 + * @return int + */ + public static function getDaysInMonth($month, $year) { + if (1 > $month || 12 < $month) { + return 0; + } + if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { + return 0; + } + return $daysInmonths[$month - 1]; + } + /** + * 获取该年的天数 + * @return int + */ + public static function getDaysInYear($year) { + return self::isLeapYear($year) ? 366 : 365; + } + /** + * 取得RFC格式的日期与时间 + * @return string + */ + public static function getRFCDate($date = null) { + $time = $date ? is_int($date) ? $date : strtotime($date) : time(); + $tz = date('Z', $time); + $tzs = ($tz < 0) ? '-' : '+'; + $tz = abs($tz); + $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; + return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); + } + /** + * 取得中国日期时间 + * @param int $time + * @return string + */ + public static function getChinaDate($time = null) { + list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); + return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); + } + /** + * 取得中国的星期 + * @param int $week 处国人的星期,是一个数值 + * @return string + */ + public static function getChinaWeek($week = null) { + $week = $week ? $week : (int) date('w', time()); + $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); + return $weekMap[$week]; + } + /** + * 取得一天中的时段 + * @param int $hour 小时 + * @return string + */ + public static function getPeriodOfTime($hour = null) { + $hour = $hour ? $hour : (int) date('G', time()); + $period = ''; + if (0 <= $hour && 6 > $hour) { + $period = '凌晨'; + } elseif (6 <= $hour && 8 > $hour) { + $period = '早上'; + } elseif (8 <= $hour && 11 > $hour) { + $period = '上午'; + } elseif (11 <= $hour && 13 > $hour) { + $period = '中午'; + } elseif (13 <= $hour && 15 > $hour) { + $period = '响午'; + } elseif (15 <= $hour && 18 > $hour) { + $period = '下午'; + } elseif (18 <= $hour && 20 > $hour) { + $period = '傍晚'; + } elseif (20 <= $hour && 22 > $hour) { + $period = '晚上'; + } elseif (22 <= $hour && 23 >= $hour) { + $period = '深夜'; + } + return $period; + } + /** + * 获取UTC日期格式 + * @param mixed $dateTime + * @return string + */ + public static function getUTCDate($dateTime = null) { + $oldTimezone = self::getTimezone(); + if ('UTC' !== strtoupper($oldTimezone)) { + self::setTimezone('UTC'); + } + $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); + if ('UTC' !== strtoupper($oldTimezone)) { + self::setTimezone($oldTimezone); + } + return $date; + } + /** + * 获取微秒数 + * @return number + */ + public static function getMicroTime($get_as_float = null,$mircrotime = null) { + return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); + } + /** + * 判断是否是闰年 + * @param int $year + * @return string + */ + public static function isLeapYear($year) { + if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { + return true; + } + return false; + } + public static function getTimeStamp($dateTime = null){ + return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); + } + + /** + * @param int $time 当前时间戳 + * @param int $timestamp 比较的时间戳 + * @param string $format 格式化当前时间戳 + * @param array $type 要返回的时间类型 + * @return array + */ + public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { + $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); + $timestamp = $timestamp ? $timestamp : time(); + $compareTime = strtotime(self::format('Y-m-d',$timestamp)); + $currentTime = strtotime(self::format('Y-m-d',$time)); + $decrease = $timestamp - $time; + $result = self::format($format,$time); + if (0 >= $decrease) { + return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); + } + if ($currentTime == $compareTime) { + if (1 == $type) { + if (60 >= $decrease) { + return array($decrease . $timelang['second'], $result); + } + return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); + } + return array(self::format('H:i',$time), $result); + } elseif ($currentTime == $compareTime - 86400) { + return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); + } elseif ($currentTime == $compareTime - 172800) { + return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); + } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { + return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); + } + return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); + } +} \ No newline at end of file diff --git a/wind/utility/date/WindGeneralDate.php b/wind/utility/date/WindGeneralDate.php new file mode 100644 index 00000000..3e52d67a --- /dev/null +++ b/wind/utility/date/WindGeneralDate.php @@ -0,0 +1,248 @@ + 2010-12-16 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ +/** + * 是将日期转化为一个对象去操作 + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qian Su + * @version $Id$ + * @package + * tags + */ +class WindGeneralDate { + /** + * @var int 填充展示 + */ + const FILL = 0; + /** + * @var int 数字展示 + */ + const DIGIT = 1; + /** + * @var int 文本展示 + */ + const TEXT = 2; + /** + * @var string 默认格式化 + */ + const DEFAULT_FORMAT = 'Y-m-d H:i:s'; + /** + * @var int unix时间戳 + */ + private $time = 0; + + /** + * 根据输入的日期格式转化为时间戳进行属性time初始化 + * + * mktime函数,在只有输入一个年份的时候,就会默认转化为上一年的最后一天,输入一个月份并且缺省输入day的时候, + * 会转化为上个月的最后一天。所以这种情况需要注意。 + * 如果该构造函数没有参数传入的时候,得到的日期不是期望的当前日期,而是上两年的11月的30日 + * + * 如果月份为空:如果年份为空,则取当前月份;否则取1 + * 如果日期为空:如果年份为空,则取当前日期,否则取1 + * 如果小时为空:如果年份为空,则取当前小时 + * 如果分为空:如果年份为空,则取当前分 + * 如果秒为空:如果年份为空,则取当前秒 + * 如果年份为空:取当前年份 + * + * @param int $year 年 + * @param int $month 月 + * @param int $day 日 + * @param int $hours 小时 + * @param int $minutes 分 + * @param int $second 秒 + */ + public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { + $time = time(); + !$month && ((!$year) ? $month = date('m', $time) : $month = 1); + !$day && ((!$year) ? $day = date('d', $time) : $day = 1); + !$hours && !$year && $hours = date('H', $time); + !$minutes && !$year && $minutes = date('i', $time); + !$second && !$year && $second = date('s', $time); + !$year && $year = date('Y', $time); + $this->time = mktime($hours, $minutes, $second, $month, $day, $year); + } + /** + * 获取当前时间所在月的天数 + * @return string + */ + public function getDaysInMonth() { + return date('t', $this->time); + } + /** + * 获取当前时间所在年的天数 + * @return int 如果是闰年返回366否则返回365 + */ + public function getDaysInYear() { + return $this->isLeapYear() ? 366 : 365; + } + /** + * 所表示当前日期是该年中的第几天。 + * @return int 返回时该年中的第几天 + */ + public function getDayOfYear() { + return date('z', $this->time) + 1; + } + /** + * 表示当前日期为该月中的第几天。 + * @return int + */ + public function getDayOfMonth() { + return date('j', $this->time); + } + /** + * 表示当前日期是该星期中的第几天。 + * @return int + */ + public function getDayOfWeek() { + return date('w', $this->time) + 1; + } + /** + * 判断当前日期所在年的第几周 + * @return int + */ + public function getWeekOfYear() { + return date('W', $this->time); + } + /** + * 获取当前日期的年份 + * @param boolean $format 是否返回四位格式的年份或是两位格式的年份 + * @return string + */ + public function getYear($format = true) { + return date($format ? 'Y' : 'y', $this->time); + } + /** + * 获当前日期的取月份 + * @param int $display 显示类型 + * @return string + */ + public function getMonth($display = self::FILL) { + if(self::FILL == $display){ + return date('m', $this->time); + }elseif(self::DIGIT == $display){ + return date('n', $this->time); + }elseif(self::TEXT == $display){ + return date('M', $this->time); + } + return date('n', $this->time); + } + /** + * 获取当前日期的天数 + * @param string $display 显示类型 + * @return string + */ + public function getDay($display = self::FILL) { + if(self::FILL == $display){ + return date('d', $this->time); + }elseif(self::DIGIT == $display){ + return date('j', $this->time); + }elseif(self::TEXT == $display){ + return date('jS', $this->time); + } + return date('j', $this->time); + } + /** + * 获取当前日期的星期 + * @param string $display 显示类型 + * @return string + */ + public function getWeek($display = self::FILL) { + if(self::FILL == $display || self::DIGIT == $display){ + return date('w', $this->time); + }elseif(self::TEXT == $display){ + return date('D', $this->time); + } + return date('N', $this->time); + } + /** + * 获取当前日期的12小时制时间 + * @param string $display 显示类型 + * @return string + */ + public function get12Hours($display = self::FILL){ + if(self::FILL == $display){ + return date('h', $this->time); + }elseif(self::DIGIT == $display){ + return date('g', $this->time);; + } + return date('h', $this->time); + } + /** + * 获取当前日期的24小时制时间 + * @param string $display 显示类型 + * @return string + */ + public function get24Hours($display = self::FILL){ + if(self::FILL == $display){ + return date('H', $this->time); + }elseif(self::DIGIT == $display){ + return date('G', $this->time);; + } + return date('H', $this->time); + } + /** + * 获取当前日期的分钟 + * @return string + */ + public function getMinutes() { + return date('i', $this->time); + } + /** + * 获取当前日期的秒数 + * @return string + */ + public function getSeconds() { + return date('s', $this->time); + } + /** + * 获取当前日期的本地时区 + * @return string + */ + public function getLocalTimeZone() { + return date('T', $this->time); + } + /** + * 重新设置当前日期与时间 + * @param string | int $time + */ + public function setTime($time) { + if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { + $this->time = $time; + } + } + /** + * 取得当前日期时间对象 + * @return WindDate + */ + public function getNow() { + $date = getdate($this->time); + return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); + } + /** + * 对象转化为字符串,魔术方法 + * @return string + */ + public function __toString() { + return $this->toString(); + } + /** + * 格式化时间输出 + * @param string $format 需要输出的格式 + * @return string + */ + public function toString($format = null) { + return date($format ? $format : self::DEFAULT_FORMAT, $this->time); + } + /** + * 判断是否是闰年 + * @return string 返回1或是0 + */ + public function isLeapYear() { + return date('L', $this->time); + } +} \ No newline at end of file diff --git a/wind/utility/json/WindDecoder.php b/wind/utility/json/WindDecoder.php new file mode 100644 index 00000000..17e3342b --- /dev/null +++ b/wind/utility/json/WindDecoder.php @@ -0,0 +1,235 @@ + +* @author Matt Knapp +* @author Brett Stimmerman +* @copyright 2005 Michal Migurski +* @license http://www.opensource.org/licenses/bsd-license.php +* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 +*/ + +/** + * CJSON converts PHP data to and from JSON format. + * + * @author Michal Migurski + * @author Matt Knapp + * @author Brett Stimmerman + * @version $Id$ + * @package system.web.helpers + * @since 1.0 + */ +class WindDecoder { + const JSON_SLICE = 1; + const JSON_IN_STR = 2; + const JSON_IN_ARR = 4; + const JSON_IN_OBJ = 8; + const JSON_IN_CMT = 16; + public static function decode($str, $useArray = true) { + $str = strtolower(self::reduceString($str)); + if ('true' == $str) { + return true; + } elseif ('false' == $str) { + return false; + } elseif ('null' == $str) { + return null; + } elseif (is_numeric($str)) { + return (float)$str == (integer)$str ? (integer) $str : (float) $str; + }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ + return self::jsonToString($str); + }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ + return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); + } + return false; + } + protected static function jsonToString($string) { + $delim = substr($string, 0, 1); + $chrs = substr($string, 1, -1); + $decodeStr = ''; + for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { + $compare = substr($chrs, $c, 2); + $ordCode = ord($chrs{$c}); + if('\b' == $compare){ + $decodeStr .= chr(0x08); + ++$c; + }elseif('\t' == $compare){ + $decodeStr .= chr(0x09); + ++$c; + }elseif('\n' == $compare){ + $decodeStr .= chr(0x0A); + ++$c; + }elseif('\f' == $compare){ + $decodeStr .= chr(0x0C); + ++$c; + }elseif('\r' == $compare){ + $decodeStr .= chr(0x0D); + ++$c; + }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ + if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { + $decodeStr .= $chrs{++$c}; + } + }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); + $decodeStr .= self::utf16beToUTF8($utf16); + $c += 5; + }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ + $decodeStr .= $chrs{$c}; + }elseif(0xC0 == ($ordCode & 0xE0)){ + $decodeStr .= substr($chrs, $c, 2); + ++$c; + }elseif(0xE0 == ($ordCode & 0xF0)){ + $decodeStr .= substr($chrs, $c, 3); + $c += 2; + }elseif(0xF0 == ($ordCode & 0xF8)){ + $decodeStr .= substr($chrs, $c, 4); + $c += 3; + }elseif(0xF8 == ($ordCode & 0xFC)){ + $decodeStr .= substr($chrs, $c, 5); + $c += 4; + }elseif(0xFC == ($ordCode & 0xFE)){ + $decodeStr .= substr($chrs, $c, 6); + $c += 5; + } + } + return $decodeStr; + } + protected static function jsonToArray($str) { + return self::complexConvert($str,true); + } + protected static function jsonToObject($str) { + return self::complexConvert($str,false); + } + protected static function complexConvert($str,$useArray = true){ + if ('[' == $str{0}) { + $stk = array(self::JSON_IN_ARR); + $arr = array(); + } else { + $obj = $useArray ? array() : new stdClass(); + $stk = array(self::JSON_IN_OBJ); + } + array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); + $chrs = substr($str, 1, -1); + $chrs = self::reduceString($chrs); + if ('' == $chrs) { + return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; + } + for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + if (reset($stk) == self::JSON_IN_ARR) { + array_push($arr, self::decode($slice, $useArray)); + } elseif (reset($stk) == self::JSON_IN_OBJ) { + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + $key = self::decode($parts[1], $useArray); + $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); + } + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { + array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { + array_pop($stk); + } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, + self::JSON_IN_ARR, self::JSON_IN_OBJ))) { + array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); + } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { + array_pop($stk); + } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, + self::JSON_IN_ARR, self::JSON_IN_OBJ))) { + array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { + array_pop($stk); + } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, + self::JSON_IN_ARR, self::JSON_IN_OBJ))) { + array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { + array_pop($stk); + for ($i = $top['where']; $i <= ++$c; ++$i){ + $chrs = substr_replace($chrs, ' ', $i, 1); + } + } + + } + if (self::JSON_IN_ARR == reset($stk)) { + return $arr; + } elseif (self::JSON_IN_OBJ == reset($stk)) { + return $obj; + } + return false; + } + + protected static function unicodeToUTF8(&$str) { + $utf8 = ''; + foreach ($str as $unicode) { + if ($unicode < 128) { + $utf8 .= chr($unicode); + } elseif ($unicode < 2048) { + $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); + $utf8 .= chr(128 + ($unicode % 64)); + } else { + $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); + $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); + $utf8 .= chr(128 + ($unicode % 64)); + } + } + return $utf8; + } + + protected static function reduceString($str) { + return trim(preg_replace(array( + '#^\s*//(.+)$#m', + '#^\s*/\*(.+)\*/#Us', + '#/\*(.+)\*/\s*$#Us'), + '', $str)); + } + + protected static function utf16beToUTF8(&$str) { + return self::unicodeToUTF8(unpack('n*', $str)); + } + +} \ No newline at end of file diff --git a/wind/utility/json/WindEncoder.php b/wind/utility/json/WindEncoder.php new file mode 100644 index 00000000..289a7b63 --- /dev/null +++ b/wind/utility/json/WindEncoder.php @@ -0,0 +1,202 @@ + +* @author Matt Knapp +* @author Brett Stimmerman +* @copyright 2005 Michal Migurski +* @license http://www.opensource.org/licenses/bsd-license.php +* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 +*/ + +/** + * CJSON converts PHP data to and from JSON format. + * + * @author Michal Migurski + * @author Matt Knapp + * @author Brett Stimmerman + * @version $Id$ + * @package system.web.helpers + * @since 1.0 + */ +class WindEncoder { + public static $charset = 'utf-8'; + /** + * @param mixed $var + * @return string + */ + public static function encode($value) { + switch (gettype($value)) { + case 'boolean': + return $value ? 'true' : 'false'; + case 'NULL': + return 'null'; + case 'integer': + return (int) $value; + case 'double': + case 'float': + return (float) $value; + case 'string': + return self::stringToJson($value); + case 'array': + return self::arrayToJson($value); + case 'object': + return self::objectToJson($value); + default: + return ''; + } + return ''; + } + /** + * 将字符串转化成json格式对象 + * @param string $string + * @return string + */ + protected static function stringToJson($string) { + if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { + $string = iconv($enc, 'UTF-8', $string); + } + $ascii = ''; + $strlen = strlen($string); + for ($c = 0; $c < $strlen; ++$c) { + $ordVar = ord($string{$c}); + if (0x08 == $ordVar) { + $ascii .= '\b'; + } elseif (0x09 == $ordVar) { + $ascii .= '\t'; + } elseif (0x0A == $ordVar) { + $ascii .= '\n'; + } elseif (0x0C == $ordVar) { + $ascii .= '\f'; + } elseif (0x0D == $ordVar) { + $ascii .= '\r'; + } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { + $ascii .= '\\' . $string{$c}; + } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { + $ascii .= $string{$c}; //ASCII + } elseif (0xC0 == ($ordVar & 0xE0)) { + $char = pack('C*', $ordVar, ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } elseif (0xE0 == ($ordVar & 0xF0)) { + $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } elseif (0xF0 == ($ordVar & 0xF8)) { + $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } elseif (0xF8 == ($ordVar & 0xFC)) { + $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } elseif (0xFC == ($ordVar & 0xFE)) { + $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); + $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); + } + } + return '"' . $ascii . '"'; + } + /** + * 将数组转化成json格式对象 + * @param array $array + * @return string + */ + protected static function arrayToJson(array $array) { + if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { + return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; + } + return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; + } + /** + * 将对象转化成json格式对象 + * @param string $object + * @return string + */ + protected static function objectToJson($object) { + if ($object instanceof Traversable) { + $vars = array(); + foreach ($object as $k => $v) { + $vars[$k] = $v; + } + } else { + $vars = get_object_vars($object); + } + return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; + } + + protected static function nameValue($name, $value) { + return self::encode(strval($name)) . ':' . self::encode($value); + } + + protected static function utf8ToUTF16BE(&$string, $bom = false) { + $out = $bom ? "\xFE\xFF" : ''; + if (function_exists('mb_convert_encoding')) { + return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); + } + $uni = self::utf8ToUnicode($string); + foreach ($uni as $cp) { + $out .= pack('n', $cp); + } + return $out; + } + + protected static function utf8ToUnicode(&$string) { + $unicode = $values = array(); + $lookingFor = 1; + for ($i = 0, $length = strlen($string); $i < $length; $i++) { + $thisValue = ord($string[$i]); + if ($thisValue < 128) { + $unicode[] = $thisValue; + } else { + if (count($values) == 0) { + $lookingFor = ($thisValue < 224) ? 2 : 3; + } + $values[] = $thisValue; + if (count($values) == $lookingFor) { + $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; + $values = array(); + $lookingFor = 1; + } + } + } + return $unicode; + } + +} \ No newline at end of file diff --git a/wind/viewer/AbstractWindTemplateCompiler.php b/wind/viewer/AbstractWindTemplateCompiler.php new file mode 100644 index 00000000..23e15608 --- /dev/null +++ b/wind/viewer/AbstractWindTemplateCompiler.php @@ -0,0 +1,128 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindTemplateCompiler extends WindHandlerInterceptor { + + protected $tags = array(); + + /** + * @var WindViewTemplate + */ + protected $windViewTemplate = null; + + /** + * @var WindViewerResolver + */ + protected $windViewerResolver = null; + + protected $request = null; + + protected $response = null; + + /** + * 初始化标签解析器 + * @param string $tagContent + * @param WindViewTemplate $windViewTemplate + * @param WindViewerResolver $windViewerResolver + * @param WindHttpRequest $request + * @param WindHttpResponse $response + */ + public function __construct($tags, $windViewTemplate, $windViewerResolver, $request, $response) { + $this->tags = $tags; + $this->windViewTemplate = $windViewTemplate; + $this->windViewerResolver = $windViewerResolver; + $this->request = $request; + $this->response = $response; + } + + /** + * 模板编译方法 + * @param string $content | 模板内容 + * @param WindViewTemplate $windViewTemplate | 模板编译引擎 + * @return string | 输出编译后结果 + */ + abstract public function compile($key, $content); + + /** + * 编译前预处理 + */ + protected function preCompile() {} + + /** + * 编译后处理结果 + */ + protected function postCompile() {} + + /** + * 返回该标签支持的属性信息 + */ + protected function getProperties() { + return array(); + } + + /** + * 解析属性值 + * + * @param string $content + */ + protected function compileProperty($content) { + foreach ($this->getProperties() as $value) { + if ($value) { + preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', + $content, $result); + if ($result) + $this->$value = trim(str_replace($result[1], '', $result[0])); + } + } + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + if ($this->windViewTemplate === null) + return; + $this->preCompile(); + foreach ($this->tags as $key => $value) { + if (!$value[0] || !$value[1]) + continue; + $this->compileProperty($value[1]); + $_output = $this->compile($value[0], $value[1]); + $this->windViewTemplate->setCompiledBlockData($value[0], $_output); + } + $this->postCompile(); + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() {} + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::handle() + */ + public function handle() { + $args = func_get_args(); + call_user_func_array(array($this, 'preHandle'), $args); + if (null !== ($handler = $this->interceptorChain->getHandler())) { + call_user_func_array(array($handler, 'handle'), $args); + } + call_user_func_array(array($this, 'postHandle'), $args); + } + + /** + * @return WindViewTemplate + */ + protected function getWindViewTemplate() { + return $this->windViewTemplate; + } + +} + +?> \ No newline at end of file diff --git a/wind/viewer/AbstractWindViewTemplate.php b/wind/viewer/AbstractWindViewTemplate.php new file mode 100644 index 00000000..fb8b9915 --- /dev/null +++ b/wind/viewer/AbstractWindViewTemplate.php @@ -0,0 +1,72 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindViewTemplate extends WindModule { + const SUPPORT_TAGS = 'support-tags'; + const TAG = 'tag'; + const REGEX = 'regex'; + const COMPILER = 'compiler'; + const PATTERN = 'pattern'; + + /** + * 对模板内容进行编译 + * @param string $content + * @param WindViewerResolver $windViewerResolver + */ + abstract protected function doCompile($content, $windViewerResolver = null); + + /** + * 进行视图渲染 + * + * + * @param string $templateFile | 模板文件 + * @param WindViewerResolver $windViewerResolver + */ + public function compile($templateFile, $windViewerResolver) { + $_output = $this->getTemplateFileContent($templateFile); + $_output = $this->compileDelimiter($_output); + $_output = $this->doCompile($_output, $windViewerResolver); + return $_output; + } + + /** + * @param string content + * @return string $content + */ + protected function compileDelimiter($content) { + $content = str_replace(array('', '#-->'), '?>', $content); + return $content; + } + + /** + * 获得模板文件内容,目前只支持本地文件获取 + * @param string $templateFile + */ + private function getTemplateFileContent($templateFile) { + $_output = ''; + if ($fp = @fopen($templateFile, 'r')) { + while (!feof($fp)) { + $_output .= fgets($fp, 4096); + } + fclose($fp); + } else + throw new WindViewException('Unable to open the template file \'' . $templateFile . '\'.'); + return $_output; + } + + /** + * 返回模板支持的标签 + * array('tagName'=>array('tag','compiler')) + * @return array + */ + protected function getTags() { + return $this->getConfig(self::SUPPORT_TAGS); + } +} +?> \ No newline at end of file diff --git a/wind/viewer/IWindView.php b/wind/viewer/IWindView.php new file mode 100644 index 00000000..8f80ff23 --- /dev/null +++ b/wind/viewer/IWindView.php @@ -0,0 +1,20 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindView { + + /** + * 视图渲染 + * + * @param WindForward $forward + * @param WindUrlBasedRouter $router + */ + public function render(); + +} + +?> \ No newline at end of file diff --git a/wind/viewer/IWindViewerResolver.php b/wind/viewer/IWindViewerResolver.php new file mode 100644 index 00000000..994a92b6 --- /dev/null +++ b/wind/viewer/IWindViewerResolver.php @@ -0,0 +1,26 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindViewerResolver { + + /** + * 设置视图变量信息 + * + * @param array $vars + * @param string $key + */ + public function windAssign($vars, $key = ''); + + /** + * 获取模板内容与变量信息 + */ + public function windFetch($template = ''); + +} \ No newline at end of file diff --git a/wind/viewer/WindLayout.php b/wind/viewer/WindLayout.php new file mode 100644 index 00000000..543e4ebc --- /dev/null +++ b/wind/viewer/WindLayout.php @@ -0,0 +1,122 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindLayout extends WindModule { + /* 编译结果缓存 */ + protected $blockKey = ""; + /** + * 定义主题包的位置 + * @var string + */ + private $theme; + /** + * javascript集合 + * @var string + */ + private $script; + /** + * css 集合 + * @var string + */ + private $css; + /** + * 布局文件的位置 + * @var string + */ + private $layout; + /** + * @var array + */ + private $segments = array(); + /** + * @var WindViewerResolver + */ + private $viewer = null; + + /** + * @param string $layoutFile + */ + public function __construct($layoutFile = '') { + $this->setLayoutFile($layoutFile); + } + + /** + * 解析布局文件 + * @param WindViewerResolver $viewer + */ + public function parser($viewer) { + $this->viewer = $viewer; + $content = ''; + ob_start(); + if ($this->layout) { + list($tpl) = $this->viewer->compile($this->layout); + if (!@include ($tpl)) { + throw new WindViewException('[component.viewer.WindLayout.parser] layout file ' . $tpl, + WindViewException::VIEW_NOT_EXIST); + } + } else + $this->content(); + $content = ob_get_clean(); + foreach ($this->segments as $key => $value) { + if ($key) + $content = str_replace("", $value[1], $content); + } + $content = preg_replace('/(<\/body>)/i', $this->script . '\\1', $content); + //$content = preg_replace('/<\/head>/i', $this->css . '', $content); + return $content; + } + + /** + * 设置切片内容 + * @param string $template + */ + public function segment($template) { + $this->segments[$template] = $this->viewer->compile($template, '', true); + echo ""; + } + + /** + * 当前模板内容 + * @param string $template + */ + public function content() { + $template = $this->viewer->getWindView()->templateName; + $this->segment($template); + } + + /** + * @param string $theme + */ + public function setTheme($theme) { + $this->theme = $theme; + } + + /** + * @param string $layout + */ + public function setLayout($layout) { + $this->layout = $layout; + } + + /** + * @param string $script + */ + public function setScript($script) { + $this->script .= $script; + } + + /** + * @param string $css + */ + public function setCss($css) { + $this->css .= $css; + } + +} \ No newline at end of file diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php new file mode 100644 index 00000000..bd0dcd89 --- /dev/null +++ b/wind/viewer/WindView.php @@ -0,0 +1,168 @@ + + * + * + * + * + * + * + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindView extends WindModule implements IWindView { + /** + * 模板路径信息 + * + * @var string + */ + public $templateDir; + /** + * 模板文件的扩展名 + * + * @var string + */ + public $templateExt; + /** + * 模板名称 + * + * @var string + */ + public $templateName; + /** + * 是否对模板变量进行html字符过滤 + * @var boolean + */ + public $htmlspecialchars = true; + /** + * 是否开启模板编译 + * 00: 0 关闭,不进行模板编译 + * 01: 1 进行模板编译 + * @var boolean + */ + public $isCompile = 0; + /** + * 编译目录 + * @var string + */ + public $compileDir; + /** + * 编译脚本后缀 + * @var string + */ + public $compileExt = 'tpl'; + /** + * 布局文件 + * @var string + */ + public $layout; + /** + * 主题包目录 + * @var string + */ + public $theme; + + /** + * 视图解析引擎 + * @var WindViewerResolver + */ + protected $viewResolver = null; + + /** + * 视图渲染 + * @param boolean $display + */ + public function render($display = false) { + if (!$this->templateName) + return; + + //TODO 其他输出类型 + $viewResolver = $this->_getViewResolver($this); + $viewResolver->windAssign(Wind::getApp()->getResponse()->getData($this->templateName)); + if ($display === false) { + $this->getResponse()->setBody($viewResolver->windFetch(), $this->templateName); + } else + echo $viewResolver->windFetch(); + } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + if ($this->_config) { + $this->templateDir = $this->getConfig('template-dir', '', $this->templateDir); + $this->templateExt = $this->getConfig('template-ext', '', $this->templateExt); + $this->compileDir = $this->getConfig('compile-dir', '', $this->compileDir); + $this->compileExt = $this->getConfig('compile-ext', '', $this->compileExt); + $this->isCompile = $this->getConfig('is-compile', '', $this->isCompile); + $this->htmlspecialchars = $this->getConfig('htmlspecialchars', '', + $this->htmlspecialchars); + } + } + + /** + * 模板路径解析 + * 根据模板的逻辑名称,返回模板的绝对路径信息 + * + * @param string $templateName + * @param string $templateExt + * @return string | false + */ + public function getViewTemplate($template = '', $ext = '') { + if (!$template) { + $template = $this->templateName; + } + !$ext && $ext = $this->templateExt; + return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); + } + + /** + * 模板编译路径解析 + * 根据模板的逻辑名称,返回模板的绝对路径信息 + * + * @param string $templateName + * @param string $templateExt + * @return string | false + */ + public function getCompileFile($template = '') { + if (!$this->compileDir) + return; + if (!$template) { + $template = $this->templateName; + } + $dir = Wind::getRealDir($this->compileDir, true); + if (!is_dir($dir)) + throw new WindViewException( + '[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); + $_tmp = explode('.', $template); + foreach ($_tmp as $_dir) { + !is_dir($dir) && @mkdir($dir); + $dir .= DIRECTORY_SEPARATOR . $_dir; + } + return $this->compileExt ? $dir . '.' . $this->compileExt : $dir; + } + + /** + * @return WindViewerResolver + */ + public function getViewResolver() { + if (null !== $this->viewResolver) + return $this->viewResolver; + $this->_getViewResolver(); + $this->viewResolver->setWindView($this); + if (!$this->getIsCache()) + return $this->viewResolver; + $this->viewResolver = new WindClassProxy($this->viewResolver); + $listener = Wind::import('COM:viewer.listener.WindViewCacheListener'); + $this->viewResolver->registerEventListener('windFetch', new $listener($this)); + return $this->viewResolver; + } +} \ No newline at end of file diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php new file mode 100644 index 00000000..8916f304 --- /dev/null +++ b/wind/viewer/WindViewerResolver.php @@ -0,0 +1,187 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewerResolver extends WindModule implements IWindViewerResolver { + /** + * @var array + */ + protected $vars = array(); + /** + * @var WindView + */ + protected $windView = null; + + /** + * @var WindLayout + */ + protected $windLayout = null; + + /** + * @param WindView $windView + */ + public function __construct($windView = null) { + $this->windView = $windView; + } + + /* (non-PHPdoc) + * @see IWindViewerResolver::windFetch() + */ + public function windFetch($template = '') { + ob_start(); + if (!$template) { + $template = $this->windView->templateName; + $_tpl = $this->windView->getCompileFile($template); + if ($this->checkReCompile()) { + $layout = $this->getWindLayout(); + $layout->setLayout($this->windView->layout); + $layout->setTheme($this->windView->theme); + WindFile::write($_tpl, $layout->parser($this)); + } + } else + list($_tpl) = $this->compile($template); + + WindRender::render($_tpl, Wind::getApp()->getResponse()->getData($template), $this); + return ob_get_clean(); + } + + /* (non-PHPdoc) + * @see IWindViewerResolver::windAssign() + */ + public function windAssign($vars, $key = '') { + /*if ($key === '') + $key = $this->windView->templateName; + $this->vars[$key] = $vars;*/ + } + + /** + * 编译模板并返回编译后模板名称, + * $output==true: 直接返回编译结果,不将结果写入编译文件中 + * $output==false:返回编译文件地址 + * + * @param string $template + * @param string $suffix + * @param boolean $output + * @return string + */ + public function compile($template, $suffix = '', $output = false) { + $templateFile = $this->windView->getViewTemplate($template, $suffix); + if (!is_file($templateFile)) + throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, + WindViewException::VIEW_NOT_EXIST); + + $compileFile = $this->windView->getCompileFile($template); + if (!$this->checkReCompile()) + return array($compileFile, ''); + /* @var $_windTemplate WindViewTemplate */ + $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); + $_output = $_windTemplate->compile($templateFile, $this); + if ($output === false) { + $compileFile = $this->windView->getCompileFile($template); + WindFile::write($compileFile, $_output); + } + return array($compileFile, $_output); + } + + /** + * 检查是否需要重新编译,需要编译返回false,不需要编译返回true + * @return boolean + */ + private function checkReCompile() { + return WIND_DEBUG || $this->getWindView()->isCompile; + } + + /** + * 当前模板内容 + * @param string $template + */ + private function getContent($template = '') { + !$template && $template = $this->windView->templateName; + if ($template) + echo $this->windFetch($template); + } + + /** + * @return WindView + */ + public function getWindView() { + return $this->windView; + } + + /** + * @return WindLayout + */ + public function getWindLayout() { + return $this->_getWindLayout('', $this); + } + +} + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindRender { + + /** + * Convert special characters to HTML entities + * + * @param string $text | + * @return string | string The converted string + */ + public static function encode($text) { + return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); + } + + /** + * Convert special characters to HTML entities + * + * @param array $data + * @return array + */ + public static function encodeArray($data) { + $_tmp = array(); + $_charset = Wind::getApp()->getRequest()->getCharset(); + foreach ($data as $key => $value) { + if (is_string($key)) + $key = htmlspecialchars($key, ENT_QUOTES, $_charset); + if (is_string($value)) + $value = htmlspecialchars($value, ENT_QUOTES, $_charset); + elseif (is_array($value)) + $value = self::encodeArray($value); + $_tmp[$key] = $value; + } + return $_tmp; + } + + /** + * @param string $tpl + * @param array $vars + * @param WindViewerResolver $viewer + * @throws WindViewException + */ + public static function render($tpl, $vars, $viewer) { + @extract($vars, EXTR_REFS); + if (!@include ($tpl)) { + throw new WindViewException( + '[component.viewer.ViewerResolver.render] template name ' . $tpl, + WindViewException::VIEW_NOT_EXIST); + } + } +} \ No newline at end of file diff --git a/wind/viewer/compiler/WindTemplateCompilerAction.php b/wind/viewer/compiler/WindTemplateCompilerAction.php new file mode 100644 index 00000000..801eb5c8 --- /dev/null +++ b/wind/viewer/compiler/WindTemplateCompilerAction.php @@ -0,0 +1,40 @@ + 标签解析脚本 + * 支持属性: action\controller + * + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerAction extends AbstractWindTemplateCompiler { + protected $action = ''; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + return 'getComponent(\'forward\'); + $_tpl_forward->forwardAction(' . $this->action . '); + Wind::getApp()->doDispatch($_tpl_forward, true); ?>'; + } + + /** + * @return string + */ + public function getScript() { + $_tmp = '$_tpl_forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD);' . '$_tpl_forward->setDisplay(true);' . '$_tpl_forward->forwardAnotherAction(\'' . $this->action . '\', \'' . $this->controller . '\');' . '$_tpl_app = $this->getSystemFactory()->getInstance(COMPONENT_WEBAPP);' . '$_tpl_app->doDispatch($_tpl_forward);'; + return $_tmp; + } + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::getProperties() + */ + public function getProperties() { + return array('action'); + } + +} \ No newline at end of file diff --git a/wind/viewer/compiler/WindTemplateCompilerComponent.php b/wind/viewer/compiler/WindTemplateCompilerComponent.php new file mode 100644 index 00000000..27c9cdc3 --- /dev/null +++ b/wind/viewer/compiler/WindTemplateCompilerComponent.php @@ -0,0 +1,149 @@ + + * + * the last known user to change this file in the repository + * @author xiaoxiao + * @version 2011-7-20 xiaoxiao + */ +class WindTemplateCompilerComponent extends AbstractWindTemplateCompiler { + + protected $name = ''; //组件名字 + + + protected $args = ''; //传递给组件的参数 + + + protected $templateDir = ''; //组件调用的模板路径 + + + protected $appConfig = ''; //组件的配置文件 + + protected $appConfigSuffix = 'php';//配置文件的缺省格式 + + + protected $componentPath = ''; //组件的入口地址 + + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + return $this->getScript($content); + } + + /** + * @return string + */ + private function getScript($content) { + $params = $this->matchConfig($content); + if (!isset($params['name']) || !isset($params['componentPath'])) throw new WindException('组件编译错误!'); + $content = "rebuildConfig($params) . + (isset($params['args']) ? $this->registerUrlParams($params) : '') . + "\$componentPath = Wind::getRealDir('" . $params['componentPath'] . "');\r\n" . + "Wind::register(\$componentPath, '" . $params['name'] . "');\r\n" . + "Wind::run('" . $params['name'] . "', \$config);\r\n?>"; + return $content; + } + + /** + * 编译获得配置文件 + * @param array $params + * @return array + */ + private function rebuildConfig($params) { + $temp = "\$configParser = new WindConfigParser();\r\n" . + "\$configPath = Wind::getRealPath('" . $params['appConfig'] . "', '" . $params['suffix'] . "');\r\n" . + "\$config = \$configParser->parse(\$configPath);\r\n" . + "\$config = \$config['" . $params['name'] . "'];\r\n"; + if (!isset($params['templateDir'])) return $temp; + if (isset($params['args']['m'])) + $temp .= "\$config['modules']['" . $params['args']['m'] . "']['view']['config']['template-dir'] = '" . $params['templateDir'] . "';\r\n"; + else { + $temp .= "foreach(\$config['modules'] as \$key => \$value) {\r\n" . + "\t\$config['modules'][\$key]['view']['config']['template-dir'] = '" . $params['templateDir'] . "';\r\n" . + "}\r\n"; + } + return $temp; + } + + /** + * 注册变量信息 + * + * @param array $params + */ + private function registerUrlParams($params) { + $temp = "\$routerConfig = \$config['router']['config'];\r\n" . + "\$mKey = isset(\$routerConfig['module']['url-param']) ? \$routerConfig['module']['url-param'] : 'm';\r\n" . + "\$cKey = isset(\$routerConfig['controller']['url-param']) ? \$routerConfig['controller']['url-param'] : 'c';\r\n" . + "\$aKey = isset(\$routerConfig['action']['url-param']) ? \$routerConfig['action']['url-param'] : 'a';\r\n" . + "\$_GET[\$mKey] = '" . $params['args']['m'] . "';\r\n" . + "\$_GET[\$cKey] = '" . $params['args']['c'] . "';\r\n" . + "\$_GET[\$aKey] = '" . $params['args']['a'] . "';\r\n"; + unset($params['args']['a'], $params['args']['c'], $params['args']['m']); + foreach ($params['args'] as $key => $value) { + $temp .= "\$_GET['" . $key . "'] = " . (is_array($value) ? $value : "'" . $value . "'" ) . ";\r\n"; + } + return $temp; + } + + /** + * 匹配配置信息 + * + * @param string $content + * @return array + */ + private function matchConfig($content) { + preg_match_all('/(\w+=[\'|"]?[\w|.|:]+[\'|"]?)/', $content, $mathcs); + list($config, $key, $val) = array(array(), '', ''); + foreach ($mathcs[0] as $value) { + list($key, $val) = explode('=', $value); + if (!in_array($key, $this->getProperties()) || !$val) continue; + switch ($key) { + case 'args': + $config['args'] = $this->compileArgs(trim($val, '\'"')); + break; + default: + $config[$key] = trim($val, '\'"'); + break; + } + } + return $config; + } + + /** + * 解析传递给url的参数信息 + * + * @param string $arg + * @return array + */ + private function compileArgs($arg) { + $args = explode(':', $arg); + $urlParams = array(); + list($urlParams['a'], $urlParams['c'], $urlParams['m']) = array('', '', ''); + switch (count($args)) { + case 1: + $urlParams['a'] = $args[0]; + break; + case 2: + list($urlParams['c'], $urlParams['a']) = $args; + break; + case 3: + list($urlParams['m'], $urlParams['c'], $urlParams['a']) = $args; + break; + default: + break; + } + return $urlParams; + } + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::getProperties() + */ + protected function getProperties() { + return array('name', 'templateDir', 'appConfig', 'args', 'componentPath', 'suffix'); + } +} + +?> \ No newline at end of file diff --git a/wind/viewer/compiler/WindTemplateCompilerCss.php b/wind/viewer/compiler/WindTemplateCompilerCss.php new file mode 100644 index 00000000..e541f9c9 --- /dev/null +++ b/wind/viewer/compiler/WindTemplateCompilerCss.php @@ -0,0 +1,23 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerCss extends AbstractWindTemplateCompiler { + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + foreach ($this->windViewTemplate->getCompiledBlockData() as $key => $value) { + $content = str_replace('#' . $key . '#', ($value ? $value : ' '), $content); + } + $this->windViewerResolver->getWindLayout()->setcss($content); + return ''; + } +} + +?> \ No newline at end of file diff --git a/wind/viewer/compiler/WindTemplateCompilerEcho.php b/wind/viewer/compiler/WindTemplateCompilerEcho.php new file mode 100644 index 00000000..d6cfa107 --- /dev/null +++ b/wind/viewer/compiler/WindTemplateCompilerEcho.php @@ -0,0 +1,34 @@ +a|text} //执行编译 + * {@templateName:var|html} + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content); + list($_output, $type) = explode('|', $_output . '|'); + if (strpos($_output, '::') === false && strpos($_output, ':') !== false) { + list($_namespace, $_var) = explode(':', $_output); + $_output = 'Wind::getApp()->getResponse()->getData(\'' . $_namespace . '\', \'' . $_var . '\')'; + } + if (!strcasecmp($type, 'html')) + return ''; + else + return ''; + } +} +?> \ No newline at end of file diff --git a/wind/viewer/compiler/WindTemplateCompilerInternal.php b/wind/viewer/compiler/WindTemplateCompilerInternal.php new file mode 100644 index 00000000..581b42c9 --- /dev/null +++ b/wind/viewer/compiler/WindTemplateCompilerInternal.php @@ -0,0 +1,25 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerInternal extends AbstractWindTemplateCompiler { + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + //TODO php脚本特别解析 + + + return $content; + } + +} + +?> \ No newline at end of file diff --git a/wind/viewer/compiler/WindTemplateCompilerPage.php b/wind/viewer/compiler/WindTemplateCompilerPage.php new file mode 100644 index 00000000..9b9f7292 --- /dev/null +++ b/wind/viewer/compiler/WindTemplateCompilerPage.php @@ -0,0 +1,77 @@ + + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerPage extends AbstractWindTemplateCompiler { + protected $tpl = ''; + + protected $url = ''; + + protected $total = '0'; + + protected $page = '1'; + + protected $count = '0'; + + protected $per = '0'; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + return $this->getPageCode(); + + } + + private function getPageCode() { + empty($this->total) && $this->total = '0'; + empty($this->page) && $this->page = '1'; + empty($this->count) && $this->count = '0'; + empty($this->per) && $this->per = '0'; + empty($this->url) && $this->url = ''; + $strPageCode = 'count . ';' . '$_tplPagePer=(int)' . $this->per . ';' . + '$_tplPageTotal=(int)' . $this->total . ';' . '$_tplPageCurrent=(int)' . $this->page . ';' . + '$_tplPageUrl=(string)"' . addslashes($this->url) . '";' . 'if ($_tplPageCount > 0 && $_tplPagePer > 0) {' . + '$_tplTmpPageTotal = ceil($_tplPageCount / $_tplPagePer);' . + 'if ($_tplPageTotal > $_tplTmpPageTotal) $_tplPageTotal = $_tplTmpPageTotal;' . '}' . + '$_tplPageCurrent > $_tplPageTotal && $_tplPageCurrent = $_tplPageTotal;' . 'if ($_tplPageTotal > 1) {' . + "?>\r\n" . $this->getTplContent() . "\r\n"; + return $strPageCode; + } + + private function getTplContent() { + if ($this->tpl) { + list($compileFile, $content) = $this->windViewerResolver->compile($this->tpl, '', true); + } else { + $content = $this->getDefaultHtml(); + } + return $this->parsePageTags($content); + } + + private function parsePageTags($content) { + $arrPageTags = array('$total', '$page', '$url', '$count'); + $arrPageVars = array('$_tplPageTotal', '$_tplPageCurrent', '$_tplPageUrl', '$_tplPageCount'); + return str_ireplace($arrPageTags, $arrPageVars, $content); + } + + private function getDefaultHtml() { + return ''; + } + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::getProperties() + */ + public function getProperties() { + return array('tpl', 'total', 'page', 'per', 'count', 'url'); + } +} + +?> \ No newline at end of file diff --git a/wind/viewer/compiler/WindTemplateCompilerScript.php b/wind/viewer/compiler/WindTemplateCompilerScript.php new file mode 100644 index 00000000..3894f182 --- /dev/null +++ b/wind/viewer/compiler/WindTemplateCompilerScript.php @@ -0,0 +1,33 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerScript extends AbstractWindTemplateCompiler { + protected $compile = 'true'; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + if ($this->compile === 'false') return $content; + foreach ($this->windViewTemplate->getCompiledBlockData() as $key => $value) { + $content = str_replace('#' . $key . '#', ($value ? $value : ' '), $content); + } + $this->windViewerResolver->getWindLayout()->setScript($content); + return ''; + } + + /** + * 返回该标签支持的属性信息 + */ + protected function getProperties() { + return array('compile'); + } + +} + +?> \ No newline at end of file diff --git a/wind/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/viewer/compiler/WindTemplateCompilerTemplate.php new file mode 100644 index 00000000..21657455 --- /dev/null +++ b/wind/viewer/compiler/WindTemplateCompilerTemplate.php @@ -0,0 +1,55 @@ + + * source: 模板文件源地址 + * suffix: 模板文件后缀 + * load: 是否将编译内容加载到本模板中 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindTemplateCompilerTemplate extends AbstractWindTemplateCompiler { + + protected $source = ''; + + protected $suffix = ''; + + protected $load = 'true'; + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::compile() + */ + public function compile($key, $content) { + if (!$this->source) + return $content; + + preg_match('/^{?\$(\w+)}?$/Ui', $this->source, $_tmp); + if (!empty($_tmp)) { + $_tpl = $this->windViewerResolver->getWindView()->templateName; + $this->source = Wind::getApp()->getResponse()->getData($_tpl, $_tmp[1]); + } + if ($this->load === 'false') { + list($compileFile) = $this->windViewerResolver->compile($this->source, $this->suffix); + if (!empty($_tmp)) + $compileFile = str_replace($this->source, '{$' . $_tmp[1] . '}', $compileFile); + $content = ''; + } else { + list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, + true); + } + return $content; + } + + /* (non-PHPdoc) + * @see AbstractWindTemplateCompiler::getProperties() + */ + public function getProperties() { + return array('source', 'suffix', 'load'); + } + +} + +?> \ No newline at end of file diff --git a/wind/viewer/compiler/WindViewTemplate.php b/wind/viewer/compiler/WindViewTemplate.php new file mode 100644 index 00000000..35c5ce06 --- /dev/null +++ b/wind/viewer/compiler/WindViewTemplate.php @@ -0,0 +1,190 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewTemplate extends AbstractWindViewTemplate { + + const COMPILER_ECHO = 'COM:viewer.compiler.WindTemplateCompilerEcho'; + + protected $compiledBlockData = array(); + + /** + * 模板编译器支持的标签信息 + * + * @var array('targName','args info') + */ + protected $_compilerCache = array(); + + protected $windHandlerInterceptorChain = null; + + /* (non-PHPdoc) + * @see AbstractWindViewTemplate::doCompile() + */ + protected function doCompile($content, $windViewerResolver = null) { + try { + $content = $this->registerTags($content, $windViewerResolver); + if ($this->windHandlerInterceptorChain !== null) { + $this->windHandlerInterceptorChain->getHandler()->handle(); + } + foreach (array_reverse($this->compiledBlockData) as $key => $value) { + if (!$key) + continue; + $content = str_replace($this->getBlockTag($key), ($value ? $value : ' '), $content); + } + $content = preg_replace('/\?>(\s|\n)*?<\?php/i', "\r\n", $content); + return $content; + } catch (Exception $e) { + throw new WindViewException('[component.viewer.WindViewTemplate.doCompile] compile fail.' . $e->getMessage(), + WindViewException::ERROR_SYSTEM_ERROR); + } + } + + /** + * 注册支持的标签并返回注册后的模板内容 + * @param string $content + * @param WindViewerResolver $windViewerResolver + * @return string + */ + private function registerTags($content, $windViewerResolver = null) { + foreach ((array) $this->getTags() as $key => $value) { + $compiler = isset($value[self::COMPILER]) ? $value[self::COMPILER] : ''; + $regex = isset($value[self::PATTERN]) ? $value[self::PATTERN] : ''; + $tag = isset($value[self::TAG]) ? $value[self::TAG] : ''; + if (!$compiler || !$tag) + continue; + if ($regex === '') + $regex = '/<(' . preg_quote($tag) . ')[^<>\n]*(\/>|>[^<>]*<\/\1>)/i'; + $content = $this->creatTagCompiler($content, $compiler, $regex, $windViewerResolver); + } + return $content; + } + + /** + * 创建标签解析器类 + * @param string content | 模板内容 + * @param string compiler | 标签编译器 + * @param string regex | 正则表达式 + * @param WindViewerResolver $windViewerResolver + */ + private function creatTagCompiler($content, $compiler, $regex, $windViewerResolver = null) { + $content = preg_replace_callback($regex, array($this, '_creatTagCompiler'), $content); + if ($this->windHandlerInterceptorChain === null) { + $this->windHandlerInterceptorChain = new WindHandlerInterceptorChain(); + } + $_compilerClass = Wind::import($compiler); + $this->windHandlerInterceptorChain->addInterceptors( + new $_compilerClass($this->_compilerCache, $this, $windViewerResolver, $this->getRequest(), + $this->getResponse())); + $this->_compilerCache = array(); + return $content; + } + + /* (non-PHPdoc) + * @see AbstractWindViewTemplate::getTags() + */ + protected function getTags() { + $_tags['internal'] = $this->createTag('internal', 'COM:viewer.compiler.WindTemplateCompilerInternal', + '/<\?php(.|\n)*?\?>/i'); + $_tags['template'] = $this->createTag('template', 'COM:viewer.compiler.WindTemplateCompilerTemplate'); + $_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', + '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); + $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); + /*标签体增加在该位置*/ + $_tags['page'] = $this->createTag('page', 'COM:viewer.compiler.WindTemplateCompilerPage'); + $_tags['action'] = $this->createTag('action', 'COM:viewer.compiler.WindTemplateCompilerAction'); + $_tags['script'] = $this->createTag('script', 'COM:viewer.compiler.WindTemplateCompilerScript', + '/()*/i'); + //$_tags['link'] = $this->createTag('link', 'COM:viewer.compiler.WindTemplateCompilerCss'); + //$_tags['style'] = $this->createTag('style', 'COM:viewer.compiler.WindTemplateCompilerCss'); + $_tags['component'] = $this->createTag('component', 'COM:viewer.compiler.WindTemplateCompilerComponent'); + /*标签解析结束*/ + $_tags += (array) parent::getTags(); + /*$_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', + '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); + $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i');*/ + return $_tags; + } + + /** + * 创建tag配置 + * @param string $tag + * @param string $class + */ + private function createTag($tag, $class, $pattern = '') { + return array(self::TAG => $tag, self::PATTERN => $pattern, self::COMPILER => $class); + } + + /** + * 将标签匹配到的模板内容设置到缓存中,并返回标识位到模板中进行内容站位 + * @param string $content + * @return string|Ambigous --> + */ + private function _creatTagCompiler($content) { + $_content = $content[0]; + if (!$_content) + return ''; + + $key = $this->getCompiledBlockKey(); + $this->_compilerCache[] = array($key, $_content); + return $this->getBlockTag($key); + } + + /** + * 对模板块存储进行标签处理 + * 将Key串 'HhQWFLtU0LSA3nLPLHHXMtTP3EfMtN3FsxLOR1nfYC5OiZTQri' 处理为 + * + * 在模板中进行位置标识 + * + * @param string $key | 索引 + * @return string|mixed | 处理后结果 + */ + private function getBlockTag($key) { + return '#' . $key . '#'; + } + + /** + * 获得切分后块编译缓存Key值,Key值为一个50位的随机字符串,当产生重复串时继续查找 + * @return string + */ + protected function getCompiledBlockKey() { + $key = WindUtility::generateRandStr(50); + if (key_exists($key, $this->compiledBlockData)) { + return $this->getCompiledBlockKey(); + } + return $key; + } + + /** + * 返回编译后结果,根据Key值检索编译后结果,并返回 + * @param string $key + * @return string + */ + public function getCompiledBlockData($key = '') { + if ($key) + return isset($this->compiledBlockData[$key]) ? $this->compiledBlockData[$key] : ''; + else + return $this->compiledBlockData; + } + + /** + * 根据key值保存编译后的模板块 + * @param string $key | 索引 + * @param string $compiledBlockData | 编译结果 + * @param boolean $isTag | 再结果处理时是否添加php脚本定界符 true 添加 ,flase 不添加 + */ + public function setCompiledBlockData($key, $compiledBlockData) { + if ($key) + $this->compiledBlockData[$key] = $compiledBlockData; + } + +} + +?> \ No newline at end of file diff --git a/wind/viewer/errorPage/404.htm b/wind/viewer/errorPage/404.htm new file mode 100644 index 00000000..b499243e --- /dev/null +++ b/wind/viewer/errorPage/404.htm @@ -0,0 +1,10 @@ + + + + +Insert title here + + + + + \ No newline at end of file diff --git a/wind/viewer/errorPage/default_error.htm b/wind/viewer/errorPage/default_error.htm new file mode 100644 index 00000000..97e2593f --- /dev/null +++ b/wind/viewer/errorPage/default_error.htm @@ -0,0 +1,45 @@ + + + + +{@G:title} + + + +
+ + + + +
+

{$errorHeader}:

+

+ {$key}. {$error}
+

+

You Can Get Help In:

+

{@WindHelper::errorInfo()}

+
+
+ + \ No newline at end of file diff --git a/wind/viewer/exception/WindViewException.php b/wind/viewer/exception/WindViewException.php new file mode 100644 index 00000000..59bfbd9c --- /dev/null +++ b/wind/viewer/exception/WindViewException.php @@ -0,0 +1,30 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewException extends WindException { + + const VIEW_NOT_EXIST = '300'; + const COMPILE_NOT_EXIST = '400'; + + /** + * 自定义异常号的对应异常信息 + * + * @param int $code 异常号 + * @return string 返回异常号对应的异常组装信息原型 + */ + protected function messageMapper($code) { + $messages[self::VIEW_NOT_EXIST] = 'Not exist view template file or Incorrect file path \'$message\''; + $messages[self::COMPILE_NOT_EXIST] = 'Not exist view compile file or Incorrect file path \'$message\''; + return isset($messages[$code]) ? $messages[$code] : '$message'; + } +} + +?> \ No newline at end of file diff --git a/wind/viewer/listener/WindViewCacheListener.php b/wind/viewer/listener/WindViewCacheListener.php new file mode 100644 index 00000000..99a1eef6 --- /dev/null +++ b/wind/viewer/listener/WindViewCacheListener.php @@ -0,0 +1,52 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindViewCacheListener extends WindHandlerInterceptor { + + private $windView = null; + + /** + * Enter description here ... + * @param WindView $windView + */ + public function __construct($windView) { + $this->windView = $windView; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::preHandle() + */ + public function preHandle() { + $data = $this->windView->getViewCache()->get($this->getKey()); + $data = !$data ? null : $data; + return $data; + } + + /** + * 获得保存的key值 + */ + private function getKey() { + $host = Wind::getApp()->getRequest()->getHostInfo(); + $uri = Wind::getApp()->getRequest()->getRequestUri(); + return $host.$uri . '/' . $this->windView->templateName . '.' . $this->windView->templateExt; + } + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() { + $cache = $this->windView->getViewCache(); + $cache->set($this->getKey(), $this->result); + } +} + +?> \ No newline at end of file From 015abc4505be5a018970239a1cd05484b5db29e4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 06:03:30 +0000 Subject: [PATCH 0423/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2495 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/filter/WindActionFilter.php | 86 ++++++++++++++++++++ wind/filter/WindFilter.php | 11 +++ wind/filter/WindFilterChain.php | 63 +++++++++++++++ wind/filter/WindHandlerInterceptor.php | 43 ++++++++++ wind/filter/WindHandlerInterceptorChain.php | 87 +++++++++++++++++++++ 5 files changed, 290 insertions(+) create mode 100644 wind/filter/WindActionFilter.php create mode 100644 wind/filter/WindFilter.php create mode 100644 wind/filter/WindFilterChain.php create mode 100644 wind/filter/WindHandlerInterceptor.php create mode 100644 wind/filter/WindHandlerInterceptorChain.php diff --git a/wind/filter/WindActionFilter.php b/wind/filter/WindActionFilter.php new file mode 100644 index 00000000..adbad79e --- /dev/null +++ b/wind/filter/WindActionFilter.php @@ -0,0 +1,86 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class WindActionFilter extends WindHandlerInterceptor { + protected $_vars = array(); + /** + * @var WindForward + */ + protected $forward = null; + /** + * @var WindErrorMessage + */ + protected $errorMessage = null; + + /** + * @param WindForward $forward + * @param WindErrorMessage $errorMessage + */ + public function __construct($forward, $errorMessage) { + $this->forward = $forward; + $this->errorMessage = $errorMessage; + $args = func_get_args(); + unset($args[0], $args[1]); + foreach ($args as $key => $value) + property_exists(get_class($this), $key) && $this->$key = $value; + $this->_vars = $forward->getVars(); + } + + /** + * 设置模板数据 + * @param string|array|object $data + * @param string $key + * @return + */ + protected function setOutput($data, $key = '') { + $this->forward->setVars($data, $key); + } + + /** + * 设置模板数据 + * @param string|array|object $data + * @param string $key + * @return + */ + protected function setGlobal($data, $key = '') { + $this->forward->setVars($data, $key, true); + } + + /** + * 获得输入数据 + * 如果输入了回调方法则返回数组: + * 第一个值:value + * 第二个值:验证结果 + * @param string $name input name + * @param string $type input type (GET POST COOKIE) + * @param string $callback | validation for input + * @return array | string + */ + protected function getInput($name, $type = '', $callback = array()) { + $value = ''; + switch (strtolower($type)) { + case 'form': + $value = $this->getRequest()->getData($name); + break; + case IWindRequest::INPUT_TYPE_GET: + $value = $this->getRequest()->getGet($name); + break; + case IWindRequest::INPUT_TYPE_POST: + $value = $this->getRequest()->getPost($name); + break; + case IWindRequest::INPUT_TYPE_COOKIE: + $value = $this->getRequest()->getCookie($name); + break; + default: + $value = $this->getRequest()->getAttribute($name); + } + return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; + } + +} + +?> \ No newline at end of file diff --git a/wind/filter/WindFilter.php b/wind/filter/WindFilter.php new file mode 100644 index 00000000..827cc218 --- /dev/null +++ b/wind/filter/WindFilter.php @@ -0,0 +1,11 @@ + + * @author xiaoxia xu + * @version $Id$ + * @package + */ +abstract class WindFilter extends WindHandlerInterceptor { + +} \ No newline at end of file diff --git a/wind/filter/WindFilterChain.php b/wind/filter/WindFilterChain.php new file mode 100644 index 00000000..5deb89ac --- /dev/null +++ b/wind/filter/WindFilterChain.php @@ -0,0 +1,63 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindFilterChain extends WindHandlerInterceptorChain { + + /** + * @param array $filterConfig + */ + public function __construct($filterConfig) { + $this->_initFilters($filterConfig); + } + + /** + * @param string $filterName + */ + public function deleteFilter($alias) { + unset($this->_interceptors[$alias]); + } + + /** + * 在filter链中动态的添加一个filter + * 当befor为空时,添加到程序结尾处 + * 如果befor有值,则遍历数组,找到befor的位置,将新的过滤器添加到befor后面, + * 并将所有原befor位置后的过滤器往后移一位 + * + * @param string $filterName + * @param string $path + * @param string $beforFilter + */ + public function addFilter($filter, $beforFilter = '') { + if ($beforFilter === '') { + $this->addInterceptors(array(get_class($filter) => $filter)); + return true; + } + $_interceptors = array(); + foreach ($this->_interceptors as $key => $interceptor) { + if ($beforFilter === $key) break; + $_interceptors[$key] = $interceptor; + unset($this->_interceptors[$key]); + } + $_interceptors[get_class($filter)] = $filter; + $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; + } + + /** + * @param array $filters + */ + private function _initFilters($filters = array()) { + $_temp = array(); + foreach ((array) $filters as $key => $filter) { + if (!is_array($filter)) continue; + $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); + if (!class_exists($filterClass)) continue; + $_temp[$key] = new $filterClass(); + } + $this->addInterceptors($_temp); + } + +} \ No newline at end of file diff --git a/wind/filter/WindHandlerInterceptor.php b/wind/filter/WindHandlerInterceptor.php new file mode 100644 index 00000000..7233cccd --- /dev/null +++ b/wind/filter/WindHandlerInterceptor.php @@ -0,0 +1,43 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class WindHandlerInterceptor extends WindModule { + protected $result = null; + protected $interceptorChain = null; + + abstract public function preHandle(); + + abstract public function postHandle(); + + /** + * @return mixed + */ + public function handle() { + $args = func_get_args(); + $this->result = call_user_func_array(array($this, 'preHandle'), $args); + if ($this->result !== null) { + return $this->result; + } + if (null !== ($handler = $this->interceptorChain->getHandler())) { + $this->result = call_user_func_array(array($handler, 'handle'), $args); + } else { + $this->result = $this->interceptorChain->handle(); + } + call_user_func_array(array($this, 'postHandle'), $args); + return $this->result; + } + + /** + * 设置过滤链对象 + * + * @param WindHandlerInterceptorChain $interceptorChain + */ + public function setHandlerInterceptorChain($interceptorChain) { + $this->interceptorChain = $interceptorChain; + } +} +?> \ No newline at end of file diff --git a/wind/filter/WindHandlerInterceptorChain.php b/wind/filter/WindHandlerInterceptorChain.php new file mode 100644 index 00000000..b7b53fb5 --- /dev/null +++ b/wind/filter/WindHandlerInterceptorChain.php @@ -0,0 +1,87 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindHandlerInterceptorChain extends WindModule { + protected $_interceptors = array(); + protected $_callBack = null; + protected $_args = array(); + protected $_state = 0; + + /** + * 设置回调方法 + * + * @param string|array $callBack + * @param array $args + * @return + */ + public function setCallBack($callBack, $args = array()) { + $this->_callBack = $callBack; + $this->_args = $args; + } + + /** + * 执行callback方法 + * + * @throws WindException + * @return void|mixed + */ + public function handle() { + if ($this->_callBack === null) + return null; + if (is_string($this->_callBack) && !function_exists($this->_callBack)) { + throw new WindException( + '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, + WindException::ERROR_FUNCTION_NOT_EXIST); + } + return call_user_func_array($this->_callBack, (array) $this->_args); + } + + /** + * 返回处理句柄 + * + * @return WindHandlerInterceptor + */ + public function getHandler() { + if (count($this->_interceptors) <= 0) { + return $this; + } + if ($this->_state >= count($this->_interceptors)) + return null; + $handler = $this->_interceptors[$this->_state++]; + if ($handler instanceof WindHandlerInterceptor) { + $handler->setHandlerInterceptorChain($this); + return $handler; + } + return $this->getHandler(); + } + + /** + * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 + * + * @param $interceptors + * @return + */ + public function addInterceptors($interceptors) { + if (is_array($interceptors)) + $this->_interceptors += $interceptors; + else + $this->_interceptors[] = $interceptors; + } + + /** + * 重置初始化信息 + * @return boolean + */ + public function reset() { + $this->_interceptors = array(); + $this->_callBack = null; + $this->_args = array(); + $this->_state = 0; + return true; + } +} +?> \ No newline at end of file From c71747058f85aeca4f68356037a027b15071da5e Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 06:09:15 +0000 Subject: [PATCH 0424/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2496 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/base/WindErrorMessage.php | 107 ++++++++++++++++++ wind/base/WindModule.php | 200 +++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+) create mode 100644 wind/base/WindErrorMessage.php create mode 100644 wind/base/WindModule.php diff --git a/wind/base/WindErrorMessage.php b/wind/base/WindErrorMessage.php new file mode 100644 index 00000000..eeca7b82 --- /dev/null +++ b/wind/base/WindErrorMessage.php @@ -0,0 +1,107 @@ + + * @author Qiong Wu + * @version $Id$ + * @package + */ +class WindErrorMessage extends WindModule implements IWindErrorMessage { + private $error = array(); + private $errorAction; + + /** + * @param string $message + */ + public function __construct($message = '', $errorAction = '') { + $message !== '' && $this->addError($message); + $errorAction !== '' && $this->setErrorAction($errorAction); + } + + /* (non-PHPdoc) + * @see IWindErrorMessage::sendError() + */ + public function sendError() { + if (empty($this->error)) + return; + throw new WindActionException($this); + } + + /* (non-PHPdoc) + * @see IWindErrorMessage::clearError() + */ + public function clearError() { + $this->error = array(); + } + + /* (non-PHPdoc) + * @see IWindErrorMessage::getError() + */ + public function getError($key = '') { + if ($key === '') + return $this->error; + return isset($this->error[$key]) ? $this->error[$key] : ''; + } + + /* (non-PHPdoc) + * @see IWindErrorMessage::addError() + */ + public function addError($error, $key = '') { + if ($key === '') { + if (is_string($error)) + $this->error[] = $error; + elseif (is_object($error)) + $error = get_object_vars($error); + if (is_array($error)) + $this->error += $error; + } else + $this->error[$key] = $error; + } + + /** + * @return the $errorAction + */ + public function getErrorAction() { + return $this->errorAction; + } + + /** + * /module/controller/action/?a=b&c=a + * @param string $errorAction + */ + public function setErrorAction($errorAction) { + $this->errorAction = $errorAction; + } + +} + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +interface IWindErrorMessage { + + /** + * 添加错误信息 + * @param string $message + * @param string $key + */ + public function addError($message, $key = ''); + + /** + * 获得一条Error信息 + * @param string $key + */ + public function getError($key = ''); + + /** + * 清空Error信息 + */ + public function clearError(); + + /** + * 发送错误信息 + */ + public function sendError(); +} \ No newline at end of file diff --git a/wind/base/WindModule.php b/wind/base/WindModule.php new file mode 100644 index 00000000..6f9de695 --- /dev/null +++ b/wind/base/WindModule.php @@ -0,0 +1,200 @@ + + * @version $Id$ + */ +class WindModule { + /** + * @var array + */ + protected $_config = array(); + /** + * 是否进行类型验证 + * + * @var boolean + */ + protected $_typeValidation = false; + /** + * 请求参数信息 + * + * @var array + */ + private $delayAttributes = array(); + + /** + * 设置属性值,该属性的访问类型不能为‘private’类型 + * + * @param string $propertyName + * @param string $value + * @return + */ + public function __set($propertyName, $value) { + $_setter = 'set' . ucfirst($propertyName); + if (method_exists($this, $_setter)) + $this->$_setter($value); + } + + /** + * 返回输入的属性的值,如果该属性不存在或访问类型为‘private’类型,则返回null + * + * @param string $propertyName + * @return value of the property or null + */ + public function __get($propertyName) { + $_getter = 'get' . ucfirst($propertyName); + if (method_exists($this, $_getter)) + return $this->$_getter(); + } + + /** + * 实现setter或者getter方法调用,并返回你调用方法的返回值 + * + * @param string $methodName + * @param array $args + * @return the return of the method your call + */ + public function __call($methodName, $args) { + $_prefix = substr($methodName, 0, 4); + $_propertyName = substr($methodName, 4); + $_propertyName = WindUtility::lcfirst($_propertyName); + if ($_prefix == '_get') { + if (isset($this->delayAttributes[$_propertyName])) { + $_property = $this->delayAttributes[$_propertyName]; + $_value = null; + if (isset($_property['value'])) { + $_value = $_property['value']; + } elseif (isset($_property['ref'])) { + $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); + } elseif (isset($_property['path'])) { + $_className = Wind::import($_property['path']); + $_value = $this->getSystemFactory()->createInstance($_className, $args); + } + $this->$_propertyName = $_value; + unset($this->delayAttributes[$_propertyName]); + } + return $this->$_propertyName; + } elseif ($_prefix == '_set') { + $this->$_propertyName = $args[0]; + } + } + + /** + * 对象clone魔术方法 + */ + public function __clone() { + foreach ($this->writeTableCloneProperty() as $value) { + if (!is_object($this->$value) || !isset($this->$value)) + continue; + $this->$value = clone $this->$value; + } + } + + /** + * 返回该对象的数组类型 + * + * @return array + */ + public function toArray() { + $reflection = new ReflectionClass(get_class($this)); + $properties = $reflection->getProperties(); + $_result = array(); + foreach ($properties as $property) { + $_propertyName = $property->name; + $_result[$_propertyName] = $this->$_propertyName; + } + return $_result; + } + + /** + * 根据配置名取得相应的配置 + * + * @param string $configName 键名 + * @param string $subConfigName 二级键名 + * @param string $default 默认值 + * @param array $config + * @return string|array + */ + public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { + if (empty($config)) + $config = $this->_config; + if ($configName === '') + return $config; + if (!isset($config[$configName])) + return $default; + if ($subConfigName === '') + return $config[$configName]; + if (!isset($config[$configName][$subConfigName])) + return $default; + return $config[$configName][$subConfigName]; + } + + /** + * Config配置,如果配置信息已经存在,则会合并配置 + * + * @param string|array|windConfig $config + * @return + */ + public function setConfig($config) { + if ($config) { + if (is_string($config)) + $config = Wind::getApp()->getComponent('configParser')->parse($config); + if (!empty($this->_config)) { + $this->_config = array_merge($this->_config, (array) $config); + } else + $this->_config = $config; + } + } + + /** + * 设置自动实现Getter/Setter方法的属性名称 + * 当该方法返回值为空时,类属性的可访问性跟默认相同 + * @deprecated + * @return array + */ + protected function writeTableForProperty() { + return array('delayAttributes' => 'array'); + } + + /** + * 通过重载该方法,可以实现对对象内部的对象同时进行clone + * 返回需要被clone的对象数组 + * + * @return array + */ + protected function writeTableCloneProperty() { + return array(); + } + + /** + * @return WindFactory + */ + protected function getSystemFactory() { + return Wind::getApp()->getWindFactory(); + } + + /** + * @return WindHttpRequest + */ + protected function getRequest() { + return Wind::getApp()->getRequest(); + } + + /** + * @return WindHttpResponse + */ + protected function getResponse() { + return Wind::getApp()->getResponse(); + } + + /** + * @param array $delayAttributes + */ + public function setDelayAttributes($delayAttributes) { + $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); + } + +} \ No newline at end of file From 45b8753e71f19d1bb6f0aac96b25edea06b5b1e3 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 29 Aug 2011 06:51:18 +0000 Subject: [PATCH 0425/1065] =?UTF-8?q?=E9=87=8D=E5=A4=8D=E7=9A=84=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E5=BA=94=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2497 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 0e5657c4..78406ca0 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -40,9 +40,6 @@ public static function application($appName = 'default', $config = array(), $roo $factory = new WindFactory(@include (Wind::getRealPath(self::$_components))); if ($config && !is_array($config)) $config = $factory->getInstance('configParser')->parse($config); - Wind::register( - ($rootPath ? $rootPath : (isset($config['root-path']) ? $config['root-path'] : dirname( - $_SERVER['SCRIPT_FILENAME']))), $appName, true); $appClass = @$config['class'] ? $config['class'] : 'windWebApp'; $application = $factory->getInstance($appClass, array($config, $factory)); if (!$application instanceof IWindApplication) From b1190f2b80d21a54cbff4b0415ce9d583aee37d0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 07:55:47 +0000 Subject: [PATCH 0426/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2498 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/core/IWindApplication.php | 30 -- wind/core/WindEnableValidateModule.php | 115 ------- wind/core/WindErrorMessage.php | 107 ------ wind/core/WindHelper.php | 203 ------------ wind/core/WindModule.php | 200 ------------ wind/core/exception/WindActionException.php | 49 --- wind/core/exception/WindException.php | 95 ------ wind/core/exception/WindFinalException.php | 15 - wind/core/factory/IWindFactory.php | 40 --- wind/core/factory/WindClassProxy.php | 199 ------------ wind/core/factory/WindFactory.php | 258 --------------- wind/core/filter/WindActionFilter.php | 86 ----- wind/core/filter/WindFilter.php | 11 - wind/core/filter/WindFilterChain.php | 63 ---- wind/core/filter/WindHandlerInterceptor.php | 43 --- .../filter/WindHandlerInterceptorChain.php | 87 ----- wind/core/web/WindController.php | 35 -- wind/core/web/WindDispatcher.php | 117 ------- wind/core/web/WindErrorHandler.php | 44 --- wind/core/web/WindForward.php | 205 ------------ wind/core/web/WindSimpleController.php | 306 ------------------ wind/core/web/WindSystemConfig.php | 243 -------------- wind/core/web/WindUrlHelper.php | 25 -- wind/core/web/WindWebApplication.php | 247 -------------- wind/core/web/filter/WindUrlFilter.php | 26 -- wind/core/web/listener/WindFormListener.php | 73 ----- .../web/listener/WindValidateListener.php | 96 ------ wind/core/web/view/404.htm | 140 -------- wind/core/web/view/error.htm | 155 --------- wind/core/web/view/erroraction.htm | 45 --- 30 files changed, 3358 deletions(-) delete mode 100644 wind/core/IWindApplication.php delete mode 100644 wind/core/WindEnableValidateModule.php delete mode 100644 wind/core/WindErrorMessage.php delete mode 100644 wind/core/WindHelper.php delete mode 100644 wind/core/WindModule.php delete mode 100644 wind/core/exception/WindActionException.php delete mode 100644 wind/core/exception/WindException.php delete mode 100644 wind/core/exception/WindFinalException.php delete mode 100644 wind/core/factory/IWindFactory.php delete mode 100644 wind/core/factory/WindClassProxy.php delete mode 100644 wind/core/factory/WindFactory.php delete mode 100644 wind/core/filter/WindActionFilter.php delete mode 100644 wind/core/filter/WindFilter.php delete mode 100644 wind/core/filter/WindFilterChain.php delete mode 100644 wind/core/filter/WindHandlerInterceptor.php delete mode 100644 wind/core/filter/WindHandlerInterceptorChain.php delete mode 100644 wind/core/web/WindController.php delete mode 100644 wind/core/web/WindDispatcher.php delete mode 100644 wind/core/web/WindErrorHandler.php delete mode 100644 wind/core/web/WindForward.php delete mode 100644 wind/core/web/WindSimpleController.php delete mode 100644 wind/core/web/WindSystemConfig.php delete mode 100644 wind/core/web/WindUrlHelper.php delete mode 100644 wind/core/web/WindWebApplication.php delete mode 100644 wind/core/web/filter/WindUrlFilter.php delete mode 100644 wind/core/web/listener/WindFormListener.php delete mode 100644 wind/core/web/listener/WindValidateListener.php delete mode 100644 wind/core/web/view/404.htm delete mode 100644 wind/core/web/view/error.htm delete mode 100644 wind/core/web/view/erroraction.htm diff --git a/wind/core/IWindApplication.php b/wind/core/IWindApplication.php deleted file mode 100644 index 76691622..00000000 --- a/wind/core/IWindApplication.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindApplication { - - /** - * @return - */ - public function run(); - - /** - * @return WindHttpRequest $request - */ - public function getRequest(); - - /** - * @return WindHttpResponse $response - */ - public function getResponse(); - - /** - * @return WindFactory $windFactory - */ - public function getWindFactory(); -} -?> \ No newline at end of file diff --git a/wind/core/WindEnableValidateModule.php b/wind/core/WindEnableValidateModule.php deleted file mode 100644 index d9086908..00000000 --- a/wind/core/WindEnableValidateModule.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindEnableValidateModule extends WindModule { - protected $_validatorClass = 'WIND:component.utility.WindValidator'; - protected $errorController = ''; - protected $errorAction = ''; - private $_validator = null; - private $_errors = array(); - private $_defaultMessage = 'the field validate fail.'; - - /** - * @return the $_errors - */ - public function getErrors() { - return $this->_errors; - } - - public function getErrorControllerAndAction() { - return array($this->errorController, $this->errorAction); - } - - /** - * 返回验证规则 - * - * validator : required/not-required - * @return multitype:multitype:string - */ - protected function validateRules() { - return array(); - } - - /** - * 验证方法 - * - * @param array|WindModule $input - */ - public function validate(&$input) { - if (is_array($input)) - $this->validateArray($input); - elseif (is_object($input)) - $this->validateObject($input); - } - - /** - * 验证数组类型的输入 - * @param array $input - */ - private function validateArray(&$input) { - $rules = $this->validateRules(); - foreach ((array) $rules as $rule) { - $_input = isset($input[$rule['field']]) ? $input[$rule['field']] : ''; - $arg = (array) $rule['args']; - array_unshift($arg, $_input); - if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; - if ($rule['default'] === null) { - $this->_errors[$rule['field']] = $rule['message']; - continue; - } - $input[$rule['field']] = $rule['default']; - } - } - - /** - * 验证对象类型的输入 - * 需要设置set和get方式 - * - * @param object $input 传入需要验证的数据 - * - */ - private function validateObject(&$input) { - $rules = $this->validateRules(); - $methods = get_class_methods($input); - foreach ((array) $rules as $rule) { - $getMethod = 'get' . ucfirst($rule['field']); - $_input = in_array($getMethod, $methods) ? call_user_func(array($input, $getMethod)) : ''; - $arg = (array) $rule['args']; - array_unshift($arg, $_input); - if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) continue; - if ($rule['default'] === null) { - $this->_errors[$rule['field']] = $rule['message']; - continue; - } - $setMethod = 'set' . ucfirst($rule['field']); - in_array($setMethod, $methods) && call_user_func_array(array($input, $setMethod), - array($rule['default'])); - } - } - - /** - * @param WindValidator $validator - */ - protected function setValidator($validator) { - $this->_validator = $validator; - } - - /** - * 返回验证器 - * @return WindValidator - */ - protected function getValidator() { - if ($this->_validator === null) { - $_className = Wind::import($this->_validatorClass); - $this->_validator = WindFactory::createInstance($_className); - if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); - } - return $this->_validator; - } -} \ No newline at end of file diff --git a/wind/core/WindErrorMessage.php b/wind/core/WindErrorMessage.php deleted file mode 100644 index eeca7b82..00000000 --- a/wind/core/WindErrorMessage.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindErrorMessage extends WindModule implements IWindErrorMessage { - private $error = array(); - private $errorAction; - - /** - * @param string $message - */ - public function __construct($message = '', $errorAction = '') { - $message !== '' && $this->addError($message); - $errorAction !== '' && $this->setErrorAction($errorAction); - } - - /* (non-PHPdoc) - * @see IWindErrorMessage::sendError() - */ - public function sendError() { - if (empty($this->error)) - return; - throw new WindActionException($this); - } - - /* (non-PHPdoc) - * @see IWindErrorMessage::clearError() - */ - public function clearError() { - $this->error = array(); - } - - /* (non-PHPdoc) - * @see IWindErrorMessage::getError() - */ - public function getError($key = '') { - if ($key === '') - return $this->error; - return isset($this->error[$key]) ? $this->error[$key] : ''; - } - - /* (non-PHPdoc) - * @see IWindErrorMessage::addError() - */ - public function addError($error, $key = '') { - if ($key === '') { - if (is_string($error)) - $this->error[] = $error; - elseif (is_object($error)) - $error = get_object_vars($error); - if (is_array($error)) - $this->error += $error; - } else - $this->error[$key] = $error; - } - - /** - * @return the $errorAction - */ - public function getErrorAction() { - return $this->errorAction; - } - - /** - * /module/controller/action/?a=b&c=a - * @param string $errorAction - */ - public function setErrorAction($errorAction) { - $this->errorAction = $errorAction; - } - -} - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindErrorMessage { - - /** - * 添加错误信息 - * @param string $message - * @param string $key - */ - public function addError($message, $key = ''); - - /** - * 获得一条Error信息 - * @param string $key - */ - public function getError($key = ''); - - /** - * 清空Error信息 - */ - public function clearError(); - - /** - * 发送错误信息 - */ - public function sendError(); -} \ No newline at end of file diff --git a/wind/core/WindHelper.php b/wind/core/WindHelper.php deleted file mode 100644 index 5d310429..00000000 --- a/wind/core/WindHelper.php +++ /dev/null @@ -1,203 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHelper { - const INTERNAL_LOCATION = "~Internal Location~"; - protected static $errorDir = 'WIND:core.web.view'; - protected static $errorPage = 'error.htm'; - - /** - * 错误处理句柄 - * @param string $errno - * @param string $errstr - * @param string $errfile - * @param string $errline - */ - public static function errorHandle($errno, $errstr, $errfile, $errline) { - if ($errno & error_reporting()) { - restore_error_handler(); - restore_exception_handler(); - $trace = debug_backtrace(); - unset($trace[0]["function"], $trace[0]["args"]); - self::crash(self::getErrorName($errno) . ':' . $errstr, $errfile, $errline, $trace); - } - } - - /** - * 异常处理句柄 - * @param Exception $exception - */ - public static function exceptionHandle($exception) { - restore_error_handler(); - restore_exception_handler(); - $trace = $exception->getTrace(); - if (@$trace[0]['file'] == '') { - unset($trace[0]); - $trace = array_values($trace); - } - $file = @$trace[0]['file']; - $line = @$trace[0]['line']; - self::crash($exception->getMessage(), $file, $line, $trace, $exception->getCode()); - } - - /** - * @param string $message - * @param string $file - * @param string $line - * @param array $trace - */ - protected static function crash($message, $file, $line, $trace, $status = 0) { - $errmessage = substr($message, 0, 8000); - $_headers = Wind::getApp()->getResponse()->getHeaders(); - $_errhtml = false; - foreach ($_headers as $_header) { - if (strtolower($_header['name']) == strtolower('Content-type')) { - $_errhtml = strpos(strtolower($_header['value']), strtolower('text/html')) !== false; - break; - } - } - $msg = ''; - if (WIND_DEBUG) { - $_errorPage = 'error.htm'; - /* format error trace */ - $count = count($trace); - $padLen = strlen($count); - foreach ($trace as $key => $call) { - if (!isset($call['file']) || $call['file'] == '') { - $call['file'] = self::INTERNAL_LOCATION; - $call['line'] = 'N/A'; - } - $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine( - $call); - $trace[$key] = $traceLine; - } - /* format error code */ - $fileLines = array(); - if (is_file($file)) { - $currentLine = $line - 1; - $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000)); - $topLine = $currentLine - 5; - $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true); - if (($count = count($fileLines)) > 0) { - $padLen = strlen($count); - foreach ($fileLines as $line => &$fileLine) - $fileLine = " " . htmlspecialchars( - str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( - "\t", " ", rtrim($fileLine)), null, "UTF-8"); - } - } - $msg .= "$file\n" . implode("\n", $fileLines) . "\n" . implode("\n", $trace); - } else - $_errorPage = '404.htm'; - - if ($status >= 400 && $status <= 505) { - $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); - $topic = "$status - " . $_statusMsg . "\n"; - } else - $topic = "Wind Framework - Error Caught"; - - $msg = "$topic\n$errmessage\n" . $msg . "\n\n" . self::errorInfo(); - - if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', - true); - - if ($_errhtml) { - ob_start(); - $errDir = Wind::getApp()->getConfig('errorpage'); - !$errDir && $errDir = self::$errorDir; - if (isset($_statusMsg)) { - header('HTTP/1.x ' . $status . ' ' . $_statusMsg); - header('Status: ' . $status . ' ' . $_statusMsg); - is_file(Wind::getRealPath($errDir) . '.' . $status . '.htm') && $_errorPage = $status . '.htm'; - } - require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, - true); - $msg = ob_get_clean(); - } - $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~/', $msg); - die($msg); - } - - /** - * @param array $call - * @return string - */ - private static function getCallLine($call) { - $call_signature = ""; - if (isset($call['file'])) - $call_signature .= $call['file'] . " "; - if (isset($call['line'])) - $call_signature .= "(" . $call['line'] . ") "; - if (isset($call['function'])) { - $call_signature .= $call['function'] . "("; - if (isset($call['args'])) { - foreach ($call['args'] as $arg) { - if (is_string($arg)) - $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"'; - else if (is_object($arg)) - $arg = "[Instance of '" . get_class($arg) . "']"; - else if ($arg === true) - $arg = "true"; - else if ($arg === false) - $arg = "false"; - else if ($arg === null) - $arg = "null"; - else - $arg = strval($arg); - $call_signature .= $arg . ','; - } - } - $call_signature = trim($call_signature, ',') . ")"; - } - return $call_signature; - } - - /** - * @param int $errorNumber - * @return string - */ - protected static function getErrorName($errorNumber) { - $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", - E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", - E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", - E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", - E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", - E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); - return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; - } - - public static function errorInfo() { - $info = "The server encountered an internal error and failed to process your request. Please try again later. If this error is temporary, reloading the page might resolve the problem.\nIf you are able to contact the administrator report this error message."; - $info .= "(" . Wind::getApp()->getConfig('siteInfo', '', "http://www.windframework.com/") . ")"; - return $info; - } - - /** - * 解析ControllerPath - * 返回解析后的controller信息,controller,module,app - * - * @param string $controllerPath - * @return array - */ - public static function resolveController($controllerPath) { - $_m = $_c = ''; - if (!$controllerPath) - return array($_c, $_m); - if (false !== ($pos = strrpos($controllerPath, '.'))) { - $_m = substr($controllerPath, 0, $pos); - $_c = substr($controllerPath, $pos + 1); - } else { - $_c = $controllerPath; - } - return array($_c, $_m); - } -} -?> \ No newline at end of file diff --git a/wind/core/WindModule.php b/wind/core/WindModule.php deleted file mode 100644 index 6f9de695..00000000 --- a/wind/core/WindModule.php +++ /dev/null @@ -1,200 +0,0 @@ - - * @version $Id$ - */ -class WindModule { - /** - * @var array - */ - protected $_config = array(); - /** - * 是否进行类型验证 - * - * @var boolean - */ - protected $_typeValidation = false; - /** - * 请求参数信息 - * - * @var array - */ - private $delayAttributes = array(); - - /** - * 设置属性值,该属性的访问类型不能为‘private’类型 - * - * @param string $propertyName - * @param string $value - * @return - */ - public function __set($propertyName, $value) { - $_setter = 'set' . ucfirst($propertyName); - if (method_exists($this, $_setter)) - $this->$_setter($value); - } - - /** - * 返回输入的属性的值,如果该属性不存在或访问类型为‘private’类型,则返回null - * - * @param string $propertyName - * @return value of the property or null - */ - public function __get($propertyName) { - $_getter = 'get' . ucfirst($propertyName); - if (method_exists($this, $_getter)) - return $this->$_getter(); - } - - /** - * 实现setter或者getter方法调用,并返回你调用方法的返回值 - * - * @param string $methodName - * @param array $args - * @return the return of the method your call - */ - public function __call($methodName, $args) { - $_prefix = substr($methodName, 0, 4); - $_propertyName = substr($methodName, 4); - $_propertyName = WindUtility::lcfirst($_propertyName); - if ($_prefix == '_get') { - if (isset($this->delayAttributes[$_propertyName])) { - $_property = $this->delayAttributes[$_propertyName]; - $_value = null; - if (isset($_property['value'])) { - $_value = $_property['value']; - } elseif (isset($_property['ref'])) { - $_value = $this->getSystemFactory()->getInstance($_property['ref'], $args); - } elseif (isset($_property['path'])) { - $_className = Wind::import($_property['path']); - $_value = $this->getSystemFactory()->createInstance($_className, $args); - } - $this->$_propertyName = $_value; - unset($this->delayAttributes[$_propertyName]); - } - return $this->$_propertyName; - } elseif ($_prefix == '_set') { - $this->$_propertyName = $args[0]; - } - } - - /** - * 对象clone魔术方法 - */ - public function __clone() { - foreach ($this->writeTableCloneProperty() as $value) { - if (!is_object($this->$value) || !isset($this->$value)) - continue; - $this->$value = clone $this->$value; - } - } - - /** - * 返回该对象的数组类型 - * - * @return array - */ - public function toArray() { - $reflection = new ReflectionClass(get_class($this)); - $properties = $reflection->getProperties(); - $_result = array(); - foreach ($properties as $property) { - $_propertyName = $property->name; - $_result[$_propertyName] = $this->$_propertyName; - } - return $_result; - } - - /** - * 根据配置名取得相应的配置 - * - * @param string $configName 键名 - * @param string $subConfigName 二级键名 - * @param string $default 默认值 - * @param array $config - * @return string|array - */ - public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) { - if (empty($config)) - $config = $this->_config; - if ($configName === '') - return $config; - if (!isset($config[$configName])) - return $default; - if ($subConfigName === '') - return $config[$configName]; - if (!isset($config[$configName][$subConfigName])) - return $default; - return $config[$configName][$subConfigName]; - } - - /** - * Config配置,如果配置信息已经存在,则会合并配置 - * - * @param string|array|windConfig $config - * @return - */ - public function setConfig($config) { - if ($config) { - if (is_string($config)) - $config = Wind::getApp()->getComponent('configParser')->parse($config); - if (!empty($this->_config)) { - $this->_config = array_merge($this->_config, (array) $config); - } else - $this->_config = $config; - } - } - - /** - * 设置自动实现Getter/Setter方法的属性名称 - * 当该方法返回值为空时,类属性的可访问性跟默认相同 - * @deprecated - * @return array - */ - protected function writeTableForProperty() { - return array('delayAttributes' => 'array'); - } - - /** - * 通过重载该方法,可以实现对对象内部的对象同时进行clone - * 返回需要被clone的对象数组 - * - * @return array - */ - protected function writeTableCloneProperty() { - return array(); - } - - /** - * @return WindFactory - */ - protected function getSystemFactory() { - return Wind::getApp()->getWindFactory(); - } - - /** - * @return WindHttpRequest - */ - protected function getRequest() { - return Wind::getApp()->getRequest(); - } - - /** - * @return WindHttpResponse - */ - protected function getResponse() { - return Wind::getApp()->getResponse(); - } - - /** - * @param array $delayAttributes - */ - public function setDelayAttributes($delayAttributes) { - $this->delayAttributes = array_merge($this->delayAttributes, $delayAttributes); - } - -} \ No newline at end of file diff --git a/wind/core/exception/WindActionException.php b/wind/core/exception/WindActionException.php deleted file mode 100644 index 44ed6575..00000000 --- a/wind/core/exception/WindActionException.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindActionException extends WindException { - private $error; - - /** - * @param WindErrorMessage $error - */ - public function __construct($error, $code = 0) { - if ($error instanceof WindErrorMessage) { - $this->setError($error); - parent::__construct($error->getError(0), $code); - } else - parent::__construct($error, $code); - } - - /** - * 自定义异常号的对应异常信息 - * - * @param int $code 异常号 - * @return string 返回异常号对应的异常组装信息原型 - */ - protected function messageMapper($code) { - $messages = array(); - return isset($messages[$code]) ? $messages[$code] : '$message'; - } - - /** - * @return WindErrorMessage $error - */ - public function getError() { - return $this->error; - } - - /** - * @param WindErrorMessage $error - */ - public function setError($error) { - $this->error = $error; - } -} -?> \ No newline at end of file diff --git a/wind/core/exception/WindException.php b/wind/core/exception/WindException.php deleted file mode 100644 index afbd8103..00000000 --- a/wind/core/exception/WindException.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @author Qian Su - * @version $Id: WindException.php 37 2010-11-08 12:57:04Z weihu $ - * @package - */ -class WindException extends Exception { - /* 系统错误 */ - const ERROR_SYSTEM_ERROR = '0'; - /* 类错误 */ - const ERROR_CLASS_NOT_EXIST = '100'; - const ERROR_CLASS_TYPE_ERROR = '101'; - const ERROR_CLASS_METHOD_NOT_EXIST = '102'; - const ERROR_OBJECT_NOT_EXIST = '103'; - /* 参数错误 */ - const ERROR_PARAMETER_TYPE_ERROR = '110'; - /* 配置错误 */ - const ERROR_CONFIG_ERROR = '120'; - /* 返回值类型错误 */ - const ERROR_RETURN_TYPE_ERROR = '130'; - - private $innerException = null; - - /** - * 异常构造函数 - * @param $message 异常信息 - * @param $code 异常代号 - * @param $innerException 内部异常 - */ - public function __construct($message = '', $code = 0, Exception $innerException = null) { - $message = $this->buildMessage($message, $code); - parent::__construct($message, $code); - $this->innerException = $innerException; - } - - /** - * 取得内部异常 - */ - public function getInnerException() { - return $this->innerException; - } - - /** - * 取得异常堆栈信息 - */ - public function getStackTrace() { - if ($this->innerException) { - $thisTrace = $this->getTrace(); - $class = __CLASS__; - $innerTrace = $this->innerException instanceof $class ? $this->innerException->getStackTrace() : $this->innerException->getTrace(); - foreach ($innerTrace as $trace) - $thisTrace[] = $trace; - return $thisTrace; - } else { - return $this->getTrace(); - } - return array(); - } - - /** - * 组装异常信息 - * - * 根据输入的异常号组装相对应的异常信息 - * - * @param string $message 用户自定义的信息 - * @param int $code 异常号 - * @return string 组装后的异常信息 - */ - public function buildMessage($message, $code) { - $message = str_replace(array("
", "
", "\r\n"), '', $message); - eval('$message="' . addcslashes($this->messageMapper($code), '"') . '";'); - return $message; - } - - /** - * 自定义异常号的对应异常信息 - * - * @param int $code 异常号 - * @return string 返回异常号对应的异常组装信息原型 - */ - protected function messageMapper($code) { - $messages = array(self::ERROR_SYSTEM_ERROR => 'System error \'$message\'.', - self::ERROR_CLASS_TYPE_ERROR => 'Incorrect class type \'$message\'.', - self::ERROR_CLASS_NOT_EXIST => 'Unable to create instance for \'$message\' , class is not exist.', - self::ERROR_CLASS_METHOD_NOT_EXIST => 'Unable to access the method \'$message\' in current class , the method is not exist or is protected.', - self::ERROR_OBJECT_NOT_EXIST => 'Unable to access the object in current class \'$message\' ', - self::ERROR_CONFIG_ERROR => 'Incorrect config. the config about \'$message\' error.', - self::ERROR_PARAMETER_TYPE_ERROR => 'Incorrect parameter type \'$message\'.', - self::ERROR_RETURN_TYPE_ERROR => 'Incorrect return type for \'$message\'.'); - return isset($messages[$code]) ? $messages[$code] : '$message'; - } -} \ No newline at end of file diff --git a/wind/core/exception/WindFinalException.php b/wind/core/exception/WindFinalException.php deleted file mode 100644 index 74e2f050..00000000 --- a/wind/core/exception/WindFinalException.php +++ /dev/null @@ -1,15 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindFinalException extends Exception{ - - -} - -?> \ No newline at end of file diff --git a/wind/core/factory/IWindFactory.php b/wind/core/factory/IWindFactory.php deleted file mode 100644 index 5a208bca..00000000 --- a/wind/core/factory/IWindFactory.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindFactory { - - /** - * 描述:根据类的别名获得一个类实例变量 - * 返回:类的实例对象 - * - * 该方法首先通过类的别名到类的配置文件中找到类的相关配置信息, - * 加载类的路径并创建类的依赖 - * - * @param string $classAlias - * @return instance - */ - public function getInstance($classAlias); - - /** - * 根据类的别名返回一个类的实例变量的clone - * - * @param string $classAlias - * @return clone of instance - */ - public function getPrototype($classAlias); - - /** - * 根据类名称创建类对象 - * 返回一个类类型的实例对象,通过此方法创建类实例,并不能自动获取类路径信息 - * - * @param string $className | 类名称 - * @param array $args | 类参数信息 - * @return Object | 返回的类类型的实例对象 - */ - static public function createInstance($className, $args = array()); -} \ No newline at end of file diff --git a/wind/core/factory/WindClassProxy.php b/wind/core/factory/WindClassProxy.php deleted file mode 100644 index 7c255c14..00000000 --- a/wind/core/factory/WindClassProxy.php +++ /dev/null @@ -1,199 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindClassProxy { - const EVENT_TYPE_METHOD = 'method'; - const EVENT_TYPE_SETTER = 'setter'; - const EVENT_TYPE_GETTER = 'getter'; - - private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; - private $_interceptorChainObj = null; - protected $_attributes = array(); - protected $_className = ''; - protected $_classPath = ''; - protected $_reflection = null; - protected $_instance = null; - protected $_listener = array(); - - /** - * @param object $targetObj - */ - public function __construct($targetObject = null) { - $targetObject && $this->registerTargetObject($targetObject); - } - - /* (non-PHPdoc) - * @see IWindClassProxy::registerAspect() - */ - public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) { - if (!in_array($type, - array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { - throw new WindException( - '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, - WindException::ERROR_PARAMETER_TYPE_ERROR); - } - !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); - array_push($this->_listener[$type][$event], $listener); - } - - /** - * 注册目标对象,如果已经注册了不重复注册 - * @param object $targetObject - */ - public function registerTargetObject($targetObject) { - if ($this->_instance !== null || !is_object($targetObject)) - return; - $this->_setClassName(get_class($targetObject)); - $this->_instance = $targetObject; - $types = array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER); - foreach ($types as $type) - $this->_listener[$type] = array(); - return $this; - } - - /** - * @param string $propertyName - * @param $value - * @throws WindException - * @deprecated - */ - public function __set($propertyName, $value) { - $property = $this->_getReflection()->getProperty($propertyName); - if (!$property || !$property->isPublic()) { - throw new WindException('undefined property name. '); - } - $listeners = $this->_getListenerByType(self::EVENT_TYPE_SETTER, $propertyName); - if (empty($listeners)) - return call_user_func_array(array($this, '_setProperty'), array($propertyName, $value)); - $interceptorChain = $this->_getInterceptorChain($propertyName); - $interceptorChain->addInterceptors($listeners); - $interceptorChain->setCallBack(array($this, '_setProperty'), array($propertyName, $value)); - return $interceptorChain->getHandler()->handle($value); - } - - /** - * @param unknown_type $propertyName - * @deprecated - */ - public function __get($propertyName) { - $property = $this->_getReflection()->getProperty($propertyName); - if (!$property || !$property->isPublic()) { - throw new WindException('undefined property name. '); - } - $listeners = $this->_getListenerByType(self::EVENT_TYPE_GETTER, $propertyName); - if (empty($listeners)) - return call_user_func_array(array($this, '_getProperty'), array($propertyName)); - $interceptorChain = $this->_getInterceptorChain($propertyName); - $interceptorChain->addInterceptors($listeners); - $interceptorChain->setCallBack(array($this, '_getProperty'), array($propertyName)); - return $interceptorChain->getHandler()->handle($propertyName); - } - - /** - * @param string $methodName - * @param array $args - * @throws WindException - */ - public function __call($methodName, $args) { - $listeners = $this->_getListenerByType(self::EVENT_TYPE_METHOD, $methodName); - if (empty($listeners)) - return call_user_func_array(array($this->_getInstance(), $methodName), (array) $args); - $interceptorChain = $this->_getInterceptorChain($methodName); - $interceptorChain->addInterceptors($listeners); - $interceptorChain->setCallBack(array($this->_getInstance(), $methodName), $args); - return call_user_func_array(array($interceptorChain->getHandler(), 'handle'), (array) $args); - } - - /** - * @param string $event - * @return - */ - private function _getInterceptorChain($event = '') { - if (null === $this->_interceptorChainObj) { - $chain = Wind::import($this->_interceptorChain); - $interceptorChain = WindFactory::createInstance($chain); - if ($interceptorChain && $interceptorChain instanceof WindHandlerInterceptorChain) { - $this->_interceptorChainObj = $interceptorChain; - } else - throw new WindException( - '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); - } - $this->_interceptorChainObj->reset(); - return $this->_interceptorChainObj; - } - - /** - * 根据监听器类型,返回对象的监听器对象 - * - * @param string $type - * @param string $subType - */ - private function _getListenerByType($type, $subType) { - $listener = array(); - if (isset($this->_listener[$type]) && isset($this->_listener[$type][$subType])) { - $listener = $this->_listener[$type][$subType]; - } - return $listener; - } - - /* (non-PHPdoc) - * @see IWindClassProxy::_getInstance() - */ - public function _getInstance() { - return $this->_instance; - } - - /** - * @return string - */ - public function _getClassName() { - return $this->_className; - } - - /** - * @return string - */ - public function _getClassPath() { - return $this->_classPath; - } - - /** - * @param string $className - * @return - */ - public function _setClassName($className) { - $this->_className = $className; - } - - /** - * @param string $classPath - * @return - */ - public function _setClassPath($classPath) { - $this->_setClassName(Wind::import($classPath)); - $this->_classPath = $classPath; - } - - /** - * @param string $propertyName - * @param $value - */ - public function _setProperty($propertyName, $value) { - $this->_getInstance()->$propertyName = $value; - } - - /** - * @param string $propertyName - */ - public function _getProperty($propertyName) { - return $this->_getInstance()->$propertyName; - } -} -?> \ No newline at end of file diff --git a/wind/core/factory/WindFactory.php b/wind/core/factory/WindFactory.php deleted file mode 100644 index eca4656f..00000000 --- a/wind/core/factory/WindFactory.php +++ /dev/null @@ -1,258 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindFactory implements IWindFactory { - protected $proxyType = 'WIND:core.factory.WindClassProxy'; - protected $classDefinitions = array(); - protected $instances = array(); - protected $prototype = array(); - - /** - * 初始化抽象工厂类 - * 可以通过两种方式初始化该工厂 - * 1. 直接传递一个解析好的类配置信息 - * @param string $configFile - */ - public function __construct($classDefinitions = array()) { - if (is_array($classDefinitions)) { - $this->classDefinitions = $classDefinitions; - } - } - - /* (non-PHPdoc) - * @see AbstractWindFactory::getInstance() - */ - public function getInstance($alias, $args = array()) { - $instance = null; - $definition = isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : array(); - if (isset($this->prototype[$alias])) { - $instance = clone $this->prototype[$alias]; - } elseif (isset($this->instances[$alias])) { - $instance = $this->instances[$alias]; - } else { - if (!$definition) - throw new WindException( - '[core.factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); - - if (isset($definition['constructor-arg'])) - foreach ((array) $definition['constructor-arg'] as $_var) { - if (isset($_var['value'])) { - $args[] = $_var['value']; - } elseif (isset($_var['ref'])) - $args[] = $this->getInstance($_var['ref']); - } - if (!isset($definition['className'])) - $definition['className'] = Wind::import(@$definition['path']); - $instance = $this->createInstance($definition['className'], $args); - if (isset($definition['config'])) - $this->resolveConfig($definition['config'], $alias, $instance); - if (isset($definition['properties'])) - $this->buildProperties($definition['properties'], $instance); - if (isset($definition['initMethod'])) - $this->executeInitMethod($definition['initMethod'], $instance); - !isset($definition['scope']) && $definition['scope'] = 'application'; - $this->setScope($alias, $definition['scope'], $instance); - } - - if (isset($definition['proxy'])) - $instance = $this->setProxyForClass($definition['proxy'], $instance); - return $instance; - } - - /** - * 对象组件对象到应用工厂中 - * @param object $instance - * @param string $alias - * @param string $scope - * @return boolean - */ - public function registInstance($instance, $alias, $scope = 'singleton') { - if (!is_object($instance) || !$alias) - return false; - return $this->setScope($alias, $scope, $instance); - } - - /* (non-PHPdoc) - * @see AbstractWindFactory::createInstance() - */ - static public function createInstance($className, $args = array()) { - try { - if (!$className || !class_exists($className)) - throw new WindException('class is not exist.'); - if (empty($args)) { - return new $className(); - } else { - $reflection = new ReflectionClass($className); - return call_user_func_array(array($reflection, 'newInstance'), (array) $args); - } - } catch (Exception $e) { - throw new WindException( - '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), - WindException::ERROR_CLASS_NOT_EXIST); - } - } - - /* (non-PHPdoc) - * @see IWindFactory::getPrototype() - */ - public function getPrototype($alias) { - return isset($this->prototype[$alias]) ? clone $this->prototype[$alias] : null; - } - - /** - * 动态添加类定义对象 - * @param string $alias - * @param array $classDefinition - * @return - */ - public function addClassDefinitions($alias, $classDefinition) { - if (is_string($alias) && !empty($alias)) { - if (!isset($this->classDefinitions[$alias])) - $this->classDefinitions[$alias] = $classDefinition; - } else - throw new WindException( - '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', - WindException::ERROR_PARAMETER_TYPE_ERROR); - } - - /** - * 加载类定义,如果merge为true,则覆盖原有配置信息 - * @param array $classDefinitions - * @param boolean $merge - * @return - */ - public function loadClassDefinitions($classDefinitions, $merge = true) { - foreach ((array) $classDefinitions as $alias => $definition) { - if (!is_array($definition)) - continue; - if (!isset($this->classDefinitions[$alias]) || $merge === false) { - $this->classDefinitions[$alias] = $definition; - continue; - } - $this->classDefinitions[$alias] = WindUtility::mergeArray( - $this->classDefinitions[$alias], $definition); - unset($this->instances[$alias], $this->prototype[$alias]); - } - } - - /** - * 类定义检查,检查类型以是否已经存在 - * @param array $definition - * @return boolean - */ - public function checkAlias($alias) { - if (isset($this->prototype[$alias])) - return true; - elseif (isset($this->instances[$alias])) - return true; - return false; - } - - /** - * @param string $alias - * @param string $scope - * @param object $instance - */ - protected function setScope($alias, $scope, $instance) { - switch ($scope) { - case 'prototype': - $this->prototype[$alias] = clone $instance; - break; - case 'application': - $this->instances[$alias] = $instance; - break; - default: - $this->instances[$alias] = $instance; - break; - - } - return true; - } - - /** - * 为类对象设置配置 - * @param array|string $config - * @param string $alias - * @param WindModule $instance - * @return - */ - protected function resolveConfig($config, $alias, $instance) { - if (isset($config['resource'])) { - $_configPath = Wind::getRealPath($config['resource'], true); - $configParser = $this->getInstance('configParser'); - $config = $configParser->parse($_configPath, $alias, true, - Wind::getApp()->getComponent('windCache')); - } - if ($config && method_exists($instance, 'setConfig')) - $instance->setConfig($config); - } - - /** - * 执行用户配置的初始化操作 - * @param string $initMethod - * @param object $instance - * @return - */ - protected function executeInitMethod($initMethod, $instance) { - try { - return call_user_func_array(array($instance, $initMethod), array()); - } catch (Exception $e) { - throw new WindException( - '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', - WindException::ERROR_CLASS_METHOD_NOT_EXIST); - } - } - - /** - * 为类设置代理 - * @param string $definition - * @param WindModule $instance - * @return WindClassProxy - */ - protected function setProxyForClass($proxy, $instance) { - if ($proxy === 'false' || $proxy === false) - return $instance; - - if ($proxy === 'true' || $proxy === true) - $proxy = $this->proxyType; - $this->addClassDefinitions($proxy, array('path' => $proxy, 'scope' => 'prototype')); - return $this->getInstance($proxy)->registerTargetObject($instance); - } - - /** - * 将类实例的依赖注入到类实例中 - * @param string $properties - * @param WindModule $instance - */ - protected function buildProperties($properties, $instance) { - if (!isset($properties['delay'])) { - $instance->setDelayAttributes($properties); - } elseif ($properties['delay'] === 'false' || $properties['delay'] === false) { - foreach ($properties as $key => $subDefinition) { - $_value = ''; - if (isset($subDefinition['value'])) - $_value = $subDefinition['value']; - elseif (isset($subDefinition['ref'])) - $_value = $this->getInstance($subDefinition['ref']); - elseif (isset($subDefinition['path'])) { - $_className = Wind::import($subDefinition['path']); - $_value = $this->createInstance($_className); - } - $_setter = 'set' . ucfirst(trim($key, '_')); - if (method_exists($instance, $_setter)) - call_user_func_array(array($instance, $_setter), array($_value)); - } - } else - $instance->setDelayAttributes($properties); - } -} \ No newline at end of file diff --git a/wind/core/filter/WindActionFilter.php b/wind/core/filter/WindActionFilter.php deleted file mode 100644 index adbad79e..00000000 --- a/wind/core/filter/WindActionFilter.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class WindActionFilter extends WindHandlerInterceptor { - protected $_vars = array(); - /** - * @var WindForward - */ - protected $forward = null; - /** - * @var WindErrorMessage - */ - protected $errorMessage = null; - - /** - * @param WindForward $forward - * @param WindErrorMessage $errorMessage - */ - public function __construct($forward, $errorMessage) { - $this->forward = $forward; - $this->errorMessage = $errorMessage; - $args = func_get_args(); - unset($args[0], $args[1]); - foreach ($args as $key => $value) - property_exists(get_class($this), $key) && $this->$key = $value; - $this->_vars = $forward->getVars(); - } - - /** - * 设置模板数据 - * @param string|array|object $data - * @param string $key - * @return - */ - protected function setOutput($data, $key = '') { - $this->forward->setVars($data, $key); - } - - /** - * 设置模板数据 - * @param string|array|object $data - * @param string $key - * @return - */ - protected function setGlobal($data, $key = '') { - $this->forward->setVars($data, $key, true); - } - - /** - * 获得输入数据 - * 如果输入了回调方法则返回数组: - * 第一个值:value - * 第二个值:验证结果 - * @param string $name input name - * @param string $type input type (GET POST COOKIE) - * @param string $callback | validation for input - * @return array | string - */ - protected function getInput($name, $type = '', $callback = array()) { - $value = ''; - switch (strtolower($type)) { - case 'form': - $value = $this->getRequest()->getData($name); - break; - case IWindRequest::INPUT_TYPE_GET: - $value = $this->getRequest()->getGet($name); - break; - case IWindRequest::INPUT_TYPE_POST: - $value = $this->getRequest()->getPost($name); - break; - case IWindRequest::INPUT_TYPE_COOKIE: - $value = $this->getRequest()->getCookie($name); - break; - default: - $value = $this->getRequest()->getAttribute($name); - } - return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; - } - -} - -?> \ No newline at end of file diff --git a/wind/core/filter/WindFilter.php b/wind/core/filter/WindFilter.php deleted file mode 100644 index 827cc218..00000000 --- a/wind/core/filter/WindFilter.php +++ /dev/null @@ -1,11 +0,0 @@ - - * @author xiaoxia xu - * @version $Id$ - * @package - */ -abstract class WindFilter extends WindHandlerInterceptor { - -} \ No newline at end of file diff --git a/wind/core/filter/WindFilterChain.php b/wind/core/filter/WindFilterChain.php deleted file mode 100644 index 5deb89ac..00000000 --- a/wind/core/filter/WindFilterChain.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindFilterChain extends WindHandlerInterceptorChain { - - /** - * @param array $filterConfig - */ - public function __construct($filterConfig) { - $this->_initFilters($filterConfig); - } - - /** - * @param string $filterName - */ - public function deleteFilter($alias) { - unset($this->_interceptors[$alias]); - } - - /** - * 在filter链中动态的添加一个filter - * 当befor为空时,添加到程序结尾处 - * 如果befor有值,则遍历数组,找到befor的位置,将新的过滤器添加到befor后面, - * 并将所有原befor位置后的过滤器往后移一位 - * - * @param string $filterName - * @param string $path - * @param string $beforFilter - */ - public function addFilter($filter, $beforFilter = '') { - if ($beforFilter === '') { - $this->addInterceptors(array(get_class($filter) => $filter)); - return true; - } - $_interceptors = array(); - foreach ($this->_interceptors as $key => $interceptor) { - if ($beforFilter === $key) break; - $_interceptors[$key] = $interceptor; - unset($this->_interceptors[$key]); - } - $_interceptors[get_class($filter)] = $filter; - $this->_interceptors = (array) $_interceptors + (array) $this->_interceptors; - } - - /** - * @param array $filters - */ - private function _initFilters($filters = array()) { - $_temp = array(); - foreach ((array) $filters as $key => $filter) { - if (!is_array($filter)) continue; - $filterClass = Wind::import($filter[WindSystemConfig::CLASS_PATH]); - if (!class_exists($filterClass)) continue; - $_temp[$key] = new $filterClass(); - } - $this->addInterceptors($_temp); - } - -} \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptor.php b/wind/core/filter/WindHandlerInterceptor.php deleted file mode 100644 index 7233cccd..00000000 --- a/wind/core/filter/WindHandlerInterceptor.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class WindHandlerInterceptor extends WindModule { - protected $result = null; - protected $interceptorChain = null; - - abstract public function preHandle(); - - abstract public function postHandle(); - - /** - * @return mixed - */ - public function handle() { - $args = func_get_args(); - $this->result = call_user_func_array(array($this, 'preHandle'), $args); - if ($this->result !== null) { - return $this->result; - } - if (null !== ($handler = $this->interceptorChain->getHandler())) { - $this->result = call_user_func_array(array($handler, 'handle'), $args); - } else { - $this->result = $this->interceptorChain->handle(); - } - call_user_func_array(array($this, 'postHandle'), $args); - return $this->result; - } - - /** - * 设置过滤链对象 - * - * @param WindHandlerInterceptorChain $interceptorChain - */ - public function setHandlerInterceptorChain($interceptorChain) { - $this->interceptorChain = $interceptorChain; - } -} -?> \ No newline at end of file diff --git a/wind/core/filter/WindHandlerInterceptorChain.php b/wind/core/filter/WindHandlerInterceptorChain.php deleted file mode 100644 index b7b53fb5..00000000 --- a/wind/core/filter/WindHandlerInterceptorChain.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHandlerInterceptorChain extends WindModule { - protected $_interceptors = array(); - protected $_callBack = null; - protected $_args = array(); - protected $_state = 0; - - /** - * 设置回调方法 - * - * @param string|array $callBack - * @param array $args - * @return - */ - public function setCallBack($callBack, $args = array()) { - $this->_callBack = $callBack; - $this->_args = $args; - } - - /** - * 执行callback方法 - * - * @throws WindException - * @return void|mixed - */ - public function handle() { - if ($this->_callBack === null) - return null; - if (is_string($this->_callBack) && !function_exists($this->_callBack)) { - throw new WindException( - '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, - WindException::ERROR_FUNCTION_NOT_EXIST); - } - return call_user_func_array($this->_callBack, (array) $this->_args); - } - - /** - * 返回处理句柄 - * - * @return WindHandlerInterceptor - */ - public function getHandler() { - if (count($this->_interceptors) <= 0) { - return $this; - } - if ($this->_state >= count($this->_interceptors)) - return null; - $handler = $this->_interceptors[$this->_state++]; - if ($handler instanceof WindHandlerInterceptor) { - $handler->setHandlerInterceptorChain($this); - return $handler; - } - return $this->getHandler(); - } - - /** - * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 - * - * @param $interceptors - * @return - */ - public function addInterceptors($interceptors) { - if (is_array($interceptors)) - $this->_interceptors += $interceptors; - else - $this->_interceptors[] = $interceptors; - } - - /** - * 重置初始化信息 - * @return boolean - */ - public function reset() { - $this->_interceptors = array(); - $this->_callBack = null; - $this->_args = array(); - $this->_state = 0; - return true; - } -} -?> \ No newline at end of file diff --git a/wind/core/web/WindController.php b/wind/core/web/WindController.php deleted file mode 100644 index 8c70fea6..00000000 --- a/wind/core/web/WindController.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class WindController extends WindSimpleController { - - /* (non-PHPdoc) - * @see WindAction::resolvedActionMethod() - */ - protected function resolvedActionMethod($handlerAdapter) { - $action = $handlerAdapter->getAction(); - if ($action !== 'run') - $action = $this->resolvedActionName($action); - if ($action == 'doAction') - throw new WindException('[core.web.WindController.resolvedActionMethod]', - WindException::ERROR_CLASS_METHOD_NOT_EXIST); - $method = new ReflectionMethod($this, $action); - if ($method->isAbstract() || !$method->isPublic()) { - throw new WindException('[core.web.WindController.resolvedActionMethod]', - WindException::ERROR_CLASS_METHOD_NOT_EXIST); - } - return $action; - } - - /** - * @param string $action - * @throws WindException - */ - protected function resolvedActionName($action) { - return $action . 'Action'; - } -} \ No newline at end of file diff --git a/wind/core/web/WindDispatcher.php b/wind/core/web/WindDispatcher.php deleted file mode 100644 index 29039784..00000000 --- a/wind/core/web/WindDispatcher.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindDispatcher extends WindModule { - /** - * 将上一次请求信息缓存在这个变量中 - * @var array - */ - protected $token; - /** - * @var boolean - */ - protected $display = false; - - /** - * 请求分发处理 - * - * @param WindForward $forward - * @param WindRouter $router - * @param boolean $display - * @return - */ - public function dispatch($forward, $router, $display) { - $this->checkToken($router, false); - if ($forward->getIsRedirect()) - $this->dispatchWithRedirect($forward, $router); - elseif ($forward->getIsReAction()) - $this->dispatchWithAction($forward, $router, $display); - else { - $view = $forward->getWindView(); - if ($view->templateName) { - $vars = $forward->getVars(); - Wind::getApp()->getResponse()->setData($vars, $view->templateName); - Wind::getApp()->getResponse()->setData($vars['G'], true); - $view->render($forward, $router, $this->display); - } - $this->display = false; - } - } - - /** - * 请求分发一个重定向请求 - * @param WindForward $forward - * @param WindUrlBasedRouter $router - * @return - */ - protected function dispatchWithRedirect($forward, $router) { - $_url = $forward->getUrl(); - if (!$_url && $forward->getIsReAction()) { - $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), - $forward->getController(), $forward->getArgs()); - if ($this->checkToken($router)) - throw new WindFinalException( - '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, - WindException::ERROR_SYSTEM_ERROR); - - } else - $_url = $this->_getUrlHelper()->checkUrl($_url); - $this->getResponse()->sendRedirect($_url); - } - - /** - * 请求分发一个操作请求 - * module/controller/action/?param - * @param WindForward $forward - * @param WindRouter $router - * @param boolean $display - * @return - */ - protected function dispatchWithAction($forward, $router, $display) { - if (!$action = $forward->getAction()) - throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', - WindException::ERROR_PARAMETER_TYPE_ERROR); - - $args = $forward->getArgs(); - $this->display = $display; - list($action, $_args) = explode('?', $action . '?'); - $action = trim($action, '/') . '/'; - $action = explode('/', $action); - end($action); - if ($_tmp = prev($action)) - $router->setAction($_tmp); - if ($_tmp = prev($action)) - $router->setController($_tmp); - if ($_tmp = prev($action)) - $router->setModule($_tmp); - if ($this->checkToken($router)) - throw new WindFinalException( - '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, - WindException::ERROR_SYSTEM_ERROR); - - Wind::getApp()->processRequest(); - } - - /** - * 检查请求是否是重复请求 - * @param WindUrlBasedRouter $router - * @param boolean $check - * @return boolean - */ - protected function checkToken($router, $check = true) { - $token = $router->getModule() . '/' . $router->getController() . '/' . $router->getAction(); - if ($check === false) { - $this->token = $token; - } else - return !strcasecmp($token, $this->token); - } - -} diff --git a/wind/core/web/WindErrorHandler.php b/wind/core/web/WindErrorHandler.php deleted file mode 100644 index e5a08652..00000000 --- a/wind/core/web/WindErrorHandler.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindErrorHandler extends WindController { - protected $error = array(); - protected $errorCode = 0; - protected $urlReferer = ''; - protected $errorDir = 'WIND:core.web.view'; - - /* (non-PHPdoc) - * @see WindAction::beforeAction() - */ - public function beforeAction($handlerAdapter) { - $this->error = $this->getInput('error'); - $this->errorCode = (int) $this->getInput('errorCode'); - if ($this->request->getUrlReferer()) - $this->urlReferer = $this->getRequest()->getUrlReferer(); - else - $this->urlReferer = $this->getRequest()->getBaseUrl(); - } - - /* (non-PHPdoc) - * @see WindAction::run() - */ - public function run() { - if ($this->errorCode >= 400 && $this->errorCode <= 505) { - $_statusMsg = ucwords($this->getResponse()->codeMap($this->errorCode)); - $topic = "$this->errorCode - " . $_statusMsg; - $this->getResponse()->setStatus($this->errorCode); - } else - $topic = "Error message"; - $this->setOutput($topic, "errorHeader"); - $this->setOutput($this->urlReferer, "baseUrl"); - $this->setOutput($this->error, "errors"); - $errDir = Wind::getApp()->getConfig('errorpage'); - !$errDir && $errDir = $this->errorDir; - $this->setTemplatePath($errDir); - $this->setTemplate('erroraction'); - } -} \ No newline at end of file diff --git a/wind/core/web/WindForward.php b/wind/core/web/WindForward.php deleted file mode 100644 index 4ad03521..00000000 --- a/wind/core/web/WindForward.php +++ /dev/null @@ -1,205 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindForward extends WindModule { - /** - * 定义视图处理器 - * @var WindView - */ - protected $windView = null; - /** - * 模板变量信息 - * @var array - */ - private $vars = array('G' => array()); - /** - * 是否为Action请求 - * @var boolean - */ - private $isReAction = false; - /** - * 是否是重定向请求 - * @var boolean - */ - private $isRedirect = false; - /** - * 跳转链接 - * @var string - */ - private $url; - private $action; - private $controller; - private $args; - - /** - * 将请求重定向到另外一个Action操作 - * @param string $action | $action 操作 - * @param string $controller | controller 路径 , controller 为空是则指向当前的控制器 - * @param array $args | 参数 - * @param boolean $isRedirect | 是否重定向 - * - * @return - */ - public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { - $this->setIsReAction(true); - $this->setAction($action); - $this->setController($controller); - $this->setArgs($args); - $this->setIsRedirect($isRedirect); - } - - /** - * 将请求重定向到另外一个Action操作 - * $action参数支持: - * module/controller/action/?a=&b=&c= - * - * @param string $action | $action 操作 - * @param array $args | 参数 - * @param boolean $isRedirect | 是否重定向 - * @return - */ - public function forwardAction($action, $args = array(), $isRedirect = false) { - $this->setIsReAction(true); - $this->setAction($action); - $this->setArgs($args); - $this->setIsRedirect($isRedirect); - } - - /** - * 设置页面模板变量 - * - * @param string|array|object $vars - * @param string $key - */ - public function setVars($vars, $key = '', $isG = false) { - if (!$key) { - if (is_object($vars)) - $vars = get_object_vars($vars); - if (is_array($vars)) - if ($isG) - $this->vars['G'] = $vars; - else - $this->vars += $vars; - } else { - if ($isG) - $this->vars['G'][$key] = $vars; - else - $this->vars[$key] = $vars; - } - } - - /** - * @return the $isRedirect - */ - public function getIsRedirect() { - return $this->isRedirect; - } - - /** - * @param boolean $isRedirect - */ - public function setIsRedirect($isRedirect) { - $this->isRedirect = $isRedirect; - } - - /** - * @return the $isReAction - */ - public function getIsReAction() { - return $this->isReAction; - } - - /** - * @param boolean $isReAction - */ - public function setIsReAction($isReAction) { - $this->isReAction = $isReAction; - } - - /** - * @return the $vars - */ - public function getVars() { - return $this->vars; - } - - /** - * @return the $url - */ - public function getUrl() { - return $this->url; - } - - /** - * @param string $url - */ - public function setUrl($url) { - $this->url = $url; - } - - /** - * @return the $action - */ - public function getAction() { - return $this->action; - } - - /** - * @return the $controller - */ - public function getController() { - return $this->controller; - } - - /** - * @return the $args - */ - public function getArgs() { - return $this->args; - } - - /** - * @param field_type $action - */ - public function setAction($action) { - $this->action = $action; - } - - /** - * @param field_type $controller - */ - public function setController($controller) { - $this->controller = $controller; - } - - /** - * @param field_type $args - */ - public function setArgs($args) { - $this->args = $args; - } - - /** - * @return WindView - */ - public function getWindView() { - if ($this->windView === null) - $this->_getWindView(); - $module = Wind::getApp()->getModules(); - isset($module['template-dir']) && $this->windView->templateDir = $module['template-dir']; - isset($module['compile-dir']) && $this->windView->compileDir = $module['compile-dir']; - return $this->windView; - } - - /** - * @param WindView $windView - */ - public function setWindView($windView) { - $this->windView = $windView; - } -} \ No newline at end of file diff --git a/wind/core/web/WindSimpleController.php b/wind/core/web/WindSimpleController.php deleted file mode 100644 index c73ab5af..00000000 --- a/wind/core/web/WindSimpleController.php +++ /dev/null @@ -1,306 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class WindSimpleController extends WindModule implements IWindController { - protected $_vars = array(); - /** - * @var WindForward - */ - protected $forward = null; - /** - * @var WindErrorMessage - */ - protected $errorMessage = null; - - /** - * 默认的操作处理方法 - */ - abstract public function run(); - - /* (non-PHPdoc) - * @see IWindController::doAction() - */ - public function doAction($handlerAdapter) { - if ($this->forward !== null) - $this->_vars = $this->forward->getVars(); - $this->beforeAction($handlerAdapter); - $this->setDefaultTemplateName($handlerAdapter); - $method = $this->resolvedActionMethod($handlerAdapter); - call_user_func_array(array($this, $method), array()); - if ($this->errorMessage !== null) - $this->getErrorMessage()->sendError(); - $this->afterAction($handlerAdapter); - return $this->forward; - } - - /* (non-PHPdoc) - * @see IWindController::resolveActionFilter($action) - */ - protected function resolveActionFilter($__filters) { - @extract(@$this->getRequest()->getRequest(), EXTR_REFS); - $chain = WindFactory::createInstance('WindHandlerInterceptorChain'); - foreach ((array) $__filters as $__filter) { - if (isset($__filter['expression']) && !empty($__filter['expression'])) { - if (!@eval('return ' . $__filter['expression'] . ';')) - continue; - /*list($p, $v) = explode('=', $__filter['expression'] . '='); - if ($this->getRequest()->getRequest($p) != $v) - continue;*/ - } - $__args = array($this->getForward(), $this->getErrorMessage()); - if (isset($__filter['args'])) - $__args = $__args + (array) $__filter['args']; - $chain->addInterceptors(WindFactory::createInstance(Wind::import(@$__filter['class']), $__args)); - } - $chain->getHandler()->handle(); - } - - /** - * @param AbstractWindRouter $handlerAdapter - */ - protected function beforeAction($handlerAdapter) {} - - /** - * @param AbstractWindRouter $handlerAdapter - */ - protected function afterAction($handlerAdapter) {} - - /** - * 重定向一个请求到另外的Action - * @param string $action - * @param array $args - * @param boolean $isRedirect - * @return - */ - protected function forwardAction($action = 'run', $args = array(), $isRedirect = false) { - //$this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); - $this->getForward()->forwardAction($action, $args, $isRedirect); - } - - /** - * 重定向一个请求到另外的URL - * @param string $url - * @return - */ - protected function forwardRedirect($url) { - $this->getForward()->setIsRedirect(true); - $this->getForward()->setUrl($url); - } - - /* 数据处理 */ - /** - * 设置模板数据 - * @param string|array|object $data - * @param string $key - * @return - */ - protected function setOutput($data, $key = '') { - $this->getForward()->setVars($data, $key); - } - - /** - * 设置模板数据 - * @param string|array|object $data - * @param string $key - * @return - */ - protected function setGlobal($data, $key = '') { - $this->getForward()->setVars($data, $key, true); - } - - /** - * 获得输入数据 - * 如果输入了回调方法则返回数组: - * 第一个值:value - * 第二个值:验证结果 - * @param string $name input name - * @param string $type input type (GET POST COOKIE) - * @param string $callback | validation for input - * @return array | string - */ - protected function getInput($name, $type = '', $callback = null) { - if (is_array($name)) - return $this->getInputWithArray($name, $type); - else - return $this->getInputWithString($name, $type, $callback); - } - - /* 模板处理 */ - /** - * 设置页面模板 - * @param string $template - * @return - */ - protected function setTemplate($template) { - $this->getForward()->getWindView()->templateName = $template; - } - - /** - * 设置模板路径 - * @param string $templatePath - * @return - */ - protected function setTemplatePath($templatePath) { - $this->getForward()->getWindView()->templateDir = $templatePath; - } - - /** - * 设置模板文件的扩展名 - * @param string $templateExt - * @return - */ - protected function setTemplateExt($templateExt) { - $this->getForward()->getWindView()->templateExt = $templateExt; - } - - /** - * 设置主题包位置 - * @param string $theme - * @return - */ - protected function setTheme($theme) { - $this->getForward()->getWindView()->thems = $theme; - } - - /** - * 设置页面布局 - * @param string $layout - * @return - */ - protected function setLayout($layout) { - $this->getForward()->getWindView()->layout = $layout; - } - - /* 错误处理 */ - /** - * 添加错误信息 - * @param string $message - * @param string $key - * @return - */ - protected function addMessage($message, $key = '') { - $this->getErrorMessage()->addError($message, $key); - } - - /** - * 发送一个错误 - * @param string $message - * @param string $key - * @param string $errorAction - * @return - */ - protected function showMessage($message = '', $key = '', $errorAction = '') { - $this->addMessage($message, $key); - $this->getErrorMessage()->setErrorAction($errorAction); - $this->getErrorMessage()->sendError(); - } - - /** - * 设置默认的模板名称 - * @param WindUrlBasedRouter $handlerAdapter - * @return - */ - protected function setDefaultTemplateName($handlerAdapter) {} - - /** - * 定义了一种解析策略,使其通过解析请求信息来获得调用的方法。 - * - * @param WindUrlBasedRouter $handlerAdapter - * @return - */ - protected function resolvedActionMethod($handlerAdapter) { - return 'run'; - } - - /** - * @param string $name - * @param string $type - * @param array $callback - * @return Ambigous - */ - private function getInputWithString($name, $type = '', $callback = array()) { - $value = ''; - switch (strtolower($type)) { - case 'form': - $value = $this->getRequest()->getData($name); - break; - case IWindRequest::INPUT_TYPE_GET: - $value = $this->getRequest()->getGet($name); - break; - case IWindRequest::INPUT_TYPE_POST: - $value = $this->getRequest()->getPost($name); - break; - case IWindRequest::INPUT_TYPE_COOKIE: - $value = $this->getRequest()->getCookie($name); - break; - default: - $value = $this->getRequest()->getAttribute($name); - } - return $callback ? array($value, call_user_func_array($callback, array($value))) : $value; - } - - /** - * @param array $name - * @param string $type - * @return array - */ - private function getInputWithArray($name, $type = '') { - $result = array(); - foreach ($name as $key => $value) { - $result[(is_array($value) ? $key : $value)] = $this->getInput($value, $type); - } - return $result; - } - - /** - * @return WindForward - */ - public function getForward() { - return $this->_getForward(); - } - - /** - * @return WindErrorMessage - */ - public function getErrorMessage() { - return $this->_getErrorMessage(); - } - - /** - * @param WindForward $forward - */ - public function setForward($forward) { - $this->forward = $forward; - } - - /** - * @param WindErrorMessage $errorMessage - */ - public function setErrorMessage($errorMessage) { - $this->errorMessage = $errorMessage; - } - -} - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindController { - - /** - * 处理请求并返回Forward对象 - * @param WindUrlBasedRouter $handlerAdapter - * @return WindForward - */ - public function doAction($handlerAdapter); - -} -?> \ No newline at end of file diff --git a/wind/core/web/WindSystemConfig.php b/wind/core/web/WindSystemConfig.php deleted file mode 100644 index 54b8f800..00000000 --- a/wind/core/web/WindSystemConfig.php +++ /dev/null @@ -1,243 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindSystemConfig extends WindModule { - private $appName = ''; - private $modules = array(); - - /** - * @param string $config - * @param string $appName - * @param WindFactory $factory - */ - public function __construct($config, $appName, $factory) { - $this->appName = $appName; - $this->setConfig($config, $factory); - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config, $factory = null) { - if (empty($config)) - return; - if (is_string($config)) { - $configParser = $factory->getInstance('configParser'); - $config = $configParser->parse($config); - if (isset($config[$this->appName])) - $this->_config = $config[$this->appName]; - } else - $this->_config = $this->_config ? array_merge($this->_config, $config) : (array) $config; - } - - /** - * @return the $appName - */ - public function getAppName() { - return $this->appName; - } - - /** - * 返回当前应用的启动脚本位置 - */ - public function getAppClass($default = '') { - return $this->getConfig('class', '', $default); - } - - /** - * 返回应用编码信息 - */ - public function getCharset() { - return $this->getConfig('charset', '', 'utf-8'); - } - - /** - * 返回配置定义中定义的过滤链列表 - * 如果定义$name则返回在filters定义标签内对应的属性值 - * - * @param string $name - * @return array|string - */ - public function getFilters() { - return $this->getConfig('filters'); - } - - /** - * 返回filterChain的类型 - * - * @return array - */ - public function getFilterClass() { - return $this->getConfig('filters', 'class'); - } - - /** - * @param string $name - * @return array|string - */ - public function getRouter() { - return $this->getConfig('router'); - } - - /** - * 返回路由类型定义 - * @return string - */ - public function getRouterClass() { - return $this->getConfig('router', 'class', COMPONENT_ROUTER); - } - - /** - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * @param string $name - * @return array|string - */ - public function getModules($name = '') { - return $this->getConfig('modules', $name, array()); - } - - /** - * 添加module - * controller - * - * Controller - * - * WIND:core.web.WindErrorHandler - * - * - * - * template - * - * htm - * - * @param string $name - * @param array $config - * @return - */ - public function setModules($name, $config = array()) { - if (!$_default = @$this->_config['modules']['default']) { - $_default = $this->getDefaultConfigStruct('modules'); - $this->_config['modules']['default'] = $_default; - } - if (!$config) - $this->_config['modules'][$name] = $_default; - else - $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); - return $this->_config['modules'][$name]; - } - - /** - * 返回module模板定义 - * @param unknown_type $name - * @param unknown_type $default - */ - public function getModuleTemplateDir($name, $default = '') { - return $this->getConfig('template-dir', '', $default, $this->getModules($name)); - } - - /** - * 根据module名称返回错误的处理句柄 - * @param string $name - * @param string $default - * @return string - */ - public function getModuleErrorHandler($name, $default = '') { - return $this->getConfig('errorhandler', '', $default, $this->getModules($name)); - } - - /** - * 返回指定moduleName的controller路径信息 - * @param string $name - * @return string - */ - public function getModuleControllerPath($name, $default = '') { - return $this->getConfig('controller-path', '', $default, $this->getModules($name)); - } - - /** - * 返回指定moduleName的controller后缀 - * @param string $name - * @return string - */ - public function getModuleControllerSuffix($name, $default = '') { - return $this->getConfig('controller-suffix', '', $default, $this->getModules($name)); - } - - /** - * 返回指定ComponentName的Component配置信息 - * @param string $name - * @return string - */ - public function getComponents($name = '', $default = array()) { - return $this->getConfig('components', $name, $default); - } - - /** - * 获得DB配置,根据DB名义的别名来获取DB链接配置信息. - * 当别名为空时,返回全部DB链接配置. - * - * @param string $dbName - */ - public function getDbConfig($dbName = '') { - $config = $this->getConfig('db'); - if (isset($config['resource']) && !empty($config['resource'])) { - $_resource = Wind::getRealPath($config['resource'], true); - $this->_config['db'] = $this->parseConfig($_resource, 'db'); - } - return $this->getConfig('db', $dbName); - } - - /** - * 配置解析方法 - * @param string $config - * @param string $key - * @param string|boolean $append - * @param factory - */ - private function parseConfig($config, $key = 'config', $append = true) { - if (!$config) - return array(); - $configParser = $this->getSystemConfig()->getInstance('configParser'); - return $configParser->parse($config); - } - - /** - * 返回对应的配置结构及默认值 - * @param string $configName - * @throws WindException - * @return string - */ - public function getDefaultConfigStruct($configName) { - $_tmp = array(); - $_tmp['modules']['controller-path'] = $this->getConfig('controller-path', '', 'controller'); - $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', - 'Controller'); - $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', - 'WIND:core.web.WindErrorHandler'); - return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); - } -} \ No newline at end of file diff --git a/wind/core/web/WindUrlHelper.php b/wind/core/web/WindUrlHelper.php deleted file mode 100644 index a9bfa467..00000000 --- a/wind/core/web/WindUrlHelper.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindUrlHelper extends WindModule { - - /** - * 构造返回Url地址 - * - * 将根据是否开启url重写来分别构造相对应的url - * - * @param string $action 执行的操作 - * @param string $controller 执行的controller - * @param array $params 附带的参数 - * @return string - */ - public function createUrl($action, $controller = '', $params = array()) { - $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); - return $router->buildUrl($action, $controller, $params); - } -} -?> \ No newline at end of file diff --git a/wind/core/web/WindWebApplication.php b/wind/core/web/WindWebApplication.php deleted file mode 100644 index 1f43ce92..00000000 --- a/wind/core/web/WindWebApplication.php +++ /dev/null @@ -1,247 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindWebApplication extends WindModule implements IWindApplication { - /** - * @var WindHttpRequest - */ - private $request; - /** - * @var WindHttpResponse - */ - private $response; - /** - * @var WindFactory - */ - protected $windFactory = null; - /** - * @var WindDispatcher - */ - protected $dispatcher = null; - /** - * @var WindRouter - */ - protected $handlerAdapter = null; - protected $defaultModule = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', - 'error-handler' => 'WIND:core.web.WindErrorHandler'); - - /** - * 应用初始化操作 - * - * @param array|string $config - * @param WindFactory $factory - * @param string $runCallBack - */ - public function __construct($config, $factory) { - $this->request = new WindHttpRequest(); - $this->response = $this->request->getResponse(@$config['charset']); - $this->windFactory = $factory; - $this->setConfig($config); - } - - /* (non-PHPdoc) - * @see IWindApplication::run() - */ - public function run() { - set_error_handler('WindHelper::errorHandle'); - set_exception_handler('WindHelper::exceptionHandle'); - $this->setModules('default', $this->defaultModule); - $this->windFactory->loadClassDefinitions($this->getConfig('components')); - $this->_getHandlerAdapter()->route(); - $this->processRequest(); - restore_error_handler(); - restore_exception_handler(); - $this->response->sendResponse(); - Wind::resetApp(); - } - - /* (non-PHPdoc) - * @see IWindApplication::doDispatch() - */ - public function doDispatch($forward, $display = false) { - if ($forward === null) - return; - $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, $display); - } - - /** - * 请求处理 - * @return - */ - public function processRequest() { - try { - if (!$this->handlerAdapter->getModule()) - $this->handlerAdapter->setModule('default'); - if (!($module = $this->getModules())) - throw new WindActionException( - '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', - 404); - $module = WindUtility::mergeArray($this->defaultModule, $module); - $handlerPath = @$module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . @$module['controller-suffix']; - if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->info( - '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); - - $this->getSystemFactory()->addClassDefinitions($handlerPath, - array('path' => $handlerPath, 'scope' => 'prototype', 'proxy' => true, - 'config' => $this->getConfig('actionmap'), - 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), - 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); - $handler = $this->windFactory->getInstance($handlerPath); - - if (!$handler) - throw new WindActionException( - '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', - 404); - $this->doDispatch($handler->doAction($this->handlerAdapter)); - } catch (WindActionException $e) { - $this->sendErrorMessage($e); - } catch (WindException $e) { - $this->sendErrorMessage($e); - } - } - - /** - * 异常处理请求 - * @param WindActionException actionException - * @return - */ - protected function sendErrorMessage($exception) { - $moduleName = $this->handlerAdapter->getModule(); - if ($moduleName === 'error') - throw new WindFinalException($exception->getMessage()); - - $errorMessage = null; - if ($exception instanceof WindActionException) - $errorMessage = $exception->getError(); - if (!$errorMessage) { - $errorMessage = $this->windFactory->getInstance('errorMessage'); - $errorMessage->addError($exception->getMessage()); - } - if (!$_errorAction = $errorMessage->getErrorAction()) { - $module = $this->getModules($moduleName); - if (empty($module)) - $module = $this->setModules('default'); - preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); - $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); - $_errorAction = 'error/' . @$matchs[0] . '/run/'; - $this->setModules('error', - array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); - } - $forward = $this->getSystemFactory()->getInstance('forward'); - $forward->forwardAction($_errorAction); - $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); - $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); - $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); - } - - /** - * 添加module - * controller - * - * Controller - * - * WIND:core.web.WindErrorHandler - * - * - * - * template - * - * htm - * - * @param string $name - * @param array $config - * @return array - */ - public function setModules($name, $config = array()) { - if (!isset($this->_config['modules'][$name])) { - $this->_config['modules'][$name] = (array) $config; - } - - /*if (isset($this->_config['modules']['default'])) - $_default = $this->_config['modules']['default']; - else { - $this->_config['modules']['default'] = $_default; - } - if (!$config) - $this->_config['modules'][$name] = $_default; - else - $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); - return $this->_config['modules'][$name];*/ - } - - /** - * @param string $name - * @throws WindActionException - * @throws WindException - * @return array - */ - public function getModules($name = '') { - if ($name === '') - return $this->getConfig('modules', $this->handlerAdapter->getModule()); - return $this->getConfig('modules', $name, array()); - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - if (!$config) - return; - $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; - $this->_config = $config; - } - - /** - * @param object $componentInstance - * @param string $componentName - */ - public function registeComponent($componentName, $componentInstance, $scope) { - return $this->windFactory->registInstance($componentInstance, $componentName); - } - - /** - * @param string $componentName - * @return object - */ - public function getComponent($componentName) { - $component = null; - switch ($componentName) { - case 'windCache': - if ($this->getConfig('iscache', '', true)) - $component = $this->windFactory->getInstance($componentName); - break; - default: - $component = $this->windFactory->getInstance($componentName); - break; - } - return $component; - } - - /** - * @return WindHttpRequest $request - */ - public function getRequest() { - return $this->request; - } - - /** - * @return WindHttpResponse $response - */ - public function getResponse() { - return $this->response; - } - - /** - * @return WindFactory $windFactory - */ - public function getWindFactory() { - return $this->windFactory; - } -} \ No newline at end of file diff --git a/wind/core/web/filter/WindUrlFilter.php b/wind/core/web/filter/WindUrlFilter.php deleted file mode 100644 index 201a3dc8..00000000 --- a/wind/core/web/filter/WindUrlFilter.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindUrlFilter extends WindFilter { - - /* (non-PHPdoc) - * @see WindFilter::preHandle() - */ - public function preHandle($request = null, $response = null) { - - } - - /* (non-PHPdoc) - * @see WindFilter::postHandle() - */ - public function postHandle($request = null, $response = null) { - - } - -} - -?> \ No newline at end of file diff --git a/wind/core/web/listener/WindFormListener.php b/wind/core/web/listener/WindFormListener.php deleted file mode 100644 index edc54f20..00000000 --- a/wind/core/web/listener/WindFormListener.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindFormListener extends WindHandlerInterceptor { - - /** - * @var WindHttpRequest - */ - private $request = null; - - private $formPath = ''; - - private $errorMessage = null; - - /** - * @param WindHttpRequest $request - * @param string $formPath - */ - public function __construct($request, $formPath, $errorMessage) { - $this->request = $request; - $this->formPath = $formPath; - $this->errorMessage = $errorMessage; - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - $className = Wind::import($this->formPath); - if (!class_exists($className)) - throw new WindException('the form \'' . $this->formPath . '\' is not exists!'); - if ('WindEnableValidateModule' != get_parent_class($className)) - throw new WindException('the form \'' . $this->formPath . '\' is not extends \'WindEnableValidateModule\'!'); - $form = new $className(); - $methods = get_class_methods($form); - foreach ($methods as $method) { - if ((0 !== strpos($method, 'set')) || ('' == ($_tmp = substr($method, 3)))) - continue; - $_tmp[0] = strtolower($_tmp[0]); - $value = $this->request->getPost($_tmp) ? $this->request->getPost($_tmp) : $this->request->getGet($_tmp); - if (null === $value) - continue; - call_user_func_array(array($form, $method), array($value)); - } - call_user_func_array(array($form, 'validate'), array($form)); - if (($error = $form->getErrors())) { - list($errorController, $errorAction) = $form->getErrorControllerAndAction(); - $this->sendError($errorController, $errorAction, $error); - } - $this->request->setAttribute('formData', $form); - } - - private function sendError($errorController, $errorAction, $errors) { - $this->errorMessage->setErrorController($errorController); - $this->errorMessage->setErrorAction($errorAction); - $this->errorMessage->addError($errors); - $this->errorMessage->sendError(); - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - // TODO Auto-generated method stub - } -} - -?> \ No newline at end of file diff --git a/wind/core/web/listener/WindValidateListener.php b/wind/core/web/listener/WindValidateListener.php deleted file mode 100644 index 71be225a..00000000 --- a/wind/core/web/listener/WindValidateListener.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindValidateListener extends WindHandlerInterceptor { - - /** - * @var WindHttpRequest - */ - private $request = null; - - private $validateRules = array(); - - private $validator = null; - - private $validatorClass = ''; - - private $defaultMessage = '验证失败'; - - /** - * @param WindHttpRequest $request - * @param array $validateRules - * @param string $validatorClass - */ - public function __construct($request, $validateRules, $validatorClass) { - $this->request = $request; - $this->validateRules = (array) $validateRules; - $this->validatorClass = $validatorClass; - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - if (!isset($this->validateRules['errorMessage'])) - $errorMessage = new WindErrorMessage(); - else { - $errorMessage = $this->validateRules['errorMessage']; - unset($this->validateRules['errorMessage']); - } - $_input = new stdClass(); - foreach ((array) $this->validateRules as $rule) { - if (!is_array($rule)) - continue; - $key = $rule['field']; - $value = $this->request->getGet($key) ? $this->request->getGet($key) : $this->request->getPost( - $key); - $args = $rule['args']; - array_unshift($args, $value); - if (call_user_func_array(array($this->getValidator(), $rule['validator']), - (array) $args) === false) { - if (null === $rule['default']) - $errorMessage->addError( - ($rule['message'] ? $rule['message'] : $this->defaultMessage), $key); - else - $value = $rule['default']; - } - $this->request->setAttribute($key, $value); - $_input->$key = $value; - } - if ($errorMessage->getError()) - $errorMessage->sendError(); - else - $this->request->setAttribute('inputData', $_input); - } - - /** - * 返回validator对象 - * @throws WindException - * @return WindValidator - */ - private function getValidator() { - if ($this->validator === null) { - $_className = Wind::import($this->validatorClass); - $this->validator = WindFactory::createInstance($_className); - if ($this->validator === null) - throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR); - } - return $this->validator; - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - - } - -} - -?> \ No newline at end of file diff --git a/wind/core/web/view/404.htm b/wind/core/web/view/404.htm deleted file mode 100644 index e5626d85..00000000 --- a/wind/core/web/view/404.htm +++ /dev/null @@ -1,140 +0,0 @@ - - - - -404 Not Found - - - -
-
-

404 Not Found

-
-
-
-
- - \ No newline at end of file diff --git a/wind/core/web/view/error.htm b/wind/core/web/view/error.htm deleted file mode 100644 index ffa40483..00000000 --- a/wind/core/web/view/error.htm +++ /dev/null @@ -1,155 +0,0 @@ - - - - -<?php echo $topic; ?> - - - -
-

-
-

-

-
    - $value): - if($key == $currentLine):?> -
  • - -
  • - -
- -

__Stack:

-
    - -
  • - -
-
-
-
- - \ No newline at end of file diff --git a/wind/core/web/view/erroraction.htm b/wind/core/web/view/erroraction.htm deleted file mode 100644 index 97e2593f..00000000 --- a/wind/core/web/view/erroraction.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -{@G:title} - - - -
- - - - -
-

{$errorHeader}:

-

- {$key}. {$error}
-

-

You Can Get Help In:

-

{@WindHelper::errorInfo()}

-
-
- - \ No newline at end of file From cfc1cbad0dcc9926a4d30d229edcd2c149d30597 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 08:03:18 +0000 Subject: [PATCH 0427/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2499 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/cache/AbstractWindCache.php | 258 ------------------ .../cache/AbstractWindCacheDependency.php | 64 ----- .../dependency/WindDbCacheDependency.php | 51 ---- .../dependency/WindFileCacheDependency.php | 27 -- .../cache/exception/WindCacheException.php | 13 - .../component/cache/strategy/WindApcCache.php | 45 --- wind/component/cache/strategy/WindDbCache.php | 171 ------------ .../cache/strategy/WindEacceleratorCache.php | 52 ---- .../cache/strategy/WindFileCache.php | 151 ---------- .../component/cache/strategy/WindMemCache.php | 86 ------ .../component/cache/strategy/WindWinCache.php | 46 ---- wind/component/cache/strategy/WindXCache.php | 71 ----- .../cache/strategy/WindZendCache.php | 45 --- 13 files changed, 1080 deletions(-) delete mode 100644 wind/component/cache/AbstractWindCache.php delete mode 100644 wind/component/cache/AbstractWindCacheDependency.php delete mode 100644 wind/component/cache/dependency/WindDbCacheDependency.php delete mode 100644 wind/component/cache/dependency/WindFileCacheDependency.php delete mode 100644 wind/component/cache/exception/WindCacheException.php delete mode 100644 wind/component/cache/strategy/WindApcCache.php delete mode 100644 wind/component/cache/strategy/WindDbCache.php delete mode 100644 wind/component/cache/strategy/WindEacceleratorCache.php delete mode 100644 wind/component/cache/strategy/WindFileCache.php delete mode 100644 wind/component/cache/strategy/WindMemCache.php delete mode 100644 wind/component/cache/strategy/WindWinCache.php delete mode 100644 wind/component/cache/strategy/WindXCache.php delete mode 100644 wind/component/cache/strategy/WindZendCache.php diff --git a/wind/component/cache/AbstractWindCache.php b/wind/component/cache/AbstractWindCache.php deleted file mode 100644 index 4b07da99..00000000 --- a/wind/component/cache/AbstractWindCache.php +++ /dev/null @@ -1,258 +0,0 @@ - - * @author Su Qian - * @version $Id$ - * @package - */ -abstract class AbstractWindCache extends WindModule { - /** - * key的安全码 - * @var string - */ - private $securityCode = ''; - /** - * 缓存前缀 - * @var sting - */ - private $keyPrefix = ''; - /** - * 缓存过期时间 - * @var int - */ - private $expire = ''; - /** - * 缓存依赖的类名称 - * @var string - */ - const DEPENDENCYCLASS = 'dependencyclass'; - /** - * 标志存储时间 - * @var string - */ - const STORETIME = 'store'; - /** - * 标志存储数据 - * @var string - */ - const DATA = 'data'; - /** - * 配置文件中标志缓存依赖名称的定义 - * @var string - */ - const DEPENDENCY = 'dependency'; - /* - * 配置项 - */ - /** - * 配置文件中标志过期时间名称定义(也包含缓存元数据中过期时间 的定义) - * @var string - */ - const EXPIRE = 'expires'; - - /** - * 执行添加操作 - * - * @param string $key - * @param object $value - * @param int $expires - * @throws WindException - */ - protected abstract function setValue($key, $value, $expires = 0); - - /** - * 执行获取操作 - * - * @param string $key - * @throws WindException - */ - protected abstract function getValue($key); - - /** - * 需要实现的删除操作 - * @param string $key - * @return - */ - protected abstract function deleteValue($key); - - /** - * 清空所有缓存 - * @return - */ - public abstract function clear(); - - /** - * 设置缓存,如果key不存在,设置缓存,否则,替换已有key的缓存。 - * @param string $key 保存缓存数据的键。 - * @param string $value 保存缓存数据。 - * @param int $expires 缓存数据的过期时间,0表示永不过期 - * @param IWindCacheDependency $denpendency 缓存依赖 - * @return boolean - */ - public function set($key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { - try { - $data = array(self::DATA => $value, self::EXPIRE => $expires ? $expires : $this->getExpire(), self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); - if (null != $denpendency) { - $denpendency->injectDependent(); - $data[self::DEPENDENCY] = serialize($denpendency); - $data[self::DEPENDENCYCLASS] = get_class($denpendency); - } - return $this->setValue($this->buildSecurityKey($key), serialize($data), $data[self::EXPIRE]); - } catch (Exception $e) { - throw new WindCacheException('Setting cache failed.' . $e->getMessage()); - } - } - - /** - * 获取指定缓存 - * @param string $key 获取缓存数据的标识,即键 - * @return mixed - */ - public function get($key) { - try { - return $this->formatData($key, $this->getValue($this->buildSecurityKey($key))); - } catch (Exception $e) { - throw new WindCacheException('Getting cache data failed. (' . $e->getMessage() . ')'); - } - } - - /** - * 通过key批量获取缓存数据 - * @param array $keys - * @return array - */ - public function batchGet(array $keys) { - $data = array(); - foreach ($keys as $key) { - $data[$key] = $this->get($key); - } - return $data; - } - - /** - * 删除缓存数据 - * - * @param string $key 获取缓存数据的标识,即键 - * @return string - */ - public function delete($key) { - try { - return $this->deleteValue($this->buildSecurityKey($key)); - } catch (Exception $e) { - throw new WindException('Delete cache data failed. (' . $e->getMessage() . ')'); - } - } - - /** - * 通过key批量删除缓存数据 - * @param array $keys - * @return boolean - */ - public function batchDelete(array $keys) { - foreach ($keys as $key) - $this->delete($key); - return true; - } - - /** - * 格式化输出,如果没有数据~则返回false - * - * @param string $value - * @return string|boolean - */ - protected function formatData($key, $value) { - $data = unserialize($value); - if (!is_array($data)) return false; - if ($this->hasChanged($key, $data)) return false; - return isset($data[self::DATA]) ? $data[self::DATA] : false; - } - - /** - * 如果缓存中有数据,则检查缓存依赖是否已经变更,如果变更则删除缓存 - * - * @param string $key 键 - * @param array $data 缓存中的数据 - * @return boolean true表示缓存依赖已变更,false表示缓存依赖未变改 - */ - protected function hasChanged($key, array $data) { - if (isset($data[self::DEPENDENCY]) && $data[self::DEPENDENCY]) { - $dependency = unserialize($data[self::DEPENDENCY]); - if (!$dependency->hasChanged($this)) return false; - } elseif (isset($data[self::EXPIRE]) && $data[self::EXPIRE]) { - $_overTime = $data[self::EXPIRE] + $data[self::STORETIME]; - if ($_overTime >= time()) return false; - } else - return false; - $this->delete($key); - return true; - } - - /** - * 生成安全的key - * - * @param string $key - * @return string - */ - protected function buildSecurityKey($key) { - return md5($this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key . $this->getSecurityCode() : $key . $this->getSecurityCode()); - } - - /** - * 返回缓存Key值前缀,默认值为null无任何前缀添加 - * - * @return the $prefix - */ - protected function getKeyPrefix() { - return $this->keyPrefix; - } - - /** - * @param sting $keyPrefix - */ - public function setKeyPrefix($keyPrefix) { - $this->keyPrefix = $keyPrefix; - } - - /** - * @return the $securityCode - */ - protected function getSecurityCode() { - return $this->securityCode; - } - - /** - * @param string $securityCode - */ - public function setSecurityCode($securityCode) { - $this->securityCode = $securityCode; - } - - /** - * 返回过期时间设置,默认值为0永不过期 - * @return the $expire - */ - public function getExpire() { - return $this->expire; - } - - /** - * @param int $expire - */ - public function setExpire($expire) { - $this->expire = intval($expire); - } - - /** - * 设置配置信息 - * - * @param array $config - */ - public function setConfig($config) { - parent::setConfig($config); - $this->setSecurityCode($this->getConfig('security-code', '', '')); - $this->setKeyPrefix($this->getConfig('key-prefix', '', '')); - $this->setExpire($this->getConfig('expires', '', 0)); - } -} \ No newline at end of file diff --git a/wind/component/cache/AbstractWindCacheDependency.php b/wind/component/cache/AbstractWindCacheDependency.php deleted file mode 100644 index 80f56701..00000000 --- a/wind/component/cache/AbstractWindCacheDependency.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - */ -abstract class AbstractWindCacheDependency extends WindModule { - - /** - * 依赖的依据 - * - * @var mixed - */ - protected $data = ''; - - /** - * @var string 依赖项的上次更改时间 - */ - protected $lastModified; - - /** - * 初始化设置,设置依赖 - */ - public function injectDependent() { - $this->lastModified = time(); - $this->data = $this->notifyDependencyChanged(); - } - - /** - * 检查是否有变更 - * - * @return boolean - */ - public function hasChanged() { - return $this->data != $this->notifyDependencyChanged(); - } - - /** - * 获得依赖数据 - * - * @return mixed - */ - public function getDenpendencyData() { - return $this->data; - } - - /** - * 获得最后更新时间 - * @return int - */ - public function getLastModified() { - return $this->lastModified; - } - - /** - * 是否有变化 - * - * @return mixed 新的值 - */ - protected abstract function notifyDependencyChanged(); - -} \ No newline at end of file diff --git a/wind/component/cache/dependency/WindDbCacheDependency.php b/wind/component/cache/dependency/WindDbCacheDependency.php deleted file mode 100644 index fd58c835..00000000 --- a/wind/component/cache/dependency/WindDbCacheDependency.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - */ -Wind::import('WIND:component.cache.dependency.AbstractWindCacheDependency'); -class WindDbCacheDependency extends AbstractWindCacheDependency{ - private $sql = ''; - private $configName = ''; - private $connection = null; - - public function __construct($sql, $configName = '') { - $sql && $this->sql = $sql; - $configName && $this->configName = $configName; - } - - /* - * (non-PHPdoc) - * @see WindCacheDependency::notifyDependencyChanged() - */ - protected function notifyDependencyChanged() { - if (!$this->sql) return null; - return $this->getConnection()->query($this->sql)->fetchAll(); - } - - /** - * 获得链接对象 - */ - private function getConnection() { - if ( null != $this->connection) return $this->connection; - $alias = 'db_' . $this->configName; - if (!$this->getSystemFactory()->checkAlias($alias)) { - $config = $this->getSystemConfig()->getDbConfig($this->configName); - $definition = array( - 'path' => $this->getConfig('class', '', 'COM:db.WindConnection', $config), - 'alias' => $alias, - 'config' => $config, - 'initMethod' => 'init', - 'scope' => 'application', - ); - $this->getSystemFactory()->addClassDefinitions($alias, $definition); - } - $this->connection = $this->getSystemFactory()->getInstance($alias); - return $this->connection; - } - - -} \ No newline at end of file diff --git a/wind/component/cache/dependency/WindFileCacheDependency.php b/wind/component/cache/dependency/WindFileCacheDependency.php deleted file mode 100644 index c72a3719..00000000 --- a/wind/component/cache/dependency/WindFileCacheDependency.php +++ /dev/null @@ -1,27 +0,0 @@ - 2011-7-25 - * @link http://www.cnblogs.com/xiaoyaoxia/ - * @copyright Copyright © 2011-2012 xiaoxiao - * @license - * @package - */ -Wind::import('WIND:component.cache.AbstractWindCacheDependency'); -class WindFileCacheDependency extends AbstractWindCacheDependency { - private $fileName = ''; - - public function __construct($fileName = null) { - $this->fileName = $fileName; - } - - /* - * (non-PHPdoc) - * @see AbstractWindCacheDependency::notifyDependencyChanged() - */ - protected function notifyDependencyChanged() { - clearstatcache();//删除文件信息的缓存 - if ($this->fileName) { - return @filemtime($this->fileName); - } - } -} \ No newline at end of file diff --git a/wind/component/cache/exception/WindCacheException.php b/wind/component/cache/exception/WindCacheException.php deleted file mode 100644 index 17a4c37e..00000000 --- a/wind/component/cache/exception/WindCacheException.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindCacheException extends WindException { - - -} - -?> \ No newline at end of file diff --git a/wind/component/cache/strategy/WindApcCache.php b/wind/component/cache/strategy/WindApcCache.php deleted file mode 100644 index cbcc786e..00000000 --- a/wind/component/cache/strategy/WindApcCache.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindApcCache extends AbstractWindCache { - - public function __construct(){ - if (!extension_loaded('apc')) { - throw new WindCacheException('The apc extension must be loaded !'); - } - } - - /* - * @see AbstractWindCache#setValue() - */ - protected function setValue($key, $value, $expires = 0) { - return apc_store($key, $value, $expires); - } - - /* - * @see AbstractWindCache#getValue() - */ - protected function getValue($key) { - return apc_fetch($key); - } - /* - * @see AbstractWindCache#deleteValue() - */ - protected function deleteValue($key) { - return apc_delete($key); - } - - /* - * @see AbstractWindCache#clear() - */ - public function clear() { - apc_clear_cache(); - return apc_clear_cache('user'); - } -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindDbCache.php b/wind/component/cache/strategy/WindDbCache.php deleted file mode 100644 index 56d8f5d4..00000000 --- a/wind/component/cache/strategy/WindDbCache.php +++ /dev/null @@ -1,171 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindDbCache extends AbstractWindCache { - - /** - * 链接句柄 - * @var AbstractWindDbAdapter - */ - private $connection; - - /** - * 缓存表 - * @var string - */ - private $table = 'pw_cache'; - - /** - * 缓存表的键字段 - * @var string - */ - private $keyField = 'key'; - - /** - * 缓存表的值字段 - * @var string - */ - private $valueField = 'value'; - - /** - * 缓存表过期时间字段 - * @var string - */ - private $expireField = 'expire'; - - /** - * 配置文件 - * @var string - */ - private $dbConfigName = ''; - - public function __construct(WindConnection $connection = null, $config = array()) { - $connection && $this->setConnection($connection); - $config && $this->setConfig($config); - } - - /* - * @see AbstractWindCache#setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return $this->store($key, $value, $expire); - } - - /* - * @see AbstractWindCache#getValue() - */ - protected function getValue($key) { - $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; - $data = $this->getConnection()->createStatement($sql)->getOne(array($key, time())); - return $data[$this->valueField]; - } - - /* - * @see AbstractWindCache#batchFetch() - */ - public function batchGet(array $keys) { - foreach ($keys as $key => $value) { - $keys[$key] = $this->buildSecurityKey($value); - } - list($sql, $result) = array('', array()); - $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys) . ' AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; - $data = $this->getConnection()->createStatement($sql)->queryAll(array(time())); - foreach ($data as $tmp) { - $result[] = $this->formatData(array_search($tmp[$this->keyField], $keys), $tmp[$this->valueField]); - } - return $result; - } - - /* - * @see AbstractWindCache#deleteValue() - */ - protected function deleteValue($key) { - $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` = ? '; - return $this->getConnection()->createStatement($sql)->update(array($key)); - } - - /* - * @see AbstractWindCache#batchDelete() - */ - public function batchDelete(array $keys) { - foreach ($keys as $key => $value) { - $keys[$key] = $this->buildSecurityKey($value); - } - $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys); - return $this->getConnection()->execute($sql); - } - - /* - * @see AbstractWindCache#clear() - */ - public function clear() { - return $this->getConnection()->execute('DELETE FROM ' . $this->getTableName()); - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->table = $this->getConfig('table-name', '', 'pw_cache', $config); - $this->keyField = $this->getConfig('field-key', '', 'key', $config); - $this->valueField = $this->getConfig('field-value', '', 'value', $config); - $this->expireField = $this->getConfig('field-expire', '', 'expire', $config); - $this->dbConfigName = $this->getConfig('dbconfig-name', '', '', $config); - } - - /** - * 设置链接对象 - * @param WindConnection $connection - */ - public function setConnection($connection) { - if ($connection instanceof WindConnection) $this->connection = $connection; - } - - /** - * 返回表名 - * @return string - */ - private function getTableName() { - return $this->table; - } - - /** - * 存储数据 - * @param string $key - * @param string $value - * @param int $expires - * @param IWindCacheDependency $denpendency - * @return boolean - */ - private function store($key, $value, $expires = 0) { - ($expires > 0) ? $expires += time() : $expire=0; - $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires); - $sql = 'REPLACE INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db); - return $this->getConnection()->createStatement($sql)->update(); - } - - /** - * 获得链接对象 - * @return WindConnection - */ - private function getConnection() { - if (null == $this->connection) { - $config = $this->getSystemConfig()->getDbConfig($this->dbConfigName); - $path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); - $alias = $this->dbConfigName ? $path . $this->dbConfigName : $path . get_class($this); - if (!$this->getSystemFactory()->checkAlias($alias)) { - $definition = array('path' => $path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', 'scope' => 'application'); - $this->getSystemFactory()->addClassDefinitions($alias, $definition); - } - $this->connection = $this->getSystemFactory()->getInstance($alias); - } - return $this->connection; - } -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindEacceleratorCache.php b/wind/component/cache/strategy/WindEacceleratorCache.php deleted file mode 100644 index 35a466a2..00000000 --- a/wind/component/cache/strategy/WindEacceleratorCache.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindEacceleratorCache extends AbstractWindCache { - - public function __construct() { - if (!function_exists('eaccelerator_get')) { - throw new WindCacheException('The eaccelerator extension must be loaded !'); - } - } - - /* - * @see AbstractWindCache#setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return eaccelerator_put($key, $value, $expire); - } - - /* - * @see AbstractWindCache#get() - */ - protected function getValue($key) { - return eaccelerator_get($key); - } - - /* - * @see AbstractWindCache#deleteValue() - */ - protected function deleteValue($key) { - return eaccelerator_rm($key); - } - - /* - * @see AbstractWindCache#clear() - * @return boolean - */ - public function clear() { - eaccelerator_gc(); - $cacheKeys = eaccelerator_list_keys(); - foreach ($cacheKeys as $key) { - $this->delete(substr($key['name'], 1)); - } - } -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindFileCache.php b/wind/component/cache/strategy/WindFileCache.php deleted file mode 100644 index 47a2c76a..00000000 --- a/wind/component/cache/strategy/WindFileCache.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindFileCache extends AbstractWindCache { - - /** - * 缓存目录 - * @var string - */ - private $cacheDir; - - /** - * 缓存后缀 - * @var string - */ - private $cacheFileSuffix = 'txt'; - - /** - * 缓存多级目录。最好不要超3层目录 - * @var int - */ - private $cacheDirectoryLevel = 0; - - /** - * 保存操作的路径信息, 存储使用过的key路径 - * @var array - */ - private $cacheFileList = array(); - - /* (non-PHPdoc) - * @see AbstractWindCache::setValue($key, $value, $expires) - */ - protected function setValue($key, $value, $expire = 0) { - return WindFile::write($key, $value) == strlen($value); - } - - /* (non-PHPdoc) - * @see AbstractWindCache::get() - */ - protected function getValue($key) { - if (!is_file($key)) return null; - return WindFile::read($key); - } - - /* (non-PHPdoc) - * @see AbstractWindCache::deleteValue() - */ - protected function deleteValue($key) { - return WindFile::write($key, ''); - } - - /* (non-PHPdoc) - * @see AbstractWindCache::clear() - */ - public function clear() { - return WindFile::clearDir($this->getCacheDir()); - } - - /** - * 获取缓存文件名。 - * - * @param string $key - * @return string - */ - protected function buildSecurityKey($key) { - $key = parent::buildSecurityKey($key); - if (false !== ($dir = $this->checkCacheDir($key))) return $dir; - $_dir = $this->getCacheDir(); - if (0 < ($level = $this->getCacheDirectoryLevel())) { - $_subdir = substr(md5($key), 0, $level); - $_dir .= DIRECTORY_SEPARATOR . $_subdir; - if (!is_dir($_dir)) mkdir($_dir, 0777, true); - } - $filename = $key . '.' . $this->getCacheFileSuffix(); - $this->cacheFileList[$key] = ($_dir ? $_dir . DIRECTORY_SEPARATOR . $filename : $filename); - return $this->cacheFileList[$key]; - } - - /** - * 采用最近最少使用原则算法 - * - * @param string $key - * @return string - */ - private function checkCacheDir($key) { - return isset($this->cacheFileList[$key]) ? $this->cacheFileList[$key] : false; - } - - /** - * 设置缓存目录 - * @param string $dir - */ - public function setCacheDir($dir) { - $_dir = Wind::getRealDir($dir); - if (!is_dir($_dir)) mkdir($_dir, 0777, true); - $this->cacheDir = $_dir; - } - - /** - * @return the $cacheDir - */ - private function getCacheDir() { - return $this->cacheDir; - } - - /** - * @param string $cacheFileSuffix - */ - public function setCacheFileSuffix($cacheFileSuffix) { - $this->cacheFileSuffix = $cacheFileSuffix; - } - - /** - * @return the $cacheFileSuffix - */ - private function getCacheFileSuffix() { - return $this->cacheFileSuffix; - } - - /** - * @param int $cacheDirectoryLevel - */ - public function setCacheDirectoryLevel($cacheDirectoryLevel) { - $this->cacheDirectoryLevel = $cacheDirectoryLevel; - } - - /** - * 返回cache目录级别,默认为0,不分级,最大分级为5 - * @return the $cacheDirectoryLevel - */ - public function getCacheDirectoryLevel() { - return $this->cacheDirectoryLevel; - } - - /* (non-PHPdoc) - * @see AbstractWindCache::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->setCacheDir($this->getConfig('dir')); - $this->setCacheFileSuffix($this->getConfig('suffix', '', 'txt')); - $this->setCacheDirectoryLevel($this->getConfig('dir-level', '', 0)); - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindMemCache.php b/wind/component/cache/strategy/WindMemCache.php deleted file mode 100644 index 5b672af2..00000000 --- a/wind/component/cache/strategy/WindMemCache.php +++ /dev/null @@ -1,86 +0,0 @@ -'localhost', - * 'port'=>11211 - * 'pconn'=>true - * ), - * array( - * 'host'=>'localhost', - * 'port'=>11212 - * 'pconn'=>false - * ) - * - * the last known user to change this file in the repository - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindMemCache extends AbstractWindCache { - - /** - * memcache缓存操作句柄 - * @var WindMemcache - */ - protected $memcache = null; - - /** - * 是否对缓存采取压缩存储 - * @var int - */ - protected $compress = 0; - - public function __construct() { - if (!extension_loaded('Memcache')) { - throw new WindCacheException('WindMemCache requires PHP `Memcache` extension to be loaded !'); - } - $this->memcache = new Memcache(); - } - - /* - * @see AbstractWindCache::setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return $this->memcache->set($key, $value, $this->compress, (int) $expire); - } - - /* - * @see AbstractWindCache::getValue() - */ - protected function getValue($key) { - return $this->memcache->get($key); - } - - /* - * @see AbstractWindCache::deleteValue() - */ - protected function deleteValue($key) { - return $this->memcache->delete($key); - } - - /* - * @see AbstractWindCache::clear() - */ - public function clear() { - return $this->memcache->flush(); - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->compress = $this->getConfig('compress', '', '0'); - $servers = $this->getConfig('servers', '', array()); - $defaultServer = array('host' => '', 'port' => '', 'pconn' => true, 'weight' => 1, 'timeout' => 15, - 'retry' => 15, 'status' => true, 'fcallback' => null); - foreach ((array) $servers as $server) { - if (!is_array($server)) throw new WindException('The memcache config is incorrect'); - if (!isset($server['host'])) throw new WindException('The memcache server ip address is not exist'); - if (!isset($server['port'])) throw new WindException('The memcache server port is not exist'); - call_user_func_array(array($this->memcache, 'addServer'), array_merge($defaultServer, $server)); - } - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindWinCache.php b/wind/component/cache/strategy/WindWinCache.php deleted file mode 100644 index a249b54c..00000000 --- a/wind/component/cache/strategy/WindWinCache.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindWinCache extends AbstractWindCache { - - public function __construct() { - if (!function_exists('wincache_ucache_get')) { - throw new WindCacheException('The wincache extension must be loaded !'); - } - } - - /* - * @see AbstractWindCache#setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return wincache_ucache_set($key, $value, $expire); - } - - /* - * @see AbstractWindCache#getValue() - */ - protected function getValue($key) { - return wincache_ucache_get($key); - } - - /* - * @see AbstractWindCache#deleteValue() - */ - protected function deleteValue($key) { - return wincache_ucache_delete($key); - } - - /* - * @see AbstractWindCache#clear() - */ - public function clear() { - return wincache_ucache_clear(); - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindXCache.php b/wind/component/cache/strategy/WindXCache.php deleted file mode 100644 index d07fa7ba..00000000 --- a/wind/component/cache/strategy/WindXCache.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindXCache extends AbstractWindCache { - private $authUser = ''; - private $authPwd = ''; - - public function __construct() { - if (!extension_loaded('xcache')) { - throw new WindCacheException('The xcache extension must be loaded !'); - } - } - - /* - * @see AbstractWindCache#setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return xcache_set($key, $value, $expire); - } - - /* - * @see AbstractWindCache#getValue() - */ - protected function getValue($key) { - return xcache_get($key); - } - - /* - * @see AbstractWindCache#deleteValue() - */ - protected function deleteValue($key) { - return xcache_unset($key); - } - - /* - * @see AbstractWindCache#clear() - */ - public function clear() { - //xcache_clear_cache需要验证权限 - $tmp['user'] = isset($_SERVER['PHP_AUTH_USER']) ? null : $_SERVER['PHP_AUTH_USER']; - $tmp['pwd'] = isset($_SERVER['PHP_AUTH_PW']) ? null : $_SERVER['PHP_AUTH_PW']; - $_SERVER['PHP_AUTH_USER'] = $this->authUser; - $_SERVER['PHP_AUTH_PW'] = $this->authPwd; - //如果配置中xcache.var_count > 0 则不能用xcache_clear_cache(XC_TYPE_VAR, 0)的方式删除 - $max = xcache_count(XC_TYPE_VAR); - for ($i = 0; $i < $max; $i++) { - xcache_clear_cache(XC_TYPE_VAR, $i); - } - //恢复之前的权限 - $_SERVER['PHP_AUTH_USER'] = $tmp['user']; - $_SERVER['PHP_AUTH_PW'] = $tmp['pwd']; - return true; - } - - /* - * (non-PHPdoc) - * @see AbstractWindCache::setConfig() - */ - public function setConfig($config = array()) { - if (!$config) return false; - parent::setConfig($config); - $this->authUser = $this->getConfig('user'); - $this->authPwd = $this->getConfig('pwd'); - } - -} \ No newline at end of file diff --git a/wind/component/cache/strategy/WindZendCache.php b/wind/component/cache/strategy/WindZendCache.php deleted file mode 100644 index dd36c252..00000000 --- a/wind/component/cache/strategy/WindZendCache.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-26 xiaoxiao - */ -class WindZendCache extends AbstractWindCache { - - public function __construct() { - if (!function_exists('zend_shm_cache_fetch')) { - throw new WindCacheException('The zend cache extension must be loaded !'); - } - } - - /* (non-PHPdoc) - * @see AbstractWindCache::setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return zend_shm_cache_store($key, $value, $expire); - } - - /* (non-PHPdoc) - * @see AbstractWindCache::getValue() - */ - protected function getValue($key) { - return zend_shm_cache_fetch($key); - } - - /* (non-PHPdoc) - * @see AbstractWindCache::deleteValue() - */ - protected function deleteValue($key) { - return zend_shm_cache_delete($key); - } - - /* (non-PHPdoc) - * @see AbstractWindCache::clear() - */ - public function clear() { - return zend_shm_cache_clear(); - } - -} \ No newline at end of file From c0a687bde38e5fa94a3c1b8b67166dfa2d1089bc Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 08:04:07 +0000 Subject: [PATCH 0428/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2500 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/http/cookie/WindCookie.php | 94 --- .../http/cookie/WindCookieObject.php | 185 ----- wind/component/http/request/IWindRequest.php | 25 - .../http/request/WindHttpRequest.php | 669 ------------------ .../component/http/response/IWindResponse.php | 11 - .../http/response/WindHttpResponse.php | 568 --------------- .../http/session/AbstractWindUserSession.php | 57 -- wind/component/http/session/WindDbSession.php | 42 -- wind/component/http/session/WindSession.php | 370 ---------- .../http/transfer/AbstractWindHttp.php | 280 -------- wind/component/http/transfer/WindHttpCurl.php | 147 ---- .../http/transfer/WindHttpSocket.php | 166 ----- .../http/transfer/WindHttpStream.php | 178 ----- 13 files changed, 2792 deletions(-) delete mode 100644 wind/component/http/cookie/WindCookie.php delete mode 100644 wind/component/http/cookie/WindCookieObject.php delete mode 100644 wind/component/http/request/IWindRequest.php delete mode 100644 wind/component/http/request/WindHttpRequest.php delete mode 100644 wind/component/http/response/IWindResponse.php delete mode 100644 wind/component/http/response/WindHttpResponse.php delete mode 100644 wind/component/http/session/AbstractWindUserSession.php delete mode 100644 wind/component/http/session/WindDbSession.php delete mode 100644 wind/component/http/session/WindSession.php delete mode 100644 wind/component/http/transfer/AbstractWindHttp.php delete mode 100644 wind/component/http/transfer/WindHttpCurl.php delete mode 100644 wind/component/http/transfer/WindHttpSocket.php delete mode 100644 wind/component/http/transfer/WindHttpStream.php diff --git a/wind/component/http/cookie/WindCookie.php b/wind/component/http/cookie/WindCookie.php deleted file mode 100644 index 7a32ef33..00000000 --- a/wind/component/http/cookie/WindCookie.php +++ /dev/null @@ -1,94 +0,0 @@ - 2010-12-17 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * cookie设置操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindCookie{ - - /** - * 设置cookie - * @param string $name cookie名称 - * @param string $value cookie值 - * @param string|int $expires 过期时间 - * @param string $path cookie路径 - * @param strint $domain cookie cookie域 - * @param boolean $encode 使用 MIME base64 对数据进行编码 - * @param boolean $serialize 是否序列化 - * @param string $prefix cookie前缀 - * @param boolean $secure 是否安全连接 - * @param boolean $httponly 是否可以访问脚本设置的cookie - * @return string|string - */ - public static function set($name, $value=null, $expires = null,$encode = false,$serialize = false,$prefix=null ,$path = null,$domain =null,$secure = false,$httponly=false){ - if(empty($name)){ - return false; - } - $name = $prefix ? $prefix.$name : $name; - $value = $serialize ? serialize($value) : $value; - $value = $encode ? base64_encode($value) : $value; - $path = $path ? $path : '/'; - $expires = is_int($expires) ? time()+$expires : strtotime($expires); - setcookie($name,$value,$expires,$path,$domain,$secure,$httponly); - return true; - } - - - /** - * 删除cookie - * @param string $name cookie名称 - * @param string $prefix cookie前缀 - * @return boolean - */ - public static function remove($name,$prefix=null){ - $name = $prefix ? $prefix.$name : $name; - if(self::exist($name)){ - self::set($name,'',time()-3600); - unset($_COOKIE[$name]); - } - return true; - } - - /** - * 取得指定名称的cookie - * @param string $name cookie名称 - * @param boolean $encode 是否对cookie值进行过转码 - * @param boolean $encode 是否对cookie值进行过序列化 - * @param string $prefix cookie前缀 - * @return string|boolean - */ - public static function get($name,$encode = false,$serialize = false,$prefix=null){ - $name = $prefix ? $prefix.$name : $name; - if(self::exist($name)){ - $value = get_magic_quotes_gpc() ? stripslashes($_COOKIE[$name]) : $_COOKIE[$name]; - $value = $encode ? base64_decode($value):$value; - return $serialize ? unserialize($value) : $value; - } - return false; - } - - /** - *移除全部cookie - */ - public static function removeAll(){ - $_COOKIE = array(); - } - - /** - * 判断cookie是否存在 - * @param string $name cookie名称 - * @param string $prefix cookie前缀 - */ - public static function exist($name,$prefix=null){ - return isset($_COOKIE[$prefix ? $prefix.$name : $name]); - } -} \ No newline at end of file diff --git a/wind/component/http/cookie/WindCookieObject.php b/wind/component/http/cookie/WindCookieObject.php deleted file mode 100644 index 3b774ff1..00000000 --- a/wind/component/http/cookie/WindCookieObject.php +++ /dev/null @@ -1,185 +0,0 @@ - 2010-12-17 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * 将cookie作为对象操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindCookieObject{ - - /** - * @var string cookie前缀 - */ - public $prefix; - /** - * Cookie 名称 - * - * @var string - */ - protected $name; - - /** - * Cookie 值 - * - * @var string - */ - protected $value; - - /** - * Cookie 过期时间 - * - * @var int - */ - protected $expires; - - /** - * Cookie 域 - * - * @var string - */ - protected $domain; - - /** - * Cookie 路径 - * - * @var string - */ - protected $path; - - /** - * 是否安全套接字 - * - * @var boolean - */ - protected $secure; - /** - * 是否启用编码 - * - * @var boolean - */ - protected $encode; - - /** - * @var string httponly - */ - protected $httponly; - - /** - * @param string $name - * @param string $value - * @param string $domain - * @param int $expires - * @param string $path - * @param bool $secure - * @param bool $httponly - * @param int $prefix - * @param bool $encode - */ - public function __construct($name, $value=null, $expires = null, $path = null,$domain =null, $secure = false,$httponly=false,$prefix=null,$encode = false){ - - $this->name = (string) $name; - $this->value = (string) $value; - $this->domain = (string) $domain; - $this->expires = (null === $expires ? null : (int) $expires); - $this->path = ($path ? $path : '/'); - $this->secure = $secure; - $this->httponly = $httponly; - $this->prefix = (string)$prefix; - $this->encode = $encode; - } - /** - * 获取cookie的名称 - * @return string - */ - public function getName(){ - return $this->prefix ? $this->prefix.$this->name : $this->prefix; - } - /** - *获取cookie值 - * @return string - */ - public function getValue(){ - return $this->value; - } - - /** - * 获取cookie的域 - * @return string - */ - public function getDomain(){ - return $this->domain; - } - /** - * 获取cookie的路径 - * @return string - */ - public function getPath(){ - return $this->path; - } - /** - *获取cookie的过期时间 - * @return int|null - */ - public function getExpirs(){ - return $this->expires; - } - /** - *是否是安全套接字 - * @return boolean - */ - public function isSecure(){ - return $this->secure; - } - /** - * 验证cookie是否过期 - * @param int|null $now 比较时间 - * @return boolean - */ - public function isExpired($now = null){ - return (is_int($this->expires) && $this->expires < ($now ? $now : time())) ? true : false; - } - - /** - *是否是session cookie - * @return boolean - */ - public function isSessionCookie(){ - return null === $this->expires; - } - - /** - * @return string - */ - public function __toString(){ - return $this->name . '='. ($this->encode ? urlencode($this->value) : $this->value) .';'; - } - - public static function getCookieFromString($cookiestr,$prefix = null,$encode = false){ - $cookie = explode(';',$cookiestr); - list($name,$value) = explode('=',array_shift($cookie)); - if(empty($name)){ - return null; - } - $domain=$expires =$path = null; - $httponly = $secure = false; - foreach($cookie as $_cookie){ - list($key,$_value) = explode('=',$_cookie); - switch($key){ - case 'domain':$domain=$_value;break; - case 'path':$path=$_value;break; - case 'expires':$expires = is_int($_value) ? $_value : strtotime($_value);break; - case 'httponly':$httponly=(bool)$_value;break; - case 'secure':$secure=(bool)$_value;break; - } - } - return new self($name,$value,$expires,$path,$domain,$secure,$httponly,$prefix,$encode); - } -} \ No newline at end of file diff --git a/wind/component/http/request/IWindRequest.php b/wind/component/http/request/IWindRequest.php deleted file mode 100644 index aa657cbf..00000000 --- a/wind/component/http/request/IWindRequest.php +++ /dev/null @@ -1,25 +0,0 @@ - 2010-11-3 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * 处理请求抽象基类 - * 如http请求 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindRequest { - const INPUT_TYPE_GET = 'get'; - const INPUT_TYPE_POST = 'post'; - const INPUT_TYPE_COOKIE = 'cookie'; -} - - - - diff --git a/wind/component/http/request/WindHttpRequest.php b/wind/component/http/request/WindHttpRequest.php deleted file mode 100644 index 29608259..00000000 --- a/wind/component/http/request/WindHttpRequest.php +++ /dev/null @@ -1,669 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHttpRequest implements IWindRequest { - /** - * 访问的端口号 - * @var int - */ - private $_port = null; - /** - * 客户端IP - * @var string - */ - private $_clientIp = null; - /** - * 语言信息 - * @var string - */ - private $_language = null; - /** - * 路径信息 - * @var string - */ - private $_pathInfo = null; - /** - * @var string - */ - private $_scriptUrl = null; - /** - * @var string - */ - private $_requestUri = null; - /** - * 基础路径信息 - * @var string - */ - private $_baseUrl = null; - private $_hostInfo = null; - /** - * 请求参数信息 - * @var array - */ - private $_attribute = array(); - /** - * @var WindHttpResponse - */ - private $_response = null; - - public function __construct() { - $this->normalizeRequest(); - } - - protected function normalizeRequest() { - if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { - if (isset($_GET)) - $_GET = $this->stripSlashes($_GET); - if (isset($_POST)) - $_POST = $this->stripSlashes($_POST); - if (isset($_REQUEST)) - $_REQUEST = $this->stripSlashes($_REQUEST); - if (isset($_COOKIE)) - $_COOKIE = $this->stripSlashes($_COOKIE); - } - } - - public function stripSlashes(&$data) { - return is_array($data) ? array_map(array($this, 'stripSlashes'), $data) : stripslashes( - $data); - } - - /** - * 设置属性数据 - * - * @param string|array|object $data - * @param string $key - * @return - */ - public function setAttribute($data, $key = '') { - if ($key) { - $this->_attribute[$key] = $data; - return; - } - if (is_object($data)) - $data = get_object_vars($data); - if (is_array($data)) - $this->_attribute = array_merge($this->_attribute, $data); - } - - /** - * 根据名称获得服务器和执行环境信息 - * - * @param string|null $name - * @return string|object|array| - */ - public function getAttribute($key, $defaultValue = '') { - if (isset($this->_attribute[$key])) - return $this->_attribute[$key]; - else if (isset($_GET[$key])) - return $_GET[$key]; - else if (isset($_POST[$key])) - return $_POST[$key]; - else if (isset($_COOKIE[$key])) - return $_COOKIE[$key]; - else if (isset($_REQUEST[$key])) - return $_REQUEST[$key]; - else if (isset($_ENV[$key])) - return $_ENV[$key]; - else if (isset($_SERVER[$key])) - return $_SERVER[$key]; - else - return $defaultValue; - } - - /** - * 返回$_GET,$_POST的值,未设置则返回default - * @param string $name | attribute name - */ - public function getRequest($key = null, $defaultValue = null) { - if (!$key) - return array_merge($_POST, $_GET); - if (isset($_GET[$key])) - return $_GET[$key]; - if (isset($_POST[$key])) - return $_POST[$key]; - return $defaultValue; - } - - /** - * 从query中取值 - * - * @param string $name - * @param string $default - * @return string|null - */ - public function getQuery($name = null, $defaultValue = null) { - return $this->getGet($name, $defaultValue); - } - - /** - * 获得post值 - * - * @param string $name - * @param string $defaultValue - * @return string|null - */ - public function getPost($name = null, $defaultValue = null) { - if ($name == null) - return $_POST; - return isset($_POST[$name]) ? $_POST[$name] : $defaultValue; - } - - /** - * 获得get值 - * - * @param string $name - * @param string $defaultValue - * @return string|null - */ - public function getGet($name = '', $defaultValue = null) { - if ($name == null) - return $_GET; - return (isset($_GET[$name])) ? $_GET[$name] : $defaultValue; - } - - /** - * 返回cookie的值,如果$name=null则返回所有Cookie值 - * - * @param string $key - * @param string $defaultValue - * @return string|null|array - */ - public function getCookie($name = null, $defaultValue = null) { - if ($name == null) - return $_COOKIE; - return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : $defaultValue; - } - - /** - * 返回session的值,如果$name=null则返回所有Cookie值 - * - * @param string $key - * @param string $defaultValue - * @return string|null|array - */ - public function getSession($name = null, $defaultValue = null) { - if ($name == null) - return $_SESSION; - return (isset($_SESSION[$name])) ? $_SESSION[$name] : $defaultValue; - } - - /** - * 返回Server的值,如果$name为空则返回所有Server的值 - * - * @param string $name - * @param string $defaultValue - * @return string|null|array - */ - public function getServer($name = null, $defaultValue = null) { - if ($name == null) - return $_SERVER; - return (isset($_SERVER[$name])) ? $_SERVER[$name] : $defaultValue; - } - - /** - * 返回env中的值,如果$name为null则返回所有env的值 - * - * @param string|null $name - * @param string $defaultValue - * @return string|null|array - */ - public function getEnv($name = null, $defaultValue = null) { - if ($name == null) - return $_ENV; - return (isset($_ENV[$name])) ? $_ENV[$name] : $defaultValue; - } - - /** - * 获取协议名称 - * - * @return string - */ - public function getScheme() { - return ($this->getServer('HTTPS') == 'on') ? 'https' : 'http'; - } - - /** - * 返回请求页面时通信协议的名称和版本 - * @return string - */ - public function getProtocol() { - return $this->getServer('SERVER_PROTOCOL', 'HTTP/1.0'); - } - - /** - * 返回访问IP - * - * @return string|0.0.0.0 - */ - public function getClientIp() { - if (!$this->_clientIp) - $this->_getClientIp(); - return $this->_clientIp; - } - - /** - * 获得请求的方法 - */ - public function getRequestMethod() { - return strtoupper($this->getServer('REQUEST_METHOD')); - } - - /** - * 获得请求类型 - * - * @return string - */ - public function getRequestType() { - return IWindRequest::REQUEST_TYPE_WEB; - } - - /** - * 返回该请求是否为ajax请求 - * @return Boolean - */ - public function getIsAjaxRequest() { - return !strcasecmp($this->getServer('HTTP_X_REQUESTED_WITH'), 'XMLHttpRequest'); - } - - /** - * Returns a boolean indicating whether this request was made using a - * secure channel, such as HTTPS. - * @return Boolean - */ - public function isSecure() { - return !strcasecmp($this->getServer('HTTPS'), 'on'); - } - - /** - * 返回请求是否为GET请求类型 - * @return boolean - */ - public function isGet() { - return !strcasecmp($this->getRequestMethod(), 'GET'); - } - - /** - * 返回请求是否为POST请求类型 - * @return boolean - */ - public function isPost() { - return !strcasecmp($this->getRequestMethod(), 'POST'); - } - - /** - * 返回请求是否为PUT请求类型 - * @return boolean - */ - public function isPut() { - return !strcasecmp($this->getRequestMethod(), 'PUT'); - } - - /** - * 返回请求是否为DELETE请求类型 - * @return boolean - */ - public function isDelete() { - return !strcasecmp($this->getRequestMethod(), 'Delete'); - } - - /** - * 初始化请求的资源标识符 - * 这里的uri是去除协议名、主机名的 - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_requestUri = /example/index.php?a=test - * - * @return string - */ - public function getRequestUri() { - if (!$this->_requestUri) - $this->_initRequestUri(); - return $this->_requestUri; - } - - /** - * 返回当前执行脚本的绝对路径 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_scriptUrl = /example/index.php - * - * @throws WindException - * @return string - */ - public function getScriptUrl() { - if (!$this->_scriptUrl) - $this->_initScriptUrl(); - return $this->_scriptUrl; - } - - /** - * 返回执行脚本 - */ - public function getScript() { - if (($pos = strrpos($this->getScriptUrl(), '/')) === false) - $pos = -1; - return substr($this->getScriptUrl(), $pos + 1); - } - - /** - * 获取Http头信息 - * @param string $header 头部名称 - * @return string|null - */ - public function getHeader($header, $default = null) { - $temp = strtoupper(str_replace('-', '_', $header)); - if (substr($temp, 0, 5) != 'HTTP_') - $temp = 'HTTP_' . $temp; - if (($header = $this->getServer($temp)) != null) - return $header; - if (function_exists('apache_request_headers')) { - $headers = apache_request_headers(); - if ($headers[$header]) - return $headers[$header]; - } - return $default; - } - - /** - * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 - * - * @throws WindException - * @return string - */ - public function getPathInfo() { - if (!$this->_pathInfo) - $this->_initPathInfo(); - return $this->_pathInfo; - } - - /** - * 获取基础URL,这里是去除了脚本文件以及访问参数信息的URL地址信息 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_baseUrl = example - * return absolute url address when absolute is true - * 'example' will be return when absolute is false - * 'http://www.phpwind.net/example' will be return when absolute is true - * 'http://www.phpwind.net:80/example' will be return when absolute is true - * 'http://www.phpwind.net:443/example' will be return when absolute is true - * - * @param boolean $absolute - * @return string - */ - public function getBaseUrl($absolute = false) { - if ($this->_baseUrl === null) - $this->_baseUrl = rtrim(dirname($this->getScriptUrl()), '\\/.'); - return $absolute ? $this->getHostInfo() . $this->_baseUrl : $this->_baseUrl; - } - - /** - * 获得主机信息,包含协议信息,主机名,访问端口信息 - * - * @return string - */ - public function getHostInfo() { - if ($this->_hostInfo === null) - $this->_initHostInfo(); - return $this->_hostInfo; - } - - /** - * 返回当前运行脚本所在的服务器的主机名。 - * 如果脚本运行于虚拟主机中 - * 该名称是由那个虚拟主机所设置的值决定 - * - * @return string|'' - */ - public function getServerName() { - return $this->getServer('SERVER_NAME', ''); - } - - /** - * 返回服务端口号 - * https链接的默认端口号为443 - * http链接的默认端口号为80 - * - * @return int - */ - public function getServerPort() { - if (!$this->_port) { - $_default = $this->isSecure() ? 443 : 80; - $this->setServerPort($this->getServer('SERVER_PORT', $_default)); - } - return $this->_port; - } - - /** - * 设置服务端口号 - * https链接的默认端口号为443 - * http链接的默认端口号为80 - * - * @param int $port - */ - public function setServerPort($port) { - $this->_port = (int) $port; - } - - /** - * 返回浏览当前页面的用户的主机名 - * DNS 反向解析不依赖于用户的 REMOTE_ADDR - * - * @return string|null - */ - public function getRemoteHost() { - return $this->getServer('REMOTE_HOST'); - } - - /** - * 返回浏览器发送Referer请求头,可以让服务器了解和追踪发出本次请求的起源URL地址 - * - * @return string|null - */ - public function getUrlReferer() { - return $this->getServer('HTTP_REFERER'); - } - - /** - * 获得用户机器上连接到 Web 服务器所使用的端口号 - * - * @return number|null - */ - public function getRemotePort() { - return $this->getServer('REMOTE_PORT'); - } - - /** - * 返回User-Agent头字段用于指定浏览器或者其他客户端程序的类型和名字 - * 如果客户机是一种无线手持终端,就返回一个WML文件;如果发现客户端是一种普通浏览器, - * 则返回通常的HTML文件 - * - * @return string - */ - public function getUserAgent() { - return $this->getServer('HTTP_USER_AGENT', ''); - } - - /** - * 返回当前请求头中 Accept: 项的内容, - * Accept头字段用于指出客户端程序能够处理的MIME类型,例如 text/html,image/* - * - * @return string|'' - */ - public function getAcceptTypes() { - return $this->getServer('HTTP_ACCEPT', ''); - } - - /** - * 返回客户端程序可以能够进行解码的数据编码方式,这里的编码方式通常指某种压缩方式 - * - * @return string|'' - */ - public function getAcceptCharset() { - return $this->getServer('HTTP_ACCEPT_ENCODING', ''); - } - - /** - * 返回客户端程序期望服务器返回哪个国家的语言文档 - * Accept-Language: en-us,zh-cn - * - * @return string - */ - public function getAcceptLanguage() { - if (!$this->_language) { - $_language = explode(',', $this->getServer('HTTP_ACCEPT_LANGUAGE', '')); - $this->_language = $_language[0] ? $_language[0] : 'zh-cn'; - } - return $this->_language; - } - - /** - * @return WindHttpResponse - */ - public function getResponse($charset) { - $response = new WindHttpResponse(); - !$charset && $charset = 'utf-8'; - $response->setHeader('Content-type', 'text/html;charset=' . $charset); - $response->setCharset($charset); - return $response; - } - - /** - * 返回访问的IP地址 - * - * Example: - * $this->_clientIp = 127.0.0.1 - * - * @return string - */ - private function _getClientIp() { - if (($ip = $this->getServer('HTTP_CLIENT_IP')) != null) { - $this->_clientIp = $ip; - } elseif (($_ip = $this->getServer('HTTP_X_FORWARDED_FOR')) != null) { - $ip = strtok($_ip, ','); - do { - $ip = ip2long($ip); - if (!(($ip == 0) || ($ip == 0xFFFFFFFF) || ($ip == 0x7F000001) || (($ip >= 0x0A000000) && ($ip <= 0x0AFFFFFF)) || (($ip >= 0xC0A8FFFF) && ($ip <= 0xC0A80000)) || (($ip >= 0xAC1FFFFF) && ($ip <= 0xAC100000)))) { - $this->_clientIp = long2ip($ip); - return; - } - } while (($ip = strtok(','))); - } elseif (($ip = $this->getServer('HTTP_PROXY_USER')) != null) { - $this->_clientIp = $ip; - } elseif (($ip = $this->getServer('REMOTE_ADDR')) != null) { - $this->_clientIp = $ip; - } else { - $this->_clientIp = "0.0.0.0"; - } - } - - /** - * 初始化请求的资源标识符 - * 这里的uri是去除协议名、主机名的 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_requestUri = /example/index.php?a=test - * - * @throws WindException - */ - private function _initRequestUri() { - if (($requestUri = $this->getServer('HTTP_X_REWRITE_URL')) != null) { - $this->_requestUri = $requestUri; - } elseif (($requestUri = $this->getServer('REQUEST_URI')) != null) { - $this->_requestUri = $requestUri; - if (strpos($this->_requestUri, $this->getServer('HTTP_HOST')) !== false) - $this->_requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $this->_requestUri); - } elseif (($requestUri = $this->getServer('ORIG_PATH_INFO')) != null) { - $this->_requestUri = $requestUri; - if (($query = $this->getServer('QUERY_STRING')) != null) - $this->_requestUri .= '?' . $query; - } else - throw new WindException(__CLASS__ . ' is unable to determine the request URI.'); - } - - /** - * 初始化当前执行脚本的绝对路径 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_scriptUrl = /example/index.php - * - * @throws WindException - * @return - */ - private function _initScriptUrl() { - if (($scriptName = $this->getServer('SCRIPT_FILENAME')) == null) - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!!'); - $scriptName = basename($scriptName); - if (($_scriptName = $this->getServer('SCRIPT_NAME')) != null && basename($_scriptName) === $scriptName) { - $this->_scriptUrl = $_scriptName; - } elseif (($_scriptName = $this->getServer('PHP_SELF')) != null && basename($_scriptName) === $scriptName) { - $this->_scriptUrl = $_scriptName; - } elseif (($_scriptName = $this->getServer('ORIG_SCRIPT_NAME')) != null && basename( - $_scriptName) === $scriptName) { - $this->_scriptUrl = $_scriptName; - } elseif (($pos = strpos($this->getServer('PHP_SELF'), '/' . $scriptName)) !== false) { - $this->_scriptUrl = substr($this->getServer('SCRIPT_NAME'), 0, $pos) . '/' . $scriptName; - } elseif (($_documentRoot = $this->getServer('DOCUMENT_ROOT')) != null && ($_scriptName = $this->getServer( - 'SCRIPT_FILENAME')) != null && strpos($_scriptName, $_documentRoot) === 0) { - $this->_scriptUrl = str_replace('\\', '/', - str_replace($_documentRoot, '', $_scriptName)); - } else - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); - } - - /** - * 获得主机信息,包含协议信息,主机名,访问端口信息 - * - * Example: - * http://www.phpwind.net/example/index.php?a=test - * $this->_hostInfo = http://www.phpwind.net/ - * $this->_hostInfo = http://www.phpwind.net:80/ - * $this->_hostInfo = https://www.phpwind.net:443/ - * - * @throws WindException - * @return - */ - private function _initHostInfo() { - $http = $this->isSecure() ? 'https' : 'http'; - if (($httpHost = $this->getServer('HTTP_HOST')) != null) - $this->_hostInfo = $http . '://' . $httpHost; - elseif (($httpHost = $this->getServer('SERVER_NAME')) != null) { - $this->_hostInfo = $http . '://' . $httpHost; - if (($port = $this->getServerPort()) != null) - $this->_hostInfo .= ':' . $port; - } else - throw new WindException(__CLASS__ . ' determine the entry script URL failed!!'); - } - - /** - * 返回包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息 - * - * @throws WindException - * @return - */ - private function _initPathInfo() { - $requestUri = urldecode($this->getRequestUri()); - $scriptUrl = $this->getScriptUrl(); - $baseUrl = $this->getBaseUrl(); - if (strpos($requestUri, $scriptUrl) === 0) - $pathInfo = substr($requestUri, strlen($scriptUrl)); - elseif ($baseUrl === '' || strpos($requestUri, $baseUrl) === 0) - $pathInfo = substr($requestUri, strlen($baseUrl)); - elseif (strpos($_SERVER['PHP_SELF'], $scriptUrl) === 0) - $pathInfo = substr($_SERVER['PHP_SELF'], strlen($scriptUrl)); - else - throw new WindException(__CLASS__ . ' determine the entry path info failed!!'); - if (($pos = strpos($pathInfo, '?')) !== false) - $pathInfo = substr($pathInfo, $pos + 1); - $this->_pathInfo = trim($pathInfo, '/'); - } -} \ No newline at end of file diff --git a/wind/component/http/response/IWindResponse.php b/wind/component/http/response/IWindResponse.php deleted file mode 100644 index 0c437993..00000000 --- a/wind/component/http/response/IWindResponse.php +++ /dev/null @@ -1,11 +0,0 @@ - 2010-11-7 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -interface IWindResponse { - -} \ No newline at end of file diff --git a/wind/component/http/response/WindHttpResponse.php b/wind/component/http/response/WindHttpResponse.php deleted file mode 100644 index a7016946..00000000 --- a/wind/component/http/response/WindHttpResponse.php +++ /dev/null @@ -1,568 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHttpResponse implements IWindResponse { - - private $_body = array(); - - private $_bodyIndex = array(); - - private $_charset = 'utf-8'; - - private $_headers = array(); - - private $_isRedirect = false; - - private $_status = ''; - - private $_data = array('G' => array()); - - /* - * Server status codes; see RFC 2068. - * Status code (100) indicating the client can continue. - */ - const W_CONTINUE = 100; - - /** - * Status code (101) indicating the server is switching protocols - * according to Upgrade header. - */ - const W_SWITCHING_PROTOCOLS = 101; - - /** - * Status code (200) indicating the request succeeded normally. - */ - const W_OK = 200; - - /** - * Status code (201) indicating the request succeeded and created - * a new resource on the server. - */ - const W_CREATED = 201; - - /** - * Status code (202) indicating that a request was accepted for - * processing, but was not completed. - */ - const W_ACCEPTED = 202; - - /** - * Status code (203) indicating that the meta information presented - * by the client did not originate from the server. - */ - const W_NON_AUTHORITATIVE_INFORMATION = 203; - - /** - * Status code (204) indicating that the request succeeded but that - * there was no new information to return. - */ - const W_NO_CONTENT = 204; - - /** - * Status code (205) indicating that the agent SHOULD reset - * the document view which caused the request to be sent. - */ - const W_RESET_CONTENT = 205; - - /** - * Status code (206) indicating that the server has fulfilled - * the partial GET request for the resource. - */ - const W_PARTIAL_CONTENT = 206; - - /** - * Status code (300) indicating that the requested resource - * corresponds to any one of a set of representations, each with - * its own specific location. - */ - const W_MULTIPLE_CHOICES = 300; - - /** - * Status code (301) indicating that the resource has permanently - * moved to a new location, and that future references should use a - * new URI with their requests. - */ - const W_MOVED_PERMANENTLY = 301; - - /** - * Status code (302) indicating that the resource has temporarily - * moved to another location, but that future references should - * still use the original URI to access the resource. - * - * This definition is being retained for backwards compatibility. - * W_FOUND is now the preferred definition. - */ - const W_MOVED_TEMPORARILY = 302; - - /** - * Status code (302) indicating that the resource reside - * temporarily under a different URI. Since the redirection might - * be altered on occasion, the client should continue to use the - * Request-URI for future requests.(HTTP/1.1) To represent the - * status code (302), it is recommended to use this variable. - */ - const W_FOUND = 302; - - /** - * Status code (303) indicating that the response to the request - * can be found under a different URI. - */ - const W_SEE_OTHER = 303; - - /** - * Status code (304) indicating that a conditional GET operation - * found that the resource was available and not modified. - */ - const W_NOT_MODIFIED = 304; - - /** - * Status code (305) indicating that the requested resource - * MUST be accessed through the proxy given by the - * Location field. - */ - const W_USE_PROXY = 305; - - /** - * Status code (307) indicating that the requested resource - * resides temporarily under a different URI. The temporary URI - * SHOULD be given by the Location - * field in the response. - */ - const W_TEMPORARY_REDIRECT = 307; - - /** - * Status code (400) indicating the request sent by the client was - * syntactically incorrect. - */ - const W_BAD_REQUEST = 400; - - /** - * Status code (401) indicating that the request requires HTTP - * authentication. - */ - const W_UNAUTHORIZED = 401; - - /** - * Status code (402) reserved for future use. - */ - const W_PAYMENT_REQUIRED = 402; - - /** - * Status code (403) indicating the server understood the request - * but refused to fulfill it. - */ - const W_FORBIDDEN = 403; - - /** - * Status code (404) indicating that the requested resource is not - * available. - */ - const W_NOT_FOUND = 404; - - /** - * Status code (405) indicating that the method specified in the - * Request-Line is not allowed for the resource - * identified by the Request-URI. - */ - const W_METHOD_NOT_ALLOWED = 405; - - /** - * Status code (406) indicating that the resource identified by the - * request is only capable of generating response entities which have - * content characteristics not acceptable according to the accept - * headers sent in the request. - */ - const W_NOT_ACCEPTABLE = 406; - - /** - * Status code (407) indicating that the client MUST first - * authenticate itself with the proxy. - */ - const W_PROXY_AUTHENTICATION_REQUIRED = 407; - - /** - * Status code (408) indicating that the client did not produce a - * request within the time that the server was prepared to wait. - */ - const W_REQUEST_TIMEOUT = 408; - - /** - * Status code (409) indicating that the request could not be - * completed due to a conflict with the current state of the - * resource. - */ - const W_CONFLICT = 409; - - /** - * Status code (410) indicating that the resource is no longer - * available at the server and no forwarding address is known. - * This condition SHOULD be considered permanent. - */ - const W_GONE = 410; - - /** - * Status code (411) indicating that the request cannot be handled - * without a defined Content-Length. - */ - const W_LENGTH_REQUIRED = 411; - - /** - * Status code (412) indicating that the precondition given in one - * or more of the request-header fields evaluated to false when it - * was tested on the server. - */ - const W_PRECONDITION_FAILED = 412; - - /** - * Status code (413) indicating that the server is refusing to process - * the request because the request entity is larger than the server is - * willing or able to process. - */ - const W_REQUEST_ENTITY_TOO_LARGE = 413; - - /** - * Status code (414) indicating that the server is refusing to service - * the request because the Request-URI is longer - * than the server is willing to interpret. - */ - const W_REQUEST_URI_TOO_LONG = 414; - - /** - * Status code (415) indicating that the server is refusing to service - * the request because the entity of the request is in a format not - * supported by the requested resource for the requested method. - */ - const W_UNSUPPORTED_MEDIA_TYPE = 415; - - /** - * Status code (416) indicating that the server cannot serve the - * requested byte range. - */ - const W_REQUESTED_RANGE_NOT_SATISFIABLE = 416; - - /** - * Status code (417) indicating that the server could not meet the - * expectation given in the Expect request header. - */ - const W_EXPECTATION_FAILED = 417; - - /** - * Status code (500) indicating an error inside the HTTP server - * which prevented it from fulfilling the request. - */ - const W_INTERNAL_SERVER_ERROR = 500; - - /** - * Status code (501) indicating the HTTP server does not support - * the functionality needed to fulfill the request. - */ - const W_NOT_IMPLEMENTED = 501; - - /** - * Status code (502) indicating that the HTTP server received an - * invalid response from a server it consulted when acting as a - * proxy or gateway. - */ - const W_BAD_GATEWAY = 502; - - /** - * Status code (503) indicating that the HTTP server is - * temporarily overloaded, and unable to handle the request. - */ - const W_SERVICE_UNAVAILABLE = 503; - - /** - * Status code (504) indicating that the server did not receive - * a timely response from the upstream server while acting as - * a gateway or proxy. - */ - const W_GATEWAY_TIMEOUT = 504; - - /** - * Status code (505) indicating that the server does not support - * or refuses to support the HTTP protocol version that was used - * in the request message. - */ - const W_HTTP_VERSION_NOT_SUPPORTED = 505; - - public function codeMap($code) { - $map = array(505 => 'http version not supported', 504 => 'gateway timeout', - 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', - 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', - 416 => 'requested range not satisfiable', 415 => 'unsupported media type', - 414 => 'request uri too long', 413 => 'request entity too large', - 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', - 408 => 'request timeout', 407 => 'proxy authentication required', - 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', - 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', - 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', - 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', - 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', - 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', - 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', - 206 => 'partial content'); - return isset($map[$code]) ? $map[$code] : ''; - } - - /** - * 设置响应头信息,如果已经设置过同名的响应头,该方法将用新的设置取代原来的头字段 - * - * @param string $name 响应头的名称 - * @param string $value 响应头的字段取值 - */ - public function setHeader($name, $value, $replace = false) { - if (!$name || !$value) - return; - $name = $this->_normalizeHeader($name); - $setted = false; - foreach ($this->_headers as $key => $one) { - if ($one['name'] == $name) { - $this->_headers[$key] = array('name' => $name, 'value' => $value, - 'replace' => $replace); - $setted = true; - break; - } - } - if ($setted === false) - $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); - } - - /** - * 设置响应头信息,如果已经设置过同名的响应头,该方法将增加一个同名的响应头 - * - * @param string $name 响应头的名称 - * @param string $value 响应头的字段取值 - */ - public function addHeader($name, $value, $replace = false) { - if ($name == '' || $value == '') - return; - $name = $this->_normalizeHeader($name); - $this->_headers[] = array('name' => $name, 'value' => $value, 'replace' => $replace); - } - - /** - * @return string - */ - public function getCharset() { - return $this->_charset; - } - - /** - * @param string $_charset - */ - public function setCharset($_charset) { - $this->_charset = $_charset; - } - - /** - * 设置响应头状态码 - * - * @param int $status - * @param string $message - */ - public function setStatus($status, $message = '') { - $status = intval($status); - if ($status < 100 || $status > 505) - return; - - $this->_status = (int) $status; - } - - /** - * 设置响应内容 - * - * @param string $content - * @param string $name - */ - public function setBody($content, $name = null) { - if (!$content) - return; - !$name && $name = 'default'; - array_push($this->_bodyIndex, $name); - $this->_body[$name] = $content; - } - - /** - * 添加cookie信息 - * - * @param Cookie $cookie - */ - public function addCookie(Cookie $cookie) { - - } - - /** - * 发送一个错误的响应信息 - * - * @param int $status - * @param string $message - */ - public function sendError($status = self::W_NOT_FOUND, $message = '') { - if (!is_int($status) || $status < 400 || $status > 505) - return; - $this->setBody($message, 'error'); - $this->setStatus($status); - $this->sendResponse(); - } - - /** - * 重定向一个响应信息 - * - * @param string $location - */ - public function sendRedirect($location, $status = 302) { - if (!is_int($status) || $status < 300 || $status > 399) - return; - - $this->addHeader('Location', $location, true); - $this->setStatus($status); - $this->_isRedirect = true; - $this->sendHeaders(); - exit(); - } - - /** - * 发送响应信息 - */ - public function sendResponse() { - $this->sendHeaders(); - $this->sendBody(); - } - - /** - * 发送响应头部信息 - */ - public function sendHeaders() { - if ($this->isSendedHeader()) - return; - foreach ($this->_headers as $header) { - header($header['name'] . ': ' . $header['value'], $header['replace']); - } - if ($this->_status) { - header('HTTP/1.x ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); - header('Status: ' . $this->_status . ' ' . ucwords($this->codeMap($this->_status))); - } - } - - /** - * 发送响应内容 - */ - public function sendBody() { - /*if ($this->_isAjax) echo "_bodyIndex as $key) - echo $this->_body[$key]; - /*if ($this->_isAjax) echo "]]>";*/ - } - - /** - * 获取内容 - * - * @param string $spec 内容的名称 - * @return string|null - */ - public function getBody($name = false) { - if ($name === false) { - ob_start(); - $this->sendBody(); - return ob_get_clean(); - } elseif ($name === true) { - return $this->_body; - } elseif (is_string($name) && isset($this->_body[$name])) - return $this->_body[$name]; - - return null; - } - - /** - * 是否已经发送了响应头部 - */ - public function isSendedHeader($throw = false) { - $sended = headers_sent($file, $line); - if ($throw && $sended) - throw new WindException( - __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); - - return $sended; - } - - /** - * 获取响应头信息 - * - * @return array - */ - public function getHeaders() { - return $this->_headers; - } - - /** - * 清理响应体信息 - */ - public function clearBody() { - $this->_body = array(); - } - - /** - * 清除响应头信息 - */ - public function clearHeaders() { - $this->_headers = array(); - } - - /** - * 格式化响应头信息 - * - * @param string $name - * @return string - */ - private function _normalizeHeader($name) { - $filtered = str_replace(array('-', '_'), ' ', (string) $name); - $filtered = ucwords(strtolower($filtered)); - $filtered = str_replace(' ', '-', $filtered); - return $filtered; - } - - /** - * @return array - */ - public function getData($key1 = '', $key2 = '') { - if (!$key1) - return $this->_data; - if (!$key2) - return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; - return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; - } - - /** - * @param $data - */ - public function setData($data, $key = '', $isG = false) { - if ($key) { - if ($isG) - $this->_data['G'][$key] = $data; - else - $this->_data[$key] = $data; - return; - } - if (is_object($data)) - $data = get_object_vars($data); - if (is_array($data)) { - if ($isG) - $this->_data['G'] += $data; - else - $this->_data += $data; - - } - } - -} \ No newline at end of file diff --git a/wind/component/http/session/AbstractWindUserSession.php b/wind/component/http/session/AbstractWindUserSession.php deleted file mode 100644 index a3da2a70..00000000 --- a/wind/component/http/session/AbstractWindUserSession.php +++ /dev/null @@ -1,57 +0,0 @@ - 2010-12-17 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * 用户定义session存储机制 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -abstract class AbstractWindUserSession { - - /** - * 打开会话存储机制 - * @param string $savePath - * @param string $sessionName - * @return bollean - */ - public static abstract function open($savePath, $sessionName); - /** - * 关闭会话存储存储机制 - * @return bollean - */ - public static abstract function close(); - /** - * 将sessionID对应的数据写到存储 - * @param string $name - * @param mixed $value - */ - public static abstract function write($name,$value); - /** - * 从存储中装载session数据 - * @param mixed $sessid - */ - public static abstract function read($name); - /** - * 对存储系统中的数据进行垃圾收集 - * @param mixed $maxlifetime - */ - public static abstract function gc($maxlifetime); - /** - * 破坏与指定的会话ID相关联的数据 - * @param mixed $name - */ - public static abstract function destroy($name); - - public static function callUserSessionHandler(){ - $className = get_class($this); - session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); - } -} - diff --git a/wind/component/http/session/WindDbSession.php b/wind/component/http/session/WindDbSession.php deleted file mode 100644 index 7c1591ae..00000000 --- a/wind/component/http/session/WindDbSession.php +++ /dev/null @@ -1,42 +0,0 @@ - 2011-3-8 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.http.session.AbstractWindUserSession'); -/** - * 数据库会话存储机制,可以实现统一登陆 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindDbSession extends AbstractWindUserSession { - - public static function open($savePath, $sessionName){ - return true; - } - - public static function close(){ - return true; - } - - public static function write($name,$value){ - - } - - public static function read($name){ - - } - - public static function gc($maxlifetime){ - - } - - public static function destroy($name){ - - } -} - diff --git a/wind/component/http/session/WindSession.php b/wind/component/http/session/WindSession.php deleted file mode 100644 index 1a22ebbd..00000000 --- a/wind/component/http/session/WindSession.php +++ /dev/null @@ -1,370 +0,0 @@ - 2010-12-17 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * Session会话操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSession implements IteratorAggregate, ArrayAccess, Countable { - /** - * @var boolean 是否自动启动session - */ - public $autostart = false; - /** - * @var int 没有启用cookie传用sessionid - */ - const COOKIE_MODE_NONE = 1; - /** - * @var int 仅仅启用cookiew传递sessionid - */ - const COOKIE_MODE_ONLY = 2; - /** - * @var int 启用cookie传用sessionid - */ - const COOKIE_MODE_ALLOW = 3; - - /** - * @var string 以files格式将session在服务端的保存 - */ - const SESSION_SAVE_FILES = 'files'; - /** - * @var string 以user(用户自定义)格式将session在服务端的保存 - */ - const SESSION_SAVE_USER = 'user'; - - /** - * @var array $read 只读session - */ - public static $read = array(); - /** - * @var array $write 只写session - */ - public static $write = array(); - - public function __construct($autostart = false) { - $this->autostart = $autostart; - } - - public function start() { - if (!$this->isStart() && !$this->getAutoStart()) { - $this->autostart ? $this->setAutoStart(1) : session_start(); - } - } - - /** - * session是否开启 - * @return boolean - */ - public function isStart() { - return '' !== $this->getSessionId(); - } - - /** - * 写入和结束session - */ - public function close() { - if ($this->isStart()) { - session_write_close(); - } - } - - /** - * 获取session - * @param string $name session名称 - * @return string - */ - public function get($name) { - return isset($_SESSION[$name]) ? $_SESSION[$name] : null; - } - - /** - * 设置一个会话 - * @param string $name session名称 - * @param string $value $name对应的值 - * @return string - */ - public function set($name, $value) { - if (empty($name) && empty($value)) { - return false; - } - $_SESSION[$name] = $value; - return true; - } - - /** - * 删除一个会话 - * @param string $name session名称 - * @return string - */ - public function remove($name) { - if (isset($_SESSION[$name])) { - $sessionValue = $_SESSION[$name]; - unset($_SESSION[$name]); - return $sessionValue; - } - return null; - } - - /** - * 判断一个session是否存在 - * @param string $name session名称 - * @return string - */ - public function exist($name) { - return isset($_SESSION[$name]); - } - - /** - * 销毁当前所有会话 - * @return string - */ - public function destroy() { - if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { - setcookie($name, '', time() - 3600); - } - session_unset(); - session_destroy(); - return true; - } - - /** - * 获取当前会话名称 - * @return string - */ - public function getSessionName() { - return session_name(); - } - /** - * 设置当前会话名称 - * @return string $name - */ - public function setSessionName($name) { - return session_name($name); - } - - /** - * 获取当前会话 id - * @return string - */ - public function getSessionId() { - return session_id(); - } - - /** - * 设置当前会话 id - * @param string $id - * @return string - */ - public function setSessionId($id) { - return session_id($id); - } - - /** - * 如果session在服务端的以files方式保存,获取session在服务器端存储路径 - * @return string - */ - public function getSavePath() { - return session_save_path(); - } - - /** - * 如果session在服务端的以files方式保存,设置session在服务器端存储路径 - * @param string $path - * @return string - */ - public function setSavePath($path) { - if (is_dir($path)) { - session_save_path($path); - return true; - } - return false; - } - - /** - * 获取session在服务端的保存方式 - * @return string - */ - public function getSessionSaveMode() { - return session_module_name(); - } - - /** - * 定义session在服务端的保存方式,files意为把sesion保存到一个临时文件里,如果我们想自定义别的方式保存(比如用数据库),则需要把该项设置为user; - * @param unknown_type $mode - * @return string - */ - public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { - return session_module_name($mode); - } - - /** - * 取得session相关的cookie参数 - * @return array - */ - public function getCookieParams() { - return session_get_cookie_params(); - } - - /** - * 设置session相关的cookie参数 - * @param array $cookie - * @return string - */ - public function setCookieParams($cookie = array()) { - extract($this->getCookieParams()); - extract($cookie); - if (isset($httponly)) { - session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); - } else { - session_set_cookie_params($lifetime, $path, $domain, $secure); - } - return true; - } - - /** - * 取得cookie传递sessionid的模式 - * @return number - */ - public function getCookieMode() { - if ('0' === ini_get('session.use_cookies')) { - self::COOKIE_MODE_NONE; - } else if ('0' === ini_get('session.use_only_cookies')) { - return self::COOKIE_MODE_ALLOW; - } else { - return self::COOKIE_MODE_ONLY; - } - return false; - } - - /** - * 设置cookie传递sessionid的模式 - * @param int $mode - * @return string - */ - public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { - if (self::COOKIE_MODE_NONE === $mode) { - ini_set('session.use_cookies', '0'); - } else if (self::COOKIE_MODE_ALLOW === $mode) { - ini_set('session.use_cookies', '1'); - ini_set('session.use_only_cookies', '0'); - } else if (self::COOKIE_MODE_ONLY === $mode) { - ini_set('session.use_cookies', '1'); - ini_set('session.use_only_cookies', '1'); - } else { - return false; - } - return true; - } - - /** - * 获取session进行清理的概率 - * @return number - */ - public function getGCProbability() { - return (int) ini_get('session.gc_probability'); - } - - /** - * 设置session进行清理的概率 - * @param int $probability 概率数 - * @return string|string - */ - public function setGCProbability($probability) { - if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { - return false; - } - ini_set('session.gc_probability', $probability); - ini_set('session.gc_divisor', '100'); - return true; - } - - /** - * 是否允许sessionid通过url参数传递 - * @return boolean - */ - public function getTransSessionID() { - return '1' === ini_get('session.use_trans_sid'); - } - - /** - * 设置是否允许sessionid通过url参数传递 - * @param int $ifTrans - * @return string - */ - public function setTransSessionID($ifTrans = 0) { - return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); - } - - /** - * 获取session存活时间 - * @return number - */ - public function getSessionLifeTime() { - return (int) ini_get('session.gc_maxlifetime'); - } - - /** - * 设置session存活时间 - * @param int $time - * @return number - */ - public function setSessionLifeTime($time = 0) { - return (int) ini_set('session.gc_maxlifetime', (int) $time); - } - - /** - * 是否自动启动session - * @return boolean - */ - public function getAutoStart() { - return '1' === ini_get('session.auto_start'); - } - - /** - * 设置自动启动 - * @param boolean $autostart 是否自动启动 - * @return string - */ - public function setAutoStart($autostart) { - return ini_set('session.auto_start', $autostart ? '1' : '0'); - } - - /** - * 获取当前session的文件名 - * @return string - */ - public function getCurrentSessionFileName(){ - return $this->getSavePath().'/sess_'.$this->getSessionId(); - } - - public function offsetExists($offset) { - $this->exist($offset); - } - - public function offsetSet($offset, $value) { - $this->set($offset, $value); - } - - public function offsetGet($offset) { - $this->get($offset); - } - public function offsetUnset($offset) { - $this->remove($offset); - } - - public function getIterator($name = null) { - return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); - } - - public function count() { - return count($_SESSION); - } -} \ No newline at end of file diff --git a/wind/component/http/transfer/AbstractWindHttp.php b/wind/component/http/transfer/AbstractWindHttp.php deleted file mode 100644 index 67996671..00000000 --- a/wind/component/http/transfer/AbstractWindHttp.php +++ /dev/null @@ -1,280 +0,0 @@ - 2010-12-23 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -abstract class AbstractWindHttp { - - /** - * @var WindHttp 单例 对象 - */ - protected static $instance = null; - - /** - * @var resource http连接句柄 - */ - protected $httpResource = null; - - /** - * @var string 发送的cookie - */ - protected $cookie = array(); - /** - * @var array 发送的http头 - */ - protected $header = array(); - /** - * @var array 访问的URL地址 - */ - protected $url = ''; - /** - * @var array 发送的数据 - */ - protected $data = array(); - - /** - * @var string 错误信息 - */ - protected $err = ''; - /** - * @var string 错误编码 - */ - protected $eno = 0; - - /** - * @var string 超时时间 - */ - protected $timeout = 0; - - /** - * @var strint 指向$cookie属性 - */ - const _COOKIE = 'cookie'; - /** - * @var string 指向$header属性 - */ - const _HEADER = 'header'; - /** - * @var string 指定$data属性 - */ - const _DATA = 'data'; - - const GET = 'GET'; - const POST = 'POST'; - /** - * 声明受保护的构造函数,避免在类的外界实例化 - * @param string $url - */ - protected function __construct($url = '', $timeout = 5) { - $this->url = $url; - $this->timeout = $timeout; - } - - /** - * 发送post请求 - * @param string $url 请求的url - * @param array $data 请求的数据 - * @param array $header 发送请求的头 - * @param array $cookie 发送的cookie - * @param array $options 额外的请求头 - * @return string 返回页根据请求的响应页面 - */ - public abstract function post($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); - /** - * get方式传值 - * @param string $url 请求的url - * @param array $data 请求的数据 - * @param array $header 发送请求的头 - * @param array $cookie 发送的cookie - * @param array $options 额外的请求头 - * @return string 返回页根据请求的响应页面 - */ - public abstract function get($url = '', $data = array(), $header = array(), $cookie = array(), $options = array()); - /** - * 发送请求底层操作 - * @param string $method 请求方式 - * @param array $options 额外的主求参数 - * @return string 返回页根据请求的响应页面 - */ - public abstract function send($method = self::GET, $options = array()); - - /** - * 打开一个http请求 - * @return httpResource http请求指针 - */ - public abstract function open(); - /** - * 发送请求 - * @param string $key 请求的名称 - * @param string $value 请求的值 - * @return boolean - */ - public abstract function request($key, $value = null); - /** - * 以数组格式请求 - * @param array $request - * @return boolean - */ - public abstract function requestByArray($request = array()); - /** - * 响应用户的请求 - * @return string 返回响应 - */ - public abstract function response(); - /** - *响应用户请求,只返回一行数据 - *@return string - */ - public abstract function resonseLine(); - /** - * - * 关闭请求 - */ - public abstract function close(); - /** - * 取得http通信中的错误 - */ - public abstract function getError(); - - /** - * 获取http单例对象,对象唯一访问入口 - * @param string $url 请求的url - * @return WindHttp - */ - public static abstract function getInstance($url = ''); - - /** - * 防止克隆 - */ - protected function __clone() {} - - /** - * 设置url - * @param string|array $url - */ - public function setUrl($url) { - $url && $this->url = $url; - } - /** - * 设置http头 - * @param string $key - * @param string $value - */ - public function setHeader($key, $value) { - $this->header[$key] = $value; - } - /** - * 批量设置http头 - * @param array $datas 实际的http头,数组的值基于key/value形式 - * @return boolean - */ - public function setHeaders($headers = array()) { - return $this->setPropertityValue(self::_HEADER, $headers); - } - /** - * 设置cookie - * @param string $key - * @param string $value - */ - public function setCookie($key, $value) { - $this->cookie[$key] = $value; - } - /** - * 批量设置要传送的cookie - * @param array $cookies 要传送的cookie,数组的值基于key/value形式 - * @return boolean - */ - public function setCookies($cookies = array()) { - return $this->setPropertityValue(self::_COOKIE, $cookies); - } - /** - * 设置data - * @param string $key - * @param string $value - */ - public function setData($key, $value) { - $this->data[$key] = $value; - } - /** - * 批量设置要传送的数据 - * @param array $datas 要传送的数据,数组的值基于key/value形式 - * @return boolean - */ - public function setDatas($datas = array()) { - return $this->setPropertityValue(self::_DATA, $datas); - } - /** - *请空数据,重新发送请求 - */ - public function clear() { - $this->url = array(); - $this->header = array(); - $this->cookie = array(); - $this->data = array(); - } - - /** - * 构请查询字符串 - * @param array $query 查询的关联数组 - * @param string $sep 分隔符 - * @return string - */ - public static function buildQuery($query, $sep = '&') { - if (!is_array($query)) { - return ''; - } - $_query = ''; - foreach ($query as $key => $value) { - $tmp = rawurlencode($key) . '=' . rawurlencode($value); - $_query .= $_query ? $sep . $tmp : $tmp; - } - return $_query; - } - /** - * 以指定分隔符的形式来将数组转化成字符串 - * @param array $array 关联数组 - * @param strin $sep 分隔符 - * @return string - */ - public static function buildArray($array, $sep = ':') { - if (!is_array($array)) { - return array(); - } - $_array = array(); - foreach ($array as $key => $value) { - $_array[] = $key . $sep . $value; - } - return $_array; - } - - /** - * 增量式设置对象的属性的值 - * @param string $propertity 要设置的对象的属性 - * @param array $value 要设置属性的值 - * @return boolean - */ - private function setPropertityValue($propertity, $value = array()) { - if (!in_array($propertity, array(self::_COOKIE, self::_DATA, self::_HEADER))) { - return false; - } - if (!is_array($value)) { - return false; - } - if (empty($this->$propertity)) { - $this->$propertity = $value; - } else { - foreach ($value as $key => $_value) { - $this->$propertity[$key] = $_value; - } - } - return true; - } -} \ No newline at end of file diff --git a/wind/component/http/transfer/WindHttpCurl.php b/wind/component/http/transfer/WindHttpCurl.php deleted file mode 100644 index fe0b5ffd..00000000 --- a/wind/component/http/transfer/WindHttpCurl.php +++ /dev/null @@ -1,147 +0,0 @@ - 2010-12-23 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.http.transfer.AbstractWindHttp'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -final class WindHttpCurl extends AbstractWindHttp { - - protected function __construct($url = '', $timeout = 5) { - parent::__construct($url, $timeout); - } - - /* - * @see wind/component/http/base/WindHttp#open() - */ - public function open() { - if (null === $this->httpResource) { - $this->httpResource = curl_init(); - } - return $this->httpResource; - } - - /* - * @see wind/component/http/base/WindHttp#request() - */ - public function request($name, $value = null) { - return curl_setopt($this->httpResource, $name, $value); - } - - /* - * @see wind/component/http/base/WindHttp#requestByArray() - */ - public function requestByArray($opt = array()) { - return curl_setopt_array($this->httpResource, $opt); - } - - /* - * @see wind/component/http/base/WindHttp#response() - */ - public function response() { - return curl_exec($this->httpResource); - } - - /** - * @see wind/component/http/base/WindHttp#resonseLine() - */ - public function resonseLine(){ - return ''; - } - - /** - * 释放资源 - */ - public function close() { - if ($this->httpResource) { - curl_close($this->httpResource); - $this->httpResource = null; - } - } - - /* - * @see wind/component/http/base/WindHttp#getError() - */ - public function getError() { - $this->err = curl_error($this->httpResource); - $this->eno = curl_errno($this->httpResource); - return $this->err ? $this->eno . ':' . $this->err : ''; - } - - /* - * @see wind/component/http/base/WindHttp#post() - */ - public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { - $url && $this->setUrl($url); - $header && is_array($header) && $this->setHeaders($header); - $cookie && is_array($cookie) && $this->setCookies($cookie); - $data && is_array($data) && $this->setDatas($data); - return $this->send(self::POST, $option); - } - /* - * @see wind/component/http/base/WindHttp#get() - */ - public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { - $url && $this->setUrl($url); - $header && is_array($header) && $this->setHeaders($header); - $cookie && is_array($cookie) && $this->setCookies($cookie); - $data && is_array($data) && $this->setDatas($data); - return $this->send(self::GET, $option); - } - /* - * @see wind/component/http/base/WindHttp#send() - */ - public function send($method = self::GET, $options = array()) { - if (null === $this->httpResource) { - $this->open(); - } - $this->request(CURLOPT_HEADER, 0); - $this->request(CURLOPT_FOLLOWLOCATION, 1); - $this->request(CURLOPT_RETURNTRANSFER, 1); - $this->request(CURLOPT_TIMEOUT, $this->timeout); - if ($options && is_array($options)) { - $this->requestByArray($options); - } - if (self::GET === $method && $this->data) { - $get = self::buildQuery($this->data, '&'); - $url = parse_url($this->url); - $sep = isset($url['query']) ? '&' : '?'; - $this->url .= $sep . $get; - } - if (self::POST === $method && $this->data) { - $this->request(CURLOPT_POST, 1); - $this->request(CURLOPT_POSTFIELDS, self::buildQuery($this->data, '&')); - } - if ($this->cookie && $this->cookie) { - $this->request(CURLOPT_COOKIE, self::buildQuery($this->cookie, ';')); - } - if (empty($this->header)) { - $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1'); - } - $this->request(CURLOPT_HTTPHEADER, self::buildArray($this->header, ':')); - $this->request(CURLOPT_URL, $this->url); - return $this->response(); - } - - /* - * @see wind/component/http/base/WindHttp#requestByArray() - */ - public static function getInstance($url = '') { - if (null === self::$instance || false === (self::$instance instanceof self)) { - self::$instance = new self($url); - } - return self::$instance; - } - - public function __destruct() { - $this->close(); - } -} - diff --git a/wind/component/http/transfer/WindHttpSocket.php b/wind/component/http/transfer/WindHttpSocket.php deleted file mode 100644 index 06c6d5f8..00000000 --- a/wind/component/http/transfer/WindHttpSocket.php +++ /dev/null @@ -1,166 +0,0 @@ - 2010-12-23 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.http.transfer.AbstractWindHttp'); -/** - * socket操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -final class WindHttpSocket extends AbstractWindHttp { - - private $host = ''; - private $port = 0; - private $path = ''; - private $query = ''; - - protected function __construct($url = '', $timeout = 5) { - parent::__construct($url, $timeout); - } - - /* - * @see wind/component/http/base/WindHttp#open() - */ - public function open() { - if (null === $this->httpResource) { - $url = parse_url($this->url); - $this->host = $url['host']; - $this->port = isset($url['port']) && $url['port'] ? $url['port'] : 80; - $this->path = isset($url['path']) && $url['path'] ? $url['path'] : '/'; - $this->path .= $url['query'] ? '?' . $url['query'] : ''; - $this->query = $url['query']; - $this->httpResource = fsockopen($this->host, $this->port, $this->eno, $this->err, $this->timeout); - } - return $this->httpResource; - } - - /* - * @see wind/component/http/base/WindHttp#request() - */ - public function request($name, $value = null) { - return fputs($this->httpResource, ($value ? $name . ': ' . $value : $name) . "\n"); - } - - /* - * @see wind/component/http/base/WindHttp#requestByArray() - */ - public function requestByArray($request = array()) { - $_request = ''; - foreach ($request as $key => $value) { - if (is_string($key)) { - $_request .= $key . ': ' . $value; - } - if (is_int($key)) { - $_request .= $value; - } - $_request .= "\n"; - } - fputs($this->httpResource, $_request); - } - /* - * @see wind/component/http/base/WindHttp#resonseLine() - */ - public function response() { - $response = ''; - while (!feof($this->httpResource)) { - $response .= fgets($this->httpResource); - } - return $response; - } - - /** - * @see wind/component/http/base/WindHttp#response() - */ - public function resonseLine(){ - return feof($this->httpResource) ? '' : fgets($this->httpResource); - } - - /* - * @see wind/component/http/base/WindHttp#close() - */ - public function close() { - if ($this->httpResource) { - fclose($this->httpResource); - $this->httpResource = null; - } - } - - /* - * @see wind/component/http/base/WindHttp#getError() - */ - public function getError() { - return $this->err ? $this->eno . ':' . $this->err : ''; - } - /* - * @see wind/component/http/base/WindHttp#post() - */ - public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { - $url && $this->setUrl($url); - $header && is_array($header) && $this->setHeaders($header); - $cookie && is_array($cookie) && $this->setCookies($cookie); - $data && is_array($data) && $this->setDatas($data); - return $this->send(self::POST, $option); - } - /* - * @see wind/component/http/base/WindHttp#get() - */ - public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { - $url && $this->setUrl($url); - $header && is_array($header) && $this->setHeaders($header); - $cookie && is_array($cookie) && $this->setCookies($cookie); - $data && is_array($data) && $this->setDatas($data); - return $this->send(self::GET, $option); - } - /* - * @see wind/component/http/base/WindHttp#send() - */ - public function send($method = self::GET, $options = array()) { - if (self::GET === $method && $this->data) { - $url = parse_url($this->url); - $get = self::buildQuery($this->data, '&'); - $this->url .= ($url['query'] ? '&' : '?') . $get; - } - $this->open(); - $this->setHeader("Host", $this->host); - $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); - if ($this->cookie && $this->cookie) { - $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); - } - if (self::POST === $method && $this->data) { - $data = self::buildQuery($this->data, '&'); - $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); - $this->setHeader('Content-Length', strlen($data)); - } - if ($options) { - $this->setHeaders($options); - } - $this->setHeader('Connection', 'Close'); - $this->request($method . " " . $this->path . " HTTP/1.1"); - $this->requestByArray($this->header); - if ($data) { - $this->request("\n" . $data); - } - $this->request("\n"); - return $this->response(); - } - - /* - * @see wind/component/http/base/WindHttp#getInstance() - */ - public static function getInstance($url = '') { - if (null === self::$instance || false === (self::$instance instanceof self)) { - self::$instance = new self($url); - } - return self::$instance; - } - - public function __destruct() { - $this->close(); - } -} \ No newline at end of file diff --git a/wind/component/http/transfer/WindHttpStream.php b/wind/component/http/transfer/WindHttpStream.php deleted file mode 100644 index abee1faa..00000000 --- a/wind/component/http/transfer/WindHttpStream.php +++ /dev/null @@ -1,178 +0,0 @@ - 2010-12-23 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.http.transfer.AbstractWindHttp'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -final class WindHttpStream extends AbstractWindHttp { - const HTTP = 'http'; - const HTTPS = 'https'; - const FTP = 'ftp'; - const FTPS = 'ftp'; - const SOCKET = 'socket'; - - /** - * @var string 字节流对象 - */ - private $context = null; - /** - * @var string 通信协议 - */ - private $wrapper = self::HTTP; - protected function __construct($url = '', $timeout = 5) { - parent::__construct($url, $timeout); - $this->context = stream_context_create(); - } - - /** - * 设置通信协议 - * @param string $wrapper - */ - public function setWrapper($wrapper = self::HTTP) { - $this->wrapper = $wrapper; - } - - /* - * @see wind/component/http/base/WindHttp#open() - */ - public function open() { - if (null === $this->httpResource) { - $this->httpResource = fopen($this->url, 'r', false, $this->context); - } - return $this->httpResource; - } - - /* - * @see wind/component/http/base/WindHttp#request() - */ - public function request($name, $value = null) { - return stream_context_set_option($this->context, $this->wrapper, $name, $value); - } - - /* - * @see wind/component/http/base/WindHttp#requestByArray() - */ - public function requestByArray($opt = array()) { - foreach ($opt as $key => $value) { - if (false === $this->request($key, $value)) { - return false; - } - } - return true; - } - - /* - * @see wind/component/http/base/WindHttp#response() - */ - public function response() { - $response = ''; - while (!feof($this->httpResource)) { - $response .= fgets($this->httpResource); - } - return $response; - } - - /** - * @see wind/component/http/base/WindHttp#resonseLine() - */ - public function resonseLine(){ - return feof($this->httpResource) ? '' : fgets($this->httpResource); - } - - /** - * 释放资源 - */ - public function close() { - if ($this->httpResource) { - fclose($this->httpResource); - $this->httpResource = null; - $this->context = null; - } - } - - /* - * @see wind/component/http/base/WindHttp#getError() - */ - public function getError() { - return $this->err ? $this->eno . ':' . $this->err : ''; - } - - /* - * @see wind/component/http/base/WindHttp#post() - */ - public function post($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { - $url && $this->setUrl($url); - $header && is_array($header) && $this->setHeaders($header); - $cookie && is_array($cookie) && $this->setCookies($cookie); - $data && is_array($data) && $this->setDatas($data); - return $this->send(self::POST, $option); - } - /* - * @see wind/component/http/base/WindHttp#get() - */ - public function get($url = '', $data = array(), $header = array(), $cookie = array(), $option = array()) { - $url && $this->setUrl($url); - $header && is_array($header) && $this->setHeaders($header); - $cookie && is_array($cookie) && $this->setCookies($cookie); - $data && is_array($data) && $this->setDatas($data); - return $this->send(self::GET, $option); - } - /* - * @see wind/component/http/base/WindHttp#send() - */ - public function send($method = self::GET, $options = array()) { - $url = parse_url($this->url); - if (self::GET === $method && $this->data) { - $get = self::buildQuery($this->data, '&'); - $this->url .= ($url['query'] ? '&' : '?') . $get; - } - if (self::POST === $method && $this->data) { - $data = self::buildQuery($this->data, '&'); - $this->setHeader('Content-Type', 'application/x-www-form-urlencoded'); - $this->setHeader('Content-Length', strlen($data)); - } - $this->setHeader("Host", $url['host']); - $this->setHeader('User-Agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)'); - if ($this->cookie) { - $this->setHeader("Cookie", self::buildQuery($this->cookie, ';')); - } - $this->setHeader('Connection', 'Close'); - $this->request('method', $method); - $this->request('timeout', $this->timeout); - - if ($this->header) { - $header = ''; - foreach ($this->header as $key => $value) { - $header .= $key . ': ' . $value . "\n"; - } - $this->request('header', $header); - } - $data && $this->request('content', $data); - $options && is_array($options) && $this->requestByArray($options); - $this->open(); - return $this->response(); - } - - /** - * @see wind/component/http/base/WindHttp#getInstance() - * - */ - public static function getInstance($url = '') { - if (null === self::$instance || false === (self::$instance instanceof self)) { - self::$instance = new self($url); - } - return self::$instance; - } - - public function __destruct() { - $this->close(); - } -} \ No newline at end of file From e2516a5e3f961879fa82aa72603c32280bb7f628 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 08:04:12 +0000 Subject: [PATCH 0429/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2501 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/component/collections/WindList.php | 280 ------ wind/component/collections/WindQueue.php | 134 --- wind/component/collections/WindSortedList.php | 333 ------- wind/component/collections/WindStack.php | 125 --- wind/component/dao/WindDao.php | 35 - wind/component/dao/WindDaoFactory.php | 63 -- .../dao/exception/WindDaoException.php | 27 - .../dao/listener/WindDaoCacheListener.php | 55 -- wind/component/db/WindConnection.php | 281 ------ wind/component/db/WindConnectionManager.php | 71 -- wind/component/db/WindResultSet.php | 165 ---- wind/component/db/WindSqlStatement.php | 375 -------- wind/component/db/drivers/mssql/WindMsSql.php | 159 ---- .../db/drivers/mssql/WindMsSqlBuilder.php | 93 -- wind/component/db/drivers/mysql/WindMySql.php | 207 ---- .../db/drivers/mysql/WindMySqlBuilder.php | 99 -- .../db/exception/WindDbException.php | 123 --- .../db/mysql/WindMysqlPdoAdapter.php | 82 -- wind/component/ftp/AbstractWindFtp.php | 185 ---- wind/component/ftp/WindFtp.php | 186 ---- wind/component/ftp/WindSocketFtp.php | 274 ------ wind/component/log/WindDebug.php | 175 ---- wind/component/log/WindLogger.php | 386 -------- wind/component/mail/WindMail.php | 898 ------------------ wind/component/mail/protocol/WindImap.php | 663 ------------- wind/component/mail/protocol/WindPop3.php | 260 ----- wind/component/mail/protocol/WindSmtp.php | 211 ---- wind/component/mail/protocol/WindSocket.php | 121 --- wind/component/mail/sender/IWindSendMail.php | 15 - wind/component/mail/sender/WindPhpMail.php | 34 - wind/component/mail/sender/WindSendMail.php | 85 -- wind/component/mail/sender/WindSmtpMail.php | 92 -- wind/component/parser/IWindConfigParser.php | 27 - wind/component/parser/WindConfigParser.php | 129 --- wind/component/parser/WindIniParser.php | 147 --- .../component/parser/WindPropertiesParser.php | 214 ----- wind/component/parser/WindXmlParser.php | 109 --- wind/component/router/AbstractWindRouter.php | 170 ---- wind/component/router/WindRouter.php | 40 - .../component/router/WindUrlRewriteRouter.php | 346 ------- .../router/route/AbstractWindRoute.php | 42 - .../router/route/WindRewriteRoute.php | 31 - wind/component/router/route/WindRoute.php | 53 -- wind/component/upload/AbstractWindUpload.php | 249 ----- wind/component/upload/WindCurlUpload.php | 32 - wind/component/upload/WindFormUpload.php | 45 - wind/component/upload/WindFtpUpload.php | 56 -- wind/component/utility/WindArray.php | 83 -- wind/component/utility/WindFile.php | 254 ----- wind/component/utility/WindHtmlHelper.php | 43 - wind/component/utility/WindImage.php | 303 ------ wind/component/utility/WindPack.php | 397 -------- wind/component/utility/WindSecurity.php | 300 ------ wind/component/utility/WindString.php | 242 ----- wind/component/utility/WindUtility.php | 82 -- wind/component/utility/WindValidator.php | 344 ------- wind/component/utility/date/WindDate.php | 272 ------ .../utility/date/WindGeneralDate.php | 248 ----- wind/component/utility/json/WindDecoder.php | 235 ----- wind/component/utility/json/WindEncoder.php | 202 ---- .../viewer/AbstractWindTemplateCompiler.php | 128 --- .../viewer/AbstractWindViewTemplate.php | 72 -- wind/component/viewer/IWindView.php | 20 - wind/component/viewer/IWindViewerResolver.php | 26 - wind/component/viewer/WindLayout.php | 122 --- wind/component/viewer/WindView.php | 168 ---- wind/component/viewer/WindViewerResolver.php | 187 ---- .../compiler/WindTemplateCompilerAction.php | 40 - .../WindTemplateCompilerComponent.php | 149 --- .../compiler/WindTemplateCompilerCss.php | 23 - .../compiler/WindTemplateCompilerEcho.php | 34 - .../compiler/WindTemplateCompilerInternal.php | 25 - .../compiler/WindTemplateCompilerPage.php | 77 -- .../compiler/WindTemplateCompilerScript.php | 33 - .../compiler/WindTemplateCompilerTemplate.php | 55 -- .../viewer/compiler/WindViewTemplate.php | 190 ---- wind/component/viewer/errorPage/404.htm | 10 - .../viewer/errorPage/default_error.htm | 45 - .../viewer/exception/WindViewException.php | 30 - .../viewer/listener/WindViewCacheListener.php | 52 - 80 files changed, 12473 deletions(-) delete mode 100644 wind/component/collections/WindList.php delete mode 100644 wind/component/collections/WindQueue.php delete mode 100644 wind/component/collections/WindSortedList.php delete mode 100644 wind/component/collections/WindStack.php delete mode 100644 wind/component/dao/WindDao.php delete mode 100644 wind/component/dao/WindDaoFactory.php delete mode 100644 wind/component/dao/exception/WindDaoException.php delete mode 100644 wind/component/dao/listener/WindDaoCacheListener.php delete mode 100644 wind/component/db/WindConnection.php delete mode 100644 wind/component/db/WindConnectionManager.php delete mode 100644 wind/component/db/WindResultSet.php delete mode 100644 wind/component/db/WindSqlStatement.php delete mode 100644 wind/component/db/drivers/mssql/WindMsSql.php delete mode 100644 wind/component/db/drivers/mssql/WindMsSqlBuilder.php delete mode 100644 wind/component/db/drivers/mysql/WindMySql.php delete mode 100644 wind/component/db/drivers/mysql/WindMySqlBuilder.php delete mode 100644 wind/component/db/exception/WindDbException.php delete mode 100644 wind/component/db/mysql/WindMysqlPdoAdapter.php delete mode 100644 wind/component/ftp/AbstractWindFtp.php delete mode 100644 wind/component/ftp/WindFtp.php delete mode 100644 wind/component/ftp/WindSocketFtp.php delete mode 100644 wind/component/log/WindDebug.php delete mode 100644 wind/component/log/WindLogger.php delete mode 100644 wind/component/mail/WindMail.php delete mode 100644 wind/component/mail/protocol/WindImap.php delete mode 100644 wind/component/mail/protocol/WindPop3.php delete mode 100644 wind/component/mail/protocol/WindSmtp.php delete mode 100644 wind/component/mail/protocol/WindSocket.php delete mode 100644 wind/component/mail/sender/IWindSendMail.php delete mode 100644 wind/component/mail/sender/WindPhpMail.php delete mode 100644 wind/component/mail/sender/WindSendMail.php delete mode 100644 wind/component/mail/sender/WindSmtpMail.php delete mode 100644 wind/component/parser/IWindConfigParser.php delete mode 100644 wind/component/parser/WindConfigParser.php delete mode 100644 wind/component/parser/WindIniParser.php delete mode 100644 wind/component/parser/WindPropertiesParser.php delete mode 100644 wind/component/parser/WindXmlParser.php delete mode 100644 wind/component/router/AbstractWindRouter.php delete mode 100644 wind/component/router/WindRouter.php delete mode 100644 wind/component/router/WindUrlRewriteRouter.php delete mode 100644 wind/component/router/route/AbstractWindRoute.php delete mode 100644 wind/component/router/route/WindRewriteRoute.php delete mode 100644 wind/component/router/route/WindRoute.php delete mode 100644 wind/component/upload/AbstractWindUpload.php delete mode 100644 wind/component/upload/WindCurlUpload.php delete mode 100644 wind/component/upload/WindFormUpload.php delete mode 100644 wind/component/upload/WindFtpUpload.php delete mode 100644 wind/component/utility/WindArray.php delete mode 100644 wind/component/utility/WindFile.php delete mode 100644 wind/component/utility/WindHtmlHelper.php delete mode 100644 wind/component/utility/WindImage.php delete mode 100644 wind/component/utility/WindPack.php delete mode 100644 wind/component/utility/WindSecurity.php delete mode 100644 wind/component/utility/WindString.php delete mode 100644 wind/component/utility/WindUtility.php delete mode 100644 wind/component/utility/WindValidator.php delete mode 100644 wind/component/utility/date/WindDate.php delete mode 100644 wind/component/utility/date/WindGeneralDate.php delete mode 100644 wind/component/utility/json/WindDecoder.php delete mode 100644 wind/component/utility/json/WindEncoder.php delete mode 100644 wind/component/viewer/AbstractWindTemplateCompiler.php delete mode 100644 wind/component/viewer/AbstractWindViewTemplate.php delete mode 100644 wind/component/viewer/IWindView.php delete mode 100644 wind/component/viewer/IWindViewerResolver.php delete mode 100644 wind/component/viewer/WindLayout.php delete mode 100644 wind/component/viewer/WindView.php delete mode 100644 wind/component/viewer/WindViewerResolver.php delete mode 100644 wind/component/viewer/compiler/WindTemplateCompilerAction.php delete mode 100644 wind/component/viewer/compiler/WindTemplateCompilerComponent.php delete mode 100644 wind/component/viewer/compiler/WindTemplateCompilerCss.php delete mode 100644 wind/component/viewer/compiler/WindTemplateCompilerEcho.php delete mode 100644 wind/component/viewer/compiler/WindTemplateCompilerInternal.php delete mode 100644 wind/component/viewer/compiler/WindTemplateCompilerPage.php delete mode 100644 wind/component/viewer/compiler/WindTemplateCompilerScript.php delete mode 100644 wind/component/viewer/compiler/WindTemplateCompilerTemplate.php delete mode 100644 wind/component/viewer/compiler/WindViewTemplate.php delete mode 100644 wind/component/viewer/errorPage/404.htm delete mode 100644 wind/component/viewer/errorPage/default_error.htm delete mode 100644 wind/component/viewer/exception/WindViewException.php delete mode 100644 wind/component/viewer/listener/WindViewCacheListener.php diff --git a/wind/component/collections/WindList.php b/wind/component/collections/WindList.php deleted file mode 100644 index f8783ca8..00000000 --- a/wind/component/collections/WindList.php +++ /dev/null @@ -1,280 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ - -/** - * WindList集合. - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindList implements IteratorAggregate, ArrayAccess, Countable { - - /** - * @var array 集合列表 - */ - private $list = array(); - /** - * @var string 列表总数指示器 - */ - private $count = 0; - /** - * @var boolean 列表是否只读 - */ - private $isReadOnly = false; - - /** - * @var boolean 是否固定大小 - */ - private $isFixedSize = false; - - /** - * WindList 实现有三种类别:只读、固定大小、可变大小。 - * 无法修改只读 WindList。 - * 固定大小的 WindList 不允许添加或移除元素,但允许修改现有元素。 - * 可变大小的 WindList 允许添加、移除和修改元素。 - * @param boolean $readOnly 是否只读 - * @param array|WindList $data 固定长度,如果指定了$data,那么这个WindList集合的长度是固定的,只许修改 - */ - public function __construct($data = array(),$readOnly = false) { - $this->isReadOnly = $readOnly; - if(false === empty($data)){ - if(is_array($data)){ - $this->list = $data; - }elseif($data instanceof WindList){ - $this->list = $data->getList(); - }else{ - throw new WindException("Parameter type is incorrect"); - } - $this->isFixedSize = true; - $this->count = count($this->list); - } - - } - /** - * 向 WindList 中添加项。 - * @param mixed $value - * @return boolean - */ - public function add($value) { - return $this->insertAt($this->count, $value); - } - /** - * 在 WindList 中的指定索引处插入项。 - * @param int $index - * @param mixed $value - * @return boolean - */ - public function insertAt($index, $value) { - if($this->isFixedSize && $this->count === $index){ - throw new WindException("The list size is fixed"); - } - if (false === $this->isReadOnly) { - if ($this->count === $index) { - $this->list[$this->count++] = $value; - } elseif (0 <= $index && $this->count > $index) { - array_splice($this->list, $index, 0, array($value)); - $this->count++; - } elseif ($this->count < $index || 0 > $index) { - throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); - } - } else { - throw new WindException('The list of read-only'); - } - return true; - } - /** - * 取得指定索引的项 - * @param int $index 指定索引 - * @return mixed - */ - public function itemAt($index) { - if (false === isset($this->list[$index])) { - throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); - } - return $this->list[$index]; - } - /** - * 返回指定项的索引,返回-1表向没有指定项 - * @param mixed $value 指定项 - * @return int - */ - public function indexOf($value) { - return false !== ($index = array_search($value, $this->list, true)) ? $index : -1; - } - /** - * 判断WindList中是否包含指定项 - * @param mixed $value 指定项 - * @return boolean - */ - public function contain($value) { - return 0 <= $this->indexOf($value); - } - /** - * 判断WindList中是否包含指定的索引 - * @param int $index 指定索引 - * @return boolean - */ - public function containAt($index) { - return 0 <= $index && $this->count > $index; - } - /** - * 修改WindList中指定索引的项 - * @param int $index 指定索引 - * @param mixed $value 要修改的项 - * @return boolean - */ - public function modify($index,$value){ - $this->removeAt($index,true); - $this->count++; - $this->insertAt($index, $value); - $this->count--; - return true; - } - /** - * 从WindList中移除指定索引的项 - * @param int $index 指定索引 - * @return mixed - */ - public function removeAt($index,$force = false) { - if ($this->isReadOnly) { - throw new WindException('The list of read-only'); - } - if($this->isFixedSize && false === $force){ - throw new WindException("The list size is fixed"); - } - if ($index > $this->count || $index < 0) { - throw new WindException('Index out of range, is indeed the range should be between 0 to '.$this->count); - } - $this->count--; - if (0 === $index) { - return array_shift($this->list); - } - if ($this->count === $index) { - return array_pop($this->list); - } - $item = $this->list[$index]; - array_splice($this->list, $index, 1); - return $item; - } - /** - * 从WindList中移除指定的项 - * @param mixed $value 指定的项 - * @return boolean - */ - public function remove($value) { - return $this->removeAt($this->indexOf($value)); - } - /** - * 清空WindList - * @return boolean - */ - public function clear() { - if ($this->isReadOnly) { - throw new WindException('The list of read-only'); - } - if($this->isFixedSize){ - throw new WindException("The list size is fixed"); - } - $this->count = 0; - $this->list = array(); - return true; - } - /** - * 将数组中的值合并到WindList - * @param array $array 要合并的数组 - * @return boolean - */ - public function mergeFromArray(array $array) { - foreach ($array as $value) { - $this->add($value); - } - return true; - } - /** - * 将WindList集合合并到WindList - * @param WindList $list 要合并的WindList集合 - * @return boolean - */ - public function mergeFromList(WindList $list) { - foreach ($list as $value) { - $this->add($value); - } - return true; - } - /** - * @return array - */ - public function getList() { - return $this->list; - } - /** - * 取得集合的总数 - * @return string - */ - public function getCount() { - return $this->count; - } - /** - * 取得集合是否只读 - * @return boolean - */ - public function getIsReadOnly() { - return $this->isReadOnly; - } - /** - * 取得集合是否是固定大小 - * @return boolean - */ - public function getIsFixedSize(){ - return $this->isFixedSize; - } - /* - * 计算集合的总个数 - * @see Countable#count() - */ - public function count() { - return $this->getCount(); - } - /** - * @param int $offset - */ - public function offsetExists($offset) { - return $this->containAt($offset); - } - /** - * @param int $offset - */ - public function offsetGet($offset) { - return $this->itemAt($offset); - } - /** - * @param int $offset - * @param mixed $value - */ - public function offsetSet($offset, $value) { - if (null === $offset || $this->count === $offset) { - return $this->add($value); - } - return $this->modify($offset, $value); - } - /** - * @param int $offset - */ - public function offsetUnset($offset) { - return $this->removeAt($offset); - } - /** - * 取得集合的迭代器 - */ - public function getIterator() { - return new ArrayIterator($this->list); - } - -} \ No newline at end of file diff --git a/wind/component/collections/WindQueue.php b/wind/component/collections/WindQueue.php deleted file mode 100644 index 0400068c..00000000 --- a/wind/component/collections/WindQueue.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ - -/** - * 队列操作,先进先出 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindQueue implements IteratorAggregate,Countable{ - /** - * @var array 队列列表 - */ - private $list = array(); - /** - * @var string 列表总数指示器 - */ - private $count = 0; - - /** - * 移除并返回位于 Queue顶部的元素。 - * @return mixed - */ - public function dequeue(){ - if(!$this->count){ - throw new WindException("The queue is empty"); - } - --$this->count; - return array_shift($this->list); - } - - /** - * 返回位于 Queue顶部的对象但不将其移除。 - * @return mixed - */ - public function peek(){ - if(!$this->count){ - throw new WindException("The queue is empty"); - } - return $this->list[0]; - } - - /** - * 将元素添加到 Queue的底部。 - * @param mixed $value - * @return number - */ - public function enqueue($value){ - ++$this->count; - return array_push($this->list,$value); - } - - /** - * 确定某元素是否在 Queue中。 - * @param mixed $value - * @return boolean - */ - public function contain($value){ - return false !==array_search($value, $this->list, true); - } - - /** - * 将数组中的值合并到当前WindQueue队列 - * @param array $array 要合并的数组 - * @return boolean - */ - public function mergeFromArray(array $array) { - foreach ($array as $value) { - $this->enqueue($value); - } - return true; - } - /** - * 将WindQueue队列集合合并到当前WindQueue队列 - * @param WindQueue $list 要合并的WindQueue集合 - * @return boolean - */ - public function mergeFromQueue(WindQueue $queue) { - foreach ($queue as $value) { - $this->enqueue($value); - } - return true; - } - - /** - *清空队列 - */ - public function clear(){ - $this->list = array(); - $this->count = 0; - return true; - } - - /** - * 创建 Queue的浅表副本。 - * @return WindQueue - */ - public function __clone(){ - return new self(); - } - - /** - * 取得队列个数 - * @return int - */ - public function getCount(){ - return $this->count; - } - - - /* - * 计算队列个数 - * @see Countable#count() - */ - public function count() { - return $this->getCount(); - } - - /** - * 取得队列的迭代器 - */ - public function getIterator() { - return new ArrayIterator($this->list); - } - - -} \ No newline at end of file diff --git a/wind/component/collections/WindSortedList.php b/wind/component/collections/WindSortedList.php deleted file mode 100644 index 6408320a..00000000 --- a/wind/component/collections/WindSortedList.php +++ /dev/null @@ -1,333 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ - -/** - * 表示键/值对的集合,这些键值对按键排序并可按照键和索引访问。 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSortedList implements IteratorAggregate, ArrayAccess, Countable { - /** - * @var array 集合列表 - */ - private $list = array(); - /** - * @var int 列表总数指示器 - */ - private $count = 0; - /** - * @var boolean 列表是否只读 - */ - private $isReadOnly = false; - - /** - * @var boolean 是否固定大小 - */ - private $isFixedSize = false; - - /** - * WindList 实现有三种类别:只读、固定大小、可变大小。 - * 无法修改只读 WindList。 - * 固定大小的 WindList 不允许添加或移除元素,但允许修改现有元素。 - * 可变大小的 WindList 允许添加、移除和修改元素。 - * @param boolean $readOnly 是否只读 - * @param array|WindList $data 固定长度,如果指定了$data,那么这个WindList集合的长度是固定的,只许修改 - */ - public function __construct($data = array(), $readOnly = false) { - $this->isReadOnly = $readOnly; - if (false === empty($data)) { - if (is_array($data)) { - $this->list = $data; - } elseif ($data instanceof WindList) { - $this->list = $data->getList(); - } else { - throw new WindException("Parameter type is incorrect"); - } - $this->isFixedSize = true; - $this->count = count($this->list); - } - - } - - /** - * 将带有指定键和值的元素添加到 WindSortedList 对象。 - * @param mixed $key - * @param mixed $value - */ - public function add($key, $value) { - $this->checkPermissions(); - if (isset($this->list[$key])) { - throw new WindException($key . ' key already exists in the collection'); - } - $this->list[$key] = $value; - ++$this->count; - return true; - } - /** - * 确定 WindSortedList对象是否包含特定的键。 - * @param mixed $key - * @return boolean - */ - public function contains($key) { - return $this->containsKey($key); - } - - /** - * 根据指定的索引确定 WindSortedList对象是否包含特定的键。 - * @param mixed $key - * @return boolean - */ - public function containsIndex($index) { - return $this->containsKey($this->getKey($index)); - } - - /** - * 确定 WindSortedList对象是否包含特定的键。 - * @param mixed $key - * @return boolean - */ - public function containsKey($key) { - return 0 <= $this->indexOfKey($key); - } - - /** - * 确定 WindSortedList对象是否包含特定值。 - * @param mixed $value - * @return boolean - */ - public function containsValue($value) { - return 0 <= $this->indexOfValue($value); - } - - /** - * 获取 WindSortedList 对象的指定索引处的键。 - * @param int $index 指定的索引 - * @return mixed - */ - public function getKey($index) { - $keys = $this->getKeyList(); - if (false === isset($keys[$index])) { - throw new WindException('Index out of range, is indeed the range should be between 0 to ' . $this->count); - } - return $keys[$index]; - } - - /** - * 获取WindSortedList 对象中的键。 - * @return mixed - */ - public function getKeyList() { - return array_keys($this->list); - } - - /** - * 获取WindSortedList 对象中的值。 - * @return mixed - */ - public function getValueList() { - return array_values($this->list); - } - - /** - * 返回WindSortedList 对象中指定键的从零开始的索引。 - * @param mixed $key - * @return mixed - */ - public function indexOfKey($key) { - return false !== ($index = array_search($key, $this->getKeyList(), true)) ? $index : -1; - } - - /** - * 返回指定的值在 SortedList 对象中第一个匹配项的从零开始的索引。 - * @param mixed $value - * @return mixed - */ - public function indexOfValue($value) { - return false !== ($index = array_search($value, $this->getValueList(), true)) ? $index : -1; - } - - /** - * 从WindSortedList中返回指定键的的值 - * @param int $key - * @return mixed - */ - public function item($key) { - if (false === isset($this->list[$key])) { - throw new WindException($key . ' is not exists in the collection'); - } - return $this->list[$key]; - } - /** - * 从WindSortedList中返回指定索引的的值 - * @param int $index - * @return mixed - */ - public function itemAt($index) { - $key = $this->getKey($index); - return $this->list[$key]; - } - /** - * 从 SortedList 对象中移除带有指定键的元素。 - * @param mixed $key - * @return mixed - */ - public function remove($key) { - $this->checkPermissions(); - if (false === isset($this->list[$key])) { - throw new WindException($key . ' is not exists in the collection'); - } - $item = $this->list[$key]; - unset($this->list[$key]); - --$this->count; - return $item; - } - /** - * 移除 WindSortedList对象的指定索引处的元素。 - * @param int $index - * @return mixed - */ - public function removeAt($index) { - $this->checkPermissions(); - $key = $this->getKey($index); - $item = $this->list[$key]; - unset($this->list[$key]); - --$this->count; - return $item; - } - /** - * 替换WindSortedList对象中指定索引处的值。 - * @param int $index - * @param mixed $value - * @return boolean - */ - public function setByIndex($index, $value) { - $this->checkPermissions(false); - $key = $this->getKey($index); - $this->list[$key] = $value; - return true; - } - /** - * 替换WindSortedList对象中指定键处的值。 - * 如果指定的键存在,那么替换,否则新增 - * @param mixed $key - * @param mixed $value - * @return mixed - */ - public function setByKey($key, $value) { - $this->checkPermissions(false); - if (isset($this->list[$key])) { - $item = $this->list[$key]; - $this->list[$key] = $value; - return $item; - } - $this->list[$key] = $value; - ++$this->count; - return $value; - } - - /** - * 从 SortedList 对象中移除所有元素。 - * @return boolean - */ - public function clear() { - $this->checkPermissions(); - $this->count = 0; - $this->list = array(); - return true; - } - /** - * 取得集合是否只读 - * @return boolean - */ - public function getIsReadOnly() { - return $this->isReadOnly; - } - /** - * 取得集合是否是固定大小 - * @return boolean - */ - public function getIsFixedSize(){ - return $this->isFixedSize; - } - /** - * 返回集合的总数 - * @return number - */ - public function getCount() { - return $this->count; - } - /* 计算集合总数 - * @see Countable#count() - */ - public function count() { - return $this->getCount(); - } - /** - * 取得WindSortedList集合迭代器 - * @return ArrayIterator - */ - public function getIterator() { - return new ArrayIterator($this->list); - } - /* - * @see ArrayAccess#offsetExists() - */ - public function offsetExists($offset) { - if (is_int($offset)) { - return $this->containsIndex($offset); - } - return $this->containsKey($offset); - } - /* - * @see ArrayAccess#offsetGet() - */ - public function offsetGet($offset) { - if (is_int($offset)) { - return $this->itemAt($offset); - } - return $this->item($offset); - } - /* - * @see ArrayAccess#offsetSet() - */ - public function offsetSet($offset, $value) { - if (is_int($offset)) { - return $this->setByIndex($offset, $value); - } - return $this->setByKey($offset, $value); - } - /* - * @see ArrayAccess#offsetUnset() - */ - public function offsetUnset($offset) { - if (is_int($offset)) { - return $this->removeAt($offset); - } - return $this->remove($offset); - } - /** - * 创建 WindSortedList对象的浅表副本。 - * @return WindSortedList - */ - public function __clone() { - return new self($this->list, $this->isReadOnly); - } - - private function checkPermissions($ifcheckFixedSize = true) { - if ($this->isReadOnly) { - throw new WindException('The list of read-only'); - } - if ($this->isFixedSize && $ifcheckFixedSize) { - throw new WindException("The list size is fixed"); - } - } - -} \ No newline at end of file diff --git a/wind/component/collections/WindStack.php b/wind/component/collections/WindStack.php deleted file mode 100644 index 0a935496..00000000 --- a/wind/component/collections/WindStack.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ - -/** - * 堆栈操作,先进后出 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindStack implements IteratorAggregate,Countable{ - - /** - * @var array 集合列表 - */ - private $list = array(); - /** - * @var string 列表总数指示器 - */ - private $count = 0; - - /** - * 移除并返回位于 Stack 底部的对象。 - * @return mixed - */ - public function pop(){ - if(!$this->count){ - throw new WindException("The stack is empty"); - } - --$this->count; - return array_pop($this->list); - } - - /** - * 返回位于 Stack底部的对象但不将其移除。 - * @return mixed - */ - public function peek(){ - if(!$this->count){ - throw new WindException("The stack is empty"); - } - return $this->list[$this->count-1]; - } - - /** - * 确定某元素是否在 Stack中。 - * @param mixed $value - * @return boolean - */ - public function contain($value){ - return false !== array_search($value, $this->list, true); - } - /** - * 将元素插入 Stack 的底部。 - * @param mixed $value - * @return number - */ - public function push($value){ - ++$this->count; - return array_push($this->list,$value); - } - /** - * 清空队列 - */ - public function clear(){ - $this->count = 0; - $this->list = array(); - return true; - } - /** - * 将数组中的值合并到当前tack队列 - * @param array $array 要合并的数组 - * @return boolean - */ - public function mergeFromArray($array) { - foreach ($array as $value) { - $this->push($value); - } - return true; - } - /** - * 将WindStack堆栈集合合并到当前Stack队列 - * @param WindStack $list 要合并的WindStack集合 - * @return boolean - */ - public function mergeFromStack(WindStack $stack) { - foreach ($stack as $value) { - $this->push($value); - } - return true; - } - /** - * 取得堆栈个数 - * @return string - */ - public function getCount(){ - return $this->count; - } - /* - * 计算堆栈的总个数 - * @see Countable#count() - */ - public function count() { - return $this->getCount(); - } - /** - * 取得堆栈的迭代器 - */ - public function getIterator() { - return new ArrayIterator($this->list); - } - /** - * 创建 stack的浅表副本。 - * @return WindStack - */ - public function __clone(){ - return new self(); - } -} \ No newline at end of file diff --git a/wind/component/dao/WindDao.php b/wind/component/dao/WindDao.php deleted file mode 100644 index 567e87ab..00000000 --- a/wind/component/dao/WindDao.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindDao extends WindModule { - /** - * @var object - */ - protected $connection = null; - - /** - * 根据用户配置决定配置是采用配置链接管理 - * @return WindConnection - */ - public function getConnection($name = '') { - $this->_getConnection(); - if ($this->connection instanceof WindConnectionManager) { - return $this->connection->getConnection($name); - } - return $this->connection; - } - - /** - * @param field_type $connection - */ - public function setConnection($connection) { - $this->connection = $connection; - } -} -?> \ No newline at end of file diff --git a/wind/component/dao/WindDaoFactory.php b/wind/component/dao/WindDaoFactory.php deleted file mode 100644 index 009e610d..00000000 --- a/wind/component/dao/WindDaoFactory.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindDaoFactory extends WindModule { - /** - * dao路径信息 - * @var string - */ - protected $daoResource = ''; - - /** - * 返回Dao类实例 - * $className接受两种形式呃参数如下 - * 'namespace:path' - * 'className' - * - * @param string $className - * @return WindDao - */ - public function getDao($className) { - try { - if (strpos($className, ":") === false) - $className = $this->getDaoResource() . '.' . $className; - Wind::getApp()->getWindFactory()->addClassDefinitions($className, - array('path' => $className, 'scope' => 'application')); - $daoInstance = Wind::getApp()->getWindFactory()->getInstance($className); - $daoInstance->setDelayAttributes(array('connection' => array('ref' => 'db'))); - return $daoInstance; - } catch (Exception $exception) { - throw new WindDaoException( - '[component.dao.WindDaoFactory] create dao ' . $className . ' fail.' . $exception->getMessage()); - } - } - - /** - * 获得dao存放的目录 - * @return string $daoResource - */ - public function getDaoResource() { - return $this->daoResource; - } - - /** - * 设置dao的获取目录 - * @param string $daoResource - */ - public function setDaoResource($daoResource) { - $this->daoResource = $daoResource; - } -} -?> \ No newline at end of file diff --git a/wind/component/dao/exception/WindDaoException.php b/wind/component/dao/exception/WindDaoException.php deleted file mode 100644 index 69cb36e5..00000000 --- a/wind/component/dao/exception/WindDaoException.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindDaoException extends WindException { - - /** - * 自定义异常号的对应异常信息 - * - * @param int $code 异常号 - * @return string 返回异常号对应的异常组装信息原型 - */ - protected function messageMapper($code) { - $messages = array(); - - return isset($messages[$code]) ? $messages[$code] : '$message'; - } -} - -?> \ No newline at end of file diff --git a/wind/component/dao/listener/WindDaoCacheListener.php b/wind/component/dao/listener/WindDaoCacheListener.php deleted file mode 100644 index e35b2c6b..00000000 --- a/wind/component/dao/listener/WindDaoCacheListener.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindDaoCacheListener extends WindHandlerInterceptor { - - private $daoObject = null; - - /** - * @param AbstractWindDao $instance - */ - function __construct($instance) { - $this->daoObject = $instance; - } - - /* - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - /* @var $cacheHandler AbstractWindCache */ - $cacheHandler = $this->daoObject->getCacheHandler(); - $key = $this->generateKey(func_get_args()); - $result = $cacheHandler->get($key); - return empty($result) ? null : $result; - } - - /* - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - /* @var $cacheHandler AbstractWindCache */ - $cacheHandler = $this->daoObject->getCacheHandler(); - $key = $this->generateKey(func_get_args()); - $cacheHandler->set($key, $this->result); - } - - /** - * 返回缓存键值 - * @param array $args - * @return string - */ - private function generateKey($args) { - return $this->event[0] . '_' . $this->event[1] . '_' . (is_array($args[0]) ? $args[0][0] : $args[0]); - } -} - -?> \ No newline at end of file diff --git a/wind/component/db/WindConnection.php b/wind/component/db/WindConnection.php deleted file mode 100644 index ffd2220a..00000000 --- a/wind/component/db/WindConnection.php +++ /dev/null @@ -1,281 +0,0 @@ - - * @version $Id$ - * @package - */ -class WindConnection extends WindModule { - /** - * PDO 链接字符串 - * @var string - */ - private $_dsn; - private $_driverName; - private $_user; - private $_pwd; - private $_tablePrefix; - private $_charset; - private $_enableLog = false; - /** - * @var array - */ - private $_attributes = array(); - /** - * @var PDO - */ - private $_dbHandle = null; - - /** - * @param string $dsn - * @param string $username - * @param string $password - */ - public function __construct($dsn = '', $username = '', $password = '') { - $this->_dsn = $dsn; - $this->_user = $username; - $this->_pwd = $password; - } - - /** - * 接受一条sql语句,并返回sqlStatement对象 - * @param string $sql | sql语句 - * @return WindSqlStatement - */ - public function createStatement($sql = null) { - return new WindSqlStatement($this, $sql); - } - - /** - * 返回数据库链接对象 - * @return WindMysqlPdoAdapter - */ - public function getDbHandle() { - if ($this->_dbHandle === null) - $this->init(); - return $this->_dbHandle; - } - - /** - * 获得链接相关属性设置 - * @param string $attribute - * @return string - * */ - public function getAttribute($attribute = '') { - if (!$attribute) - return; - if ($this->_dbHandle !== null) { - return $this->_dbHandle->getAttribute($attribute); - } else - return isset($this->_attributes[$attribute]) ? $this->_attributes[$attribute] : ''; - } - - /** - * 设置链接相关属性 - * @param string $attribute - * @param string $value - * @return - * */ - public function setAttribute($attribute, $value = null) { - if (!$attribute) - return; - if ($this->_dbHandle !== null && $this->_dbHandle instanceof PDO) { - $this->_dbHandle->setAttribute($attribute, $value); - } else - $this->_attributes[$attribute] = $value; - } - - /** - * 返回DB驱动类型 - * @return string - */ - public function getDriverName() { - if ($this->_driverName) - return $this->_driverName; - if ($this->_dbHandle !== null) { - $this->_driverName = $this->_dbHandle->getAttribute(PDO::ATTR_DRIVER_NAME); - } elseif (($pos = strpos($this->_dsn, ':')) !== false) { - $this->_driverName = strtolower(substr($this->_dsn, 0, $pos)); - } - return $this->_driverName; - } - - /** - * 执行一条sql语句 同时返回影响行数 - * @param string $sql | SQL statement - * @return int - */ - public function execute($sql) { - try { - $result = $this->getDbHandle()->exec($sql); - if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindConnection.execute] \r\n\tSQL: " . $sql . - " \r\n\tResult:" . WindString::varToString( - $result)); - return $result; - } catch (PDOException $e) { - $this->close(); - throw new WindDbException($e->getMessage()); - } - } - - /** - * 执行一条查询同时返回结果集 - * @param string $sql | SQL statement - * @return WindResultSet - */ - public function query($sql) { - try { - $statement = $this->getDbHandle()->query($sql); - return new WindResultSet($statement); - } catch (PDOException $e) { - throw new WindDbException(); - } - } - - /** - * 过滤SQL元数据,数据库对象(如表名字,字段等) - * - * @param string $data - * @throws WindDbException - */ - public function sqlMetadata($data) { - $data = str_replace(array('`', ' '), '', $data); - return ' `' . $data . '` '; - } - - /** - * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组 - * - * @param array $array - */ - public function quoteArray($array) { - return $this->getDbHandle()->filterArray($array); - } - - /** - * sql元数据安全过滤 - * - * @param string $string - */ - public function quote($string) { - return $this->getDbHandle()->quote($string); - } - - /** - * 组装单条 key=value 形式的SQL查询语句值 insert/update并进行安全过滤 - * - * @param array $array - */ - public function sqlSingle($array) { - return $this->getDbHandle()->sqlSingle($array); - } - - /** - * 创建表 - * - * @param string $tableName - * @param array $fileds - */ - public function createTable($tableName, $values, $engine = '', $autoIncrement = '') { - return $this->getDbHandle()->createTable($tableName, $values, $engine, $this->_charset, - $autoIncrement); - } - - /** - * 返回最后一条插入数据ID - * - * @param string $name - * @return int - */ - public function lastInsertId($name = '') { - if ($name) - return $this->getDbHandle()->lastInsertId($name); - else - return $this->getDbHandle()->lastInsertId(); - } - - /** - * 关闭数据库连接 - */ - public function close() { - $this->_dbHandle = null; - } - - /** - * 初始化DB句柄 - * - * @throws Exception - * @return - */ - public function init() { - try { - $driverName = $this->getDriverName(); - $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; - $dbHandleClass = Wind::import($dbHandleClass); - $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, - (array) $this->_attributes); - $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->_dbHandle->setCharset($this->_charset); - if (WIND_DEBUG & 2) { - Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindConnection.init] Initialize db connection success. \r\n\tDSN:" . $this->_dsn . "\r\n\tUser:" . $this->_user . "\r\n\tCharset:" . $this->_charset . "\r\n\tTablePrefix:" . $this->_tablePrefix . "\r\n\tDriverName:" . $this->_driverName, - 'component.db'); - } - } catch (PDOException $e) { - $this->close(); - throw new WindDbException($e->getMessage()); - } - } - - /** - * (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->_dsn = $this->getConfig('dsn', '', $this->_dsn); - $this->_user = $this->getConfig('user', '', $this->_user); - $this->_pwd = $this->getConfig('pwd', '', $this->_pwd); - $this->_enableLog = $this->getConfig('enablelog', '', $this->_enableLog); - $this->_charset = $this->getConfig('charset', '', $this->_charset); - $this->_tablePrefix = $this->getConfig('tableprefix', '', $this->_tablePrefix); - } - - /** - * 获得是否启用日志记录功能 - * @return boolean $enableLog - */ - public function getEnableLog() { - return $this->_enableLog; - } - - /** - * 设置是否启用日志记录功能 - * @param boolean $enableLog - */ - public function setEnableLog($enableLog) { - $this->_enableLog = (boolean) $enableLog; - } - - /** - * 获得表前缀 - * @return string $tablePrefix - */ - public function getTablePrefix() { - return $this->_tablePrefix; - } - - /** - * 设置表前缀 - * @param string $tablePrefix - */ - public function setTablePrefix($tablePrefix) { - $this->_tablePrefix = $tablePrefix; - } -} -?> \ No newline at end of file diff --git a/wind/component/db/WindConnectionManager.php b/wind/component/db/WindConnectionManager.php deleted file mode 100644 index 7f79e1d5..00000000 --- a/wind/component/db/WindConnectionManager.php +++ /dev/null @@ -1,71 +0,0 @@ - - * - * mysql:host=localhost;dbname=test - * root - * root - * utf8 - * pw_ - * - * - * mysql:host=localhost;dbname=test - * root - * root - * utf8 - * pw_ - * - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindConnectionManager extends WindConnection { - /** - * 链接池 - * @var array - */ - private $connPool = array(); - - /* (non-PHPdoc) - * @see WindConnection::init() - */ - public function init() { - try { - $driverName = $this->getDriverName(); - $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; - $dbHandleClass = Wind::import($dbHandleClass); - $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, - (array) $this->_attributes); - $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->_dbHandle->setCharset($this->_charset); - if (WIND_DEBUG & 2) { - $reflection = new ReflectionClass(get_class($this)); - $properties = $reflection->getProperties(); - Wind::getApp()->getComponent('windLogger')->info( - "component.db.WindConnection.init() Initialize db connection success." . WindString::varToString( - $properties), 'component.db'); - } - } catch (PDOException $e) { - $this->close(); - throw new WindDbException($e->getMessage()); - } - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - if ($config) { - if (is_string($config)) - $config = Wind::getApp()->getComponent('configParser')->parse($config); - if (!empty($this->_config)) { - $this->_config = array_merge($this->_config, (array) $config); - } else - $this->_config = $config; - } - } -} \ No newline at end of file diff --git a/wind/component/db/WindResultSet.php b/wind/component/db/WindResultSet.php deleted file mode 100644 index 10548c2f..00000000 --- a/wind/component/db/WindResultSet.php +++ /dev/null @@ -1,165 +0,0 @@ - - * @version $Id$ - * @package - */ -class WindResultSet { - /** - * @var PDOStatement - */ - private $_statement = null; - /** - * PDO fetchMode, default fetchMode PDO::FETCH_ASSOC - * @var number - */ - private $_fetchMode = PDO::FETCH_ASSOC; - /** - * PDO fetchType, default fetchType PDO::FETCH_ORI_FIRST - * @var number - */ - private $_fetchType = PDO::FETCH_ORI_FIRST; - private $_columns = array(); - - /** - * 构造函数 - * - * @param WindSqlStatement $sqlStatement 预处理对象 - * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM - * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL - */ - public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) { - if ($sqlStatement instanceof WindSqlStatement) { - $this->_statement = $sqlStatement->getStatement(); - $this->_columns = $sqlStatement->getColumns(); - } else - $this->_statement = $sqlStatement; - if ($fetchMode != 0) - $this->_fetchMode = $fetchMode; - if ($fetchMode != 0) - $this->_fetchType = $fetchType; - } - - /** - * 设置获取模式 - * - * @param int $fetchMode 设置获取的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM... - * @param boolean $flush 是否统一设置所有PDOStatement中的获取方式 - */ - public function setFetchMode($fetchMode, $flush = false) { - $this->_fetchMode = $fetchMode; - if ($flush) { - $fetchMode = func_get_args(); - call_user_func_array(array($this->_statement, 'setFetchMode'), $fetchMode); - } - } - - /** - * 返回最后一条Sql语句的影响行数 - * - * @return int - */ - public function rowCount() { - return $this->_statement->rowCount(); - } - - /** - * 返回结果集中的列数 - * - * @return number - */ - public function columnCount() { - return $this->_statement->columnCount(); - } - - /** - * 获得结果集的下一行 - * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM - * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,设置Statement的属性设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL - * @return array - */ - public function fetch($fetchMode = 0, $fetchType = 0) { - if ($fetchMode === 0) - $fetchMode = $this->_fetchMode; - if ($fetchType === 0) - $fetchMode = $this->_fetchType; - return $this->_fetch($fetchMode, $fetchType); - } - - /** - * (non-PHPdoc) - * @see WindResult::fetch() - */ - private function _fetch($fetchMode, $fetchType) { - if (!empty($this->_columns)) - $fetchMode = PDO::FETCH_BOUND; - $result = array(); - if ($row = $this->_statement->fetch($fetchMode, $fetchType)) { - if (empty($this->_columns)) - $result = $row; - else - foreach ($this->_columns as $key => $value) { - $result[$key] = $value; - } - } - if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindResultSet._fetch] \r\n\tResult:" . WindString::varToString( - $result)); - - return $result; - } - - /** - * 返回所有的查询结果 - * - * @param string $index 输出数组下标 - * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM - * @return array - */ - public function fetchAll($index = '', $fetchMode = 0) { - if ($fetchMode === 0) - $fetchMode = $this->_fetchMode; - $result = array(); - if (!$index) - while ($row = $this->fetch($fetchMode)) - $result[] = $row; - else - while ($row = $this->fetch($fetchMode)) { - if (!isset($row[$index])) - continue; - $result[$row[$index]] = $row; - } - return $result; - } - - /** - * 从下一行记录中获得下标是$index的值,如果获取失败则返回false - * - * @param int $index 列下标 - * @return string|bool - */ - public function fetchColumn($index = 0) { - $result = $this->_statement->fetchColumn($index); - if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindResultSet.fetchColumn] \r\n\tResult:" . WindString::varToString( - $result)); - return $result; - } - - /** - * 获得结果集中的下一行,同时根据设置的类返回如果没有设置则返回的使StdClass对象 - * - * @param string $className 使用的类 - * @param array $ctor_args 初始化参数 - * @return object - */ - public function fetchObject($className = '', $ctor_args = array()) { - if ($className === '') - return $this->_statement->fetchObject(); - else - return $this->_statement->fetchObject($className, $ctor_args); - } -} -?> \ No newline at end of file diff --git a/wind/component/db/WindSqlStatement.php b/wind/component/db/WindSqlStatement.php deleted file mode 100644 index e3cfa7a2..00000000 --- a/wind/component/db/WindSqlStatement.php +++ /dev/null @@ -1,375 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindSqlStatement { - /** - * @var WindConnection - */ - private $_connection; - /** - * @var PDOStatement - */ - private $_statement = null; - /** - * sql语句字符串 - * - * @var string - */ - private $_queryString; - /** - * PDO类型映射 - * - * @var array - */ - private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, - 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); - private $_columns = array(); - - /** - * 构造函数 - * - * @param WindConnection $connection WindConnection对象 - * @param string $query 预定义语句 - */ - public function __construct($connection, $query) { - $this->_connection = $connection; - $this->setQueryString($query); - } - - /** - * 参数绑定 - * - * @param mixed $parameter 预定义语句的待绑定的位置 - * @param mixed &$variable 绑定的值 - * @param int $dataType 值的类型(PDO::PARAM_STR/PDO::PARAM_INT...) - * @param int $length 绑定值的长度 - * @param mixed $driverOptions - * @throws WindDbException - * @return WindSqlStatement - */ - public function bindParam($parameter, &$variable, $dataType = null, $length = null, $driverOptions = null) { - try { - $this->init(); - if ($dataType === null) { - $dataType = $this->_getPdoDataType($variable); - } - if ($length === null) - $this->getStatement()->bindParam($parameter, $variable, $dataType); - else - $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, - $driverOptions); - return $this; - } catch (PDOException $e) { - throw new WindDbException($e->getMessage()); - } - } - - /** - * 批量绑定变量 - * - * 如果是一维数组,则使用key=>value的形式,key代表变量位置,value代表替换的值,而替换值需要的类型则通过该值的类型来判断---不准确 - * 如果是一个二维数组,则允许,key=>array(0=>value, 1=>data_type, 2=>length, 3=>driver_options)的方式来传递变量。 - * - * @param array $parameters - * @throws WindDbException - * @return WindSqlStatement - */ - public function bindParams(&$parameters) { - if (!is_array($parameters)) - throw new WindDbException( - '[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype( - $parameters)); - - $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1)); - foreach ($parameters as $key => $value) { - $_key = $keied ? $key : $key + 1; - if (is_array($value)) { - $dataType = isset($value[1]) ? $value[1] : $this->_getPdoDataType($value[0]); - $length = isset($value[2]) ? $value[2] : null; - $driverOptions = isset($value[3]) ? $value[3] : null; - $this->bindParam($_key, $parameters[$key][0], $dataType, $length, $driverOptions); - } else - $this->bindParam($_key, $parameters[$key], $this->_getPdoDataType($value)); - } - return $this; - } - - /** - * 参数绑定 - * - * @param string $parameter 预定义语句的待绑定的位置 - * @param string $value 绑定的值 - * @param int $data_type 值的类型 - * @throws WindDbException - * @return WindSqlStatement - */ - public function bindValue($parameter, $value, $data_type = null) { - try { - $this->init(); - if ($data_type === null) - $data_type = $this->_getPdoDataType($value); - $this->getStatement()->bindValue($parameter, $value, $data_type); - return $this; - } catch (PDOException $e) { - throw new WindDbException($e->getMessage()); - } - } - - /** - * 调用bindValue的批量绑定参数 - * - * @param array $values 待绑定的参数值 - * @throws WindDbException - * @return WindSqlStatement - */ - public function bindValues($values) { - if (!is_array($values)) - throw new WindDbException( - '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type \'' . gettype( - $values) . '\''); - - $keied = (array_keys($values) !== range(0, sizeof($values) - 1)); - foreach ($values as $key => $value) { - if (!$keied) - $key = $key + 1; - $this->bindValue($key, $value, $this->_getPdoDataType($value)); - } - return $this; - } - - /** - * 绑定输出结果集的列到PHP变量 - * - * @param mixed $column 需要被绑定的字段列表,可以是字段名,也可以是字段的对应的下标 - * @param mixed &$param 需要被绑定的php变量 - * @param int $type 参数的数据类型 PDO::PARAM_* - * @param int $maxlen A hint for pre-allocation. - * @param mixed $driverdata Optional parameter(s) for the driver. - * @throws WindDbException - * @return WindSqlStatement - */ - public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $driverdata = null) { - try { - $this->init(); - if ($type == null) - $type = $this->_getPdoDataType($param); - if ($type == null) - $this->getStatement()->bindColumn($column, $param); - elseif ($maxlen == null) - $this->getStatement()->bindColumn($column, $param, $type); - else - $this->getStatement()->bindColumn($column, $param, $type, $maxlen, $driverdata); - $this->_columns[$column] = & $param; - return $this; - } catch (PDOException $e) { - throw new WindDbException($e->getMessage()); - } - } - - /** - * 批量绑定输出结果集的列到PHP变量 - * - * @param array $columns 待绑定的列 - * @param array &$param 需要绑定的php变量 - * @return WindSqlStatement - */ - public function bindColumns($columns, &$param = array()) { - $int = 0; - foreach ($columns as $value) { - $this->bindColumn($value, $param[$int++]); - } - return $this; - } - - /** - * 绑定参数,执行SQL语句,并返回更新影响行数 - * @param array $params 预定义语句中需要绑定的参数 - * @param boolean $rowCount 是否返回影响行数 - * @throws WindDbException - * @return int|boolean - */ - public function update($params = array(), $rowCount = false) { - return $this->execute($params, $rowCount); - } - - /** - * 绑定参数,执行SQL语句,并返回查询结果 - * - * @param array $params 预定义语句中需要绑定的参数 - * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM - * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL - * @return WindResultSet - */ - public function query($params = array(), $fetchMode = 0, $fetchType = 0) { - $this->execute($params, false); - return new WindResultSet($this, $fetchMode, $fetchType); - } - - /** - * 绑定参数,执行SQL语句,并返回查询结果 - * - * @param array $params 预定义语句中需要绑定的参数 - * @param string $index 返回的数组的下标对应的字段 - * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM - * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL - * @return array 返回处理后的结果 - */ - public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) { - $this->execute($params, false); - $rs = new WindResultSet($this, $fetchMode, $fetchType); - return $rs->fetchAll($index); - } - - /** - * 绑定参数,执行SQL语句,并返回查询到的结果集中某一个列的值 - * - * @param array $params 预定义语句中需要绑定的参数 - * @param int $column 列的下标,默认为0即第一列 - * @return string - */ - public function getValue($params = array(), $column = 0) { - $this->execute($params, false); - $rs = new WindResultSet($this, PDO::FETCH_NUM, 0); - return $rs->fetchColumn($column); - } - - /** - * 绑定参数,执行SQL语句,并返回一行查询结果 - * - * @param array $params 预定义语句中需要绑定的参数 - * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM - * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL - * @return array - */ - public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) { - $this->execute($params, false); - $rs = new WindResultSet($this, $fetchMode, $fetchType); - return $rs->fetch(); - } - - /* (non-PHPdoc) - * @see WindConnection::lastInsterId() - */ - public function lastInsertId($name = '') { - return $this->getConnection($name); - } - - /** - * 绑定参数,执行SQL语句,并返回影响行数 - * - * @param array $params -- 绑定的参数和bindValues的参数一样 - * @param boolean $rowCount 是否返回受印象行数 - * @return rowCount - */ - public function execute($params = array(), $rowCount = true) { - try { - if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->profileBegin( - 'SQL:execute sql statement.', 'component.db'); - $this->init(); - $this->bindValues($params); - $this->getStatement()->execute(); - $_result = $rowCount ? $this->getStatement()->rowCount() : true; - if (WIND_DEBUG & 2) { - Wind::getApp()->getComponent('windLogger')->profileEnd( - 'SQL:execute sql statement.', 'component.db'); - Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindSqlStatement.execute] \r\n\tSQL:" . $this->getQueryString(), - 'component.db'); - } - return $_result; - } catch (PDOException $e) { - throw new WindDbException('[component.db.WindSqlStatement.execute]' . $e->getMessage()); - } - } - - /** - * 设置查询预定义语句 - * - * @param string $queryString - * @return WindSqlStatement - */ - public function setQueryString($queryString) { - if (!$queryString) - return $this; - if ($_prefix = $this->getConnection()->getTablePrefix()) { - list($new, $old) = strpos($_prefix, '|') !== false ? explode('|', $_prefix) : array( - $_prefix, ''); - $queryString = preg_replace('/{(' . $old . ')?(.*?)}/', $new . '\2', $queryString); - } - $this->_queryString = $queryString; - return $this; - } - - /** - * 获得查询的预定义语句 - * - * @return string $_queryString - */ - public function getQueryString() { - return $this->_queryString; - } - - /** - * 获得PDO链接对象 - * - * @return WindConnection - */ - public function getConnection() { - return $this->_connection; - } - - /** - * 获得PDOStatement对象 - * - * @return PDOStatement - */ - public function getStatement() { - return $this->_statement; - } - - /** - * 获得需要绑定的结果输出的列值 - * - * @return array $_columns - */ - public function getColumns() { - return $this->_columns; - } - - /** - * 初始化数据库链接信息 - */ - public function init() { - if ($this->_statement === null) { - try { - $this->_statement = $this->getConnection()->getDbHandle()->prepare( - $this->getQueryString()); - if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindSqlStatement.init] Initialize statement success.", - 'component.db'); - } catch (PDOException $e) { - throw new WindDbException( - "Initialization WindSqlStatement failed." . $e->getMessage()); - } - } - } - - /** - * 获得绑定参数的类型 - * - * @param string $variable - * @return int - */ - private function _getPdoDataType($variable) { - return isset($this->_typeMap[gettype($variable)]) ? $this->_typeMap[gettype($variable)] : PDO::PARAM_STR; - } -} -?> \ No newline at end of file diff --git a/wind/component/db/drivers/mssql/WindMsSql.php b/wind/component/db/drivers/mssql/WindMsSql.php deleted file mode 100644 index af1e8674..00000000 --- a/wind/component/db/drivers/mssql/WindMsSql.php +++ /dev/null @@ -1,159 +0,0 @@ - 2010-11-18 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.drivers.AbstractWindDbAdapter'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindMsSql extends AbstractWindDbAdapter { - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#connect() - */ - protected function connect() { - if (!is_resource($this->connection) || ($this->config[IWindDbConfig::FORCE])) { - $host = isset($this->config[IWindDbConfig::PORT]) ? $this->config[IWindDbConfig::HOST] . ':' . $this->config[IWindDbConfig::PORT] : $this->config[IWindDbConfig::HOST]; - $user = $this->config[IWindDbConfig::USER]; - $pass = $this->config[IWindDbConfig::PASS]; - $pconnect = ('true' === $this->config[IWindDbConfig::PCONNECT] ); - $this->connection = $pconnect ? mssql_pconnect($host, $user, $pass) : mssql_connect($host, $user, $pass, $this->config[IWindDbConfig::FORCE]); - $this->changeDB($this->config[IWindDbConfig::NAME]); - } - return $this->connection; - } - - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#query() - */ - public function query($sql) { - $this->query = mssql_query($sql, $this->connection); - $this->error($sql); - return true; - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getAffectedRows() - */ - public function getAffectedRows() { - $this->query('SELECT @@ROWCOUNT AS affectedRow'); - $row = $this->getRow(); - return (int) $row['affectedRow']; - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getLastInsertId() - */ - public function getLastInsertId() { - $this->query('SELECT @@IDENTITY as insertId'); - $row = $this->getRow(); - return (int) $row['insertId']; - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getMetaTables() - */ - public function getMetaTables($schema = '') { - $schema = $schema ? $schema : $this->getSchema(); - if (empty($schema)) { - throw new WindSqlException('', WindSqlException::DB_EMPTY); - } - $this->query("SELECT name,object_id FROM {$schema}.sys.all_objects WHERE type = 'U'"); - return $this->getAllRow(IWindDbConfig::ASSOC); - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getMetaColumns() - */ - public function getMetaColumns($table) { - if (empty($table)) { - throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); - } - $this->query('SELECT b.name Field,b.max_length,b.precision,b.scale,b.is_nullable,b.is_identity FROM sys.objects a - INNER JOIN sys.all_columns b ON a.object_id = b.object_id - INNER JOIN sys.types c ON b.system_type_id = c.system_type_id where a.name = ' . $this->escapeString($table)); - return $this->getAllRow(IWindDbConfig::ASSOC); - } - - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#getAllRow() - */ - public function getAllRow($resultIndex = null,$fetch_type = IWindDbConfig::ASSOC) { - if (!is_resource($this->query)) { - throw new WindSqlException('', WindSqlException::DB_QUERY_LINK_EMPTY); - } - if (!in_array($fetch_type, array(1, 2, 3))) { - throw new WindSqlException('', WindSqlException::DB_QUERY_FETCH_ERROR); - } - $result = array(); - while (false !== ($record = mssql_fetch_array($this->query, $fetch_type))) { - if($resultIndex && isset($record[$resultIndex])){ - $result[$record[$resultIndex]] = $record; - }else{ - $result[] = $record; - } - } - return $result; - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getRow() - */ - public function getRow($fetch_type = IWindDbConfig::ASSOC) { - return mssql_fetch_array($this->query, $fetch_type); - } - - /** - *@see wind/component/db/base/WindDbAdapter#beginTrans() - */ - public function beginTrans() { - - } - - /** - * @see wind/component/db/base/WindDbAdapter#commitTrans() - */ - public function commitTrans() { - - } - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#close() - */ - public function close() { - if (is_resource($this->connection)) { - mssql_close($this->connection); - } - } - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#dispose() - */ - public function dispose() { - $this->close($this->connection); - $this->connection = null; - $this->query = null; - } - - /** - * 切换数据库 - * @see wind/base/WDbAdapter#changeDB() - * @param string $databse 要切换的数据库 - * @param string|int|resource $key 数据库连接标识 - * @return boolean - */ - public function changeDB($database) { - return mssql_select_db($database, $this->connection); - } - - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#error() - */ - protected function error($sql) { - $this->last_sql = $sql; - return true; - } -} \ No newline at end of file diff --git a/wind/component/db/drivers/mssql/WindMsSqlBuilder.php b/wind/component/db/drivers/mssql/WindMsSqlBuilder.php deleted file mode 100644 index 096d0bb4..00000000 --- a/wind/component/db/drivers/mssql/WindMsSqlBuilder.php +++ /dev/null @@ -1,93 +0,0 @@ - 2010-11-18 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.db.drivers.AbstractWindSqlBuilder'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindMsSqlBuilder extends AbstractWindSqlBuilder { - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getInsertSql() - */ - public function getInsertSql() { - $sql = sprintf('INSERT %s(%s) VALUES %s', $this->buildFrom(), $this->buildField(), $this->buildData()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getUpdateSql() - */ - public function getUpdateSql() { - $sql = sprintf('UPDATE %s SET %s%s%s', $this->buildFrom(), $this->buildSet(), $this->buildWhere(), $this->buildOrder()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getDeleteSql() - */ - public function getDeleteSql() { - $sql = sprintf('DELETE FROM %s%s%s', $this->buildFrom(), $this->buildWhere(), $this->buildOrder()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getSelectSql() - */ - public function getSelectSql() { - $sql = sprintf('SELECT %s%s FROM %s%s%s%s%s%s', $this->buildDistinct(), $this->buildField(), $this->buildFROM(), $this->buildJoin(), $this->buildWhere(), $this->buildGroup(), $this->buildHaving(), $this->buildOrder()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getReplaceSql() - */ - public function getReplaceSql() { - return ''; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getReplaceSql() - */ - public function getLastInsertIdSql() { - return sprintf('SELECT ' . '%s', '@@IDENTITY AS insertId'); - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getReplaceSql() - */ - public function getAffectedSql($ifquery = true) { - return sprintf('SELECT ' . '%s', '@@ROWCOUNT AS affectedRows'); - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getMetaTableSql() - */ - public function getMetaTableSql($schema) { - $schema = $schema ? $schema . '.' : ''; - return "SELECT name,object_id FROM {$schema}sys.all_objects WHERE type = 'U'"; - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindSqlBuilder#getMetaColumnSql() - */ - public function getMetaColumnSql($table) { - if (empty($table)) { - throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); - } - $sql = $this->from('sys.objects', 'a')->field('b.name Field,b.max_length,b.precision,b.scale,b.is_nullable,b.is_identity')->innerJoin('sys.all_columns', 'a.object_id = b.object_id', 'b')->innerJoin('sys.types', 'b.system_type_id = c.system_type_id', 'c')->where('a.name = ? ', $table)->getSelectSql(); - return $sql; - - } - -} \ No newline at end of file diff --git a/wind/component/db/drivers/mysql/WindMySql.php b/wind/component/db/drivers/mysql/WindMySql.php deleted file mode 100644 index 981d447a..00000000 --- a/wind/component/db/drivers/mysql/WindMySql.php +++ /dev/null @@ -1,207 +0,0 @@ - 2010-11-11 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.db.drivers.AbstractWindDbAdapter'); -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindMySql extends AbstractWindDbAdapter { - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#connect() - */ - protected function connect() { - if (!is_resource($this->connection) || $this->config[IWindDbConfig::FORCE]) { - $host = isset($this->config[IWindDbConfig::PORT]) ? $this->config[IWindDbConfig::HOST] . ':' . $this->config[IWindDbConfig::PORT] : $this->config[IWindDbConfig::HOST]; - $user = $this->config[IWindDbConfig::USER]; - $pass = $this->config[IWindDbConfig::PASS]; - $pconnect = ('true' === $this->config[IWindDbConfig::PCONNECT] ); - $this->connection = $pconnect ? mysql_pconnect($host, $user, $pass) : mysql_connect($host, $user, $pass, $this->config[IWindDbConfig::FORCE]); - $this->changeDB($this->config[IWindDbConfig::NAME]); - $this->setCharset($this->config[IWindDbConfig::CHARSET]); - } else { - $this->changeDB($this->config[IWindDbConfig::NAME]); - } - return $this->connection; - } - - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#query() - */ - public function query($sql) { - $this->query = mysql_query($sql, $this->connection); - $this->error($sql); - return true; - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getAffectedRows() - */ - public function getAffectedRows() { - return mysql_affected_rows($this->connection); - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getLastInsertId() - */ - public function getLastInsertId() { - return mysql_insert_id($this->connection); - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getMetaTables() - */ - public function getMetaTables($schema = '') { - $schema = $schema ? $schema : $this->getSchema(); - if (empty($schema)) { - throw new WindSqlException('', WindSqlException::DB_EMPTY); - } - $this->query('SHOW TABLES FROM ' . $schema); - return $this->getAllRow(IWindDbConfig::ASSOC); - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getMetaColumns() - */ - public function getMetaColumns($table) { - if (empty($table)) { - throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); - } - $this->query('SHOW COLUMNS FROM ' . $table); - return $this->getAllRow(IWindDbConfig::ASSOC); - } - - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#getAllRow() - */ - public function getAllRow($resultIndex = null,$fetch_type = IWindDbConfig::ASSOC) { - if (!is_resource($this->query)) { - throw new WindSqlException('', WindSqlException::DB_QUERY_LINK_EMPTY); - } - if (!in_array($fetch_type, array(1, 2, 3))) { - throw new WindSqlException('', WindSqlException::DB_QUERY_FETCH_ERROR); - } - $result = array(); - while (false !== ($record = mysql_fetch_array($this->query, $fetch_type))) { - if($resultIndex && isset($record[$resultIndex])){ - $result[$record[$resultIndex]] = $record; - }else{ - $result[] = $record; - } - } - return $result; - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#getRow() - */ - public function getRow($fetch_type = IWindDbConfig::ASSOC) { - return mysql_fetch_array($this->query, $fetch_type); - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindDbAdapter#beginTrans() - */ - public function beginTrans() { - if ($this->transCounter == 0) { - $this->query('START TRANSACTION'); - } elseif ($this->transCounter && $this->enableSavePoint) { - $savepoint = 'savepoint_' . $this->transCounter; - $this->query("SAVEPOINT `{$savepoint}`"); - array_push($this->savepoint, $savepoint); - } - ++$this->transCounter; - return true; - } - - /** - *@see wind/component/db/base/WindDbAdapter#commitTrans() - */ - public function commitTrans() { - if ($this->transCounter <= 0) { - throw new WindSqlException('', WindSqlException::DB_QUERY_TRAN_BEGIN); - } - --$this->transCounter; - if ($this->transCounter == 0) { - if ($this->last_errstr) { - $this->query('ROLLBACK'); - } else { - $this->query('COMMIT'); - } - } elseif ($this->enableSavePoint) { - $savepoint = array_pop($this->savepoint); - if ($this->last_errstr) { - $this->query("ROLLBACK TO SAVEPOINT `{$savepoint}`"); - } - } - } - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#close() - */ - public function close() { - if (is_resource($this->connection)) { - mysql_close($this->connection); - } - } - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#dispose() - */ - public function dispose() { - $this->close($this->connection); - $this->connection = null; - $this->query = null; - } - /** - * 取得mysql版本号 - * @param string|int|resource $key 数据库连接标识 - * @return string - */ - public function getVersion() { - return mysql_get_server_info($this->connection); - } - /** - * @param string $charset 字符集 - * @param string | int $key 数据库连接标识 - * @return boolean - */ - public function setCharset($charset) { - $version = (int) substr($this->getVersion(), 0, 1); - if ($version > 4) { - $this->query("SET NAMES '" . $charset . "'"); - } - return true; - } - - /** - * 切换数据库 - * @see wind/base/WDbAdapter#changeDB() - * @param string $databse 要切换的数据库 - * @param string|int|resource $key 数据库连接标识 - * @return boolean - */ - public function changeDB($database) { - return mysql_select_db($database, $this->connection); - } - - /* (non-PHPdoc) - * @see wind/base/WDbAdapter#error() - */ - protected function error($sql) { - $this->last_errstr = mysql_error(); - $this->last_errcode = mysql_errno(); - $this->last_sql = $sql; - if ($this->last_errstr || $this->last_errcode) { - $errInfo = 'This sql statement error has occurred:'.$this->last_sql.'.
'; - $errInfo .= 'Error Message:'.$this->last_errstr.'.
'; - throw new WindSqlException($errInfo, $this->last_errcode); - } - return true; - } - -} \ No newline at end of file diff --git a/wind/component/db/drivers/mysql/WindMySqlBuilder.php b/wind/component/db/drivers/mysql/WindMySqlBuilder.php deleted file mode 100644 index 3eebd80f..00000000 --- a/wind/component/db/drivers/mysql/WindMySqlBuilder.php +++ /dev/null @@ -1,99 +0,0 @@ - 2010-11-11 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.db.drivers.AbstractWindSqlBuilder'); -/** - * mysql常用sql语句组装器 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -final class WindMySqlBuilder extends AbstractWindSqlBuilder { - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getInsertSql() - */ - public function getInsertSql() { - $sql = sprintf('INSERT %s(%s) VALUES %s', $this->buildFrom(), $this->buildField(), $this->buildData()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getUpdateSql() - */ - public function getUpdateSql() { - $sql = sprintf('UPDATE %s SET %s%s%s%s', $this->buildFrom(), $this->buildSet(), $this->buildWhere(), $this->buildOrder(), $this->buildLimit()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getDeleteSql() - */ - public function getDeleteSql() { - $sql = sprintf('DELETE FROM %s%s%s%s', $this->buildFrom(), $this->buildWhere(), $this->buildOrder(), $this->buildLimit()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getSelectSql() - */ - public function getSelectSql() { - $sql = sprintf('SELECT %s%s FROM %s%s%s%s%s%s%s', $this->buildDistinct(), $this->buildField(), $this->buildFROM(), $this->buildJoin(), $this->buildWhere(), $this->buildGroup(), $this->buildHaving(), $this->buildOrder(), $this->buildLimit()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getReplaceSql() - */ - public function getReplaceSql() { - $sql = sprintf('REPLACE %s(%s) VALUES %s', $this->buildFROM(), $this->buildField(), $this->buildData()); - $this->reset(); - return $sql; - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getReplaceSql() - */ - public function getLastInsertIdSql() { - return sprintf('SELECT ' . '%s', 'LAST_INSERT_ID() AS insertId'); - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getReplaceSql() - */ - public function getAffectedSql($ifquery = true) { - $rows = $ifquery ? 'FOUND_ROWS()' : 'ROW_COUNT()'; - return sprintf('SELECT ' . '%s', "$rows AS afftectedRows"); - } - - /* (non-PHPdoc) - * @see wind/base/WSqlBuilder#getMetaTableSql() - */ - public function getMetaTableSql($schema) { - if (empty($schema)) { - throw new WindSqlException('', WindSqlException::DB_EMPTY); - } - return 'SHOW TABLES FROM ' . $schema; - } - - /* (non-PHPdoc) - * @see wind/component/db/base/WindSqlBuilder#getMetaColumnSql() - */ - public function getMetaColumnSql($table) { - if (empty($table)) { - throw new WindSqlException('', WindSqlException::DB_TABLE_EMPTY); - } - return 'SHOW COLUMNS FROM ' . $table; - } - -} - diff --git a/wind/component/db/exception/WindDbException.php b/wind/component/db/exception/WindDbException.php deleted file mode 100644 index 17a5813e..00000000 --- a/wind/component/db/exception/WindDbException.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @version $Id$ - * @package - */ -class WindDbException extends WindException { - - /** - * 连接相关的异常 - * @var unknown_type - */ - const DB_CONN_EMPTY = 200; - - const DB_CONN_FORMAT = 201; - - const DB_CONN_NOT_EXIST = 202; - - const DB_CONN_EXIST = 203; - - const DB_CONNECT_NOT_EXIST = 204; - - /** - * 查讯 相关的异常 - * @var unknown_type - */ - const DB_QUERY_EMPTY = 210; - - const DB_QUERY_LINK_EMPTY = 211; - - const DB_QUERY_FIELD_EMPTY = 212; - - const DB_QUERY_FIELD_EXIST = 213; - - const DB_QUERY_FIELD_FORMAT = 214; - - const DB_QUERY_INSERT_DATA = 215; - - const DB_QUERY_UPDATE_DATA = 216; - - const DB_QUERY_CONDTTION_FORMAT = 217; - - const DB_QUERY_GROUP_MATCH = 218; - - const DB_QUERY_LOGIC_MATCH = 219; - - const DB_QUERY_FETCH_ERROR = 220; - - const DB_QUERY_TRAN_BEGIN = 221; - - const DB_QUERY_COMPARESS_ERROR = 222; - - const DB_QUERY_COMPARESS_EXIST = 223; - - const DB_QUERY_WHERE_ERROR = 224; - - const DB_QUERY_JOIN_TYPE_ERROR = 225; - - /** - * 字段异常 - * @var unknown_type - */ - const DB_TABLE_EMPTY = 240; - - const DB_EMPTY = 241; - - const DB_DRIVER_NOT_EXIST = 242; - - const DB_DRIVER_EXIST = 243; - - const DB_BUILDER_NOT_EXIST = 250; - - const DB_BUILDER_EXIST = 251; - - const DB_DRIVER_BUILDER_NOT_MATCH = 252; - - const DB_ADAPTER_NOT_EXIST = 260; - - const DB_ADAPTER_EXIST = 261; - - /** - * 重定义异常类型 - * - * @see WindException::messageMapper() - * @param int $code 异常号 - * @return string 最终输出异常信息的原型 - */ - protected function messageMapper($code) { - $messages = array(self::DB_CONN_EMPTY => 'Database configuration is empty. \'$message\' ', - self::DB_CONN_FORMAT => 'Database configuration format is incorrect. \'$message\' ', - self::DB_CONN_NOT_EXIST => '\'$message\' The identify of the database connection does not exist. ', - self::DB_CONN_EXIST => '\'$message\' The identify of the database connection is aleady exist.', - self::DB_CONNECT_NOT_EXIST => '\'$message\' The database connection does not exist.', - self::DB_QUERY_EMPTY => 'Query is empty. \'$message\'', - self::DB_QUERY_LINK_EMPTY => '\'$message\' Query link is not a validate resource.', - self::DB_QUERY_FIELD_EMPTY => '\'$message\' Query field is empty.', - self::DB_QUERY_FIELD_EXIST => '\'$message\' Query field is not exist.', - self::DB_QUERY_FIELD_FORMAT => 'Inside the field in the query not formatted correctly. \'$message\'', - self::DB_QUERY_INSERT_DATA => 'The new data is empty. \'$message\'', - self::DB_QUERY_UPDATE_DATA => 'The Updated data is empty. \'$message\'', - self::DB_QUERY_CONDTTION_FORMAT => 'The conditions of query are not right. \'$message\'', - self::DB_QUERY_GROUP_MATCH => '\'$message\' Query group does not match.', - self::DB_QUERY_LOGIC_MATCH => '\'$message\' Query logic does not match.', - self::DB_QUERY_FETCH_ERROR => 'The wrong way to obtain the result set. \'$message\'', - self::DB_QUERY_TRAN_BEGIN => 'Transaction has not started. \'$message\'', - self::DB_QUERY_COMPARESS_ERROR => 'Query comparison is incorrect conversion or assembly. \'$message\'', - self::DB_QUERY_COMPARESS_EXIST => 'Comparison does not exist query. \'$message\'', - self::DB_QUERY_WHERE_ERROR => 'Query where is Error. \'$message\'', - self::DB_QUERY_JOIN_TYPE_ERROR => 'The database is wrong type of join query. \'$message\'', - self::DB_TABLE_EMPTY => 'Table is empty. \'$message\'', - self::DB_EMPTY => 'Database is empty. \'$message\'', - self::DB_DRIVER_NOT_EXIST => 'The database driver does not exist. \'$message\'', - self::DB_DRIVER_EXIST => 'The database driver is aleady exist. \'$message\'', - self::DB_BUILDER_NOT_EXIST => 'The database builder does not exist. \'$message\'', - self::DB_BUILDER_EXIST => 'The database builder is aleady exist. \'$message\'', - self::DB_ADAPTER_NOT_EXIST => 'The database adapter does not exist. \'$message\'', - self::DB_ADAPTER_EXIST => 'The database adapter is aleady exist. \'$message\'', - self::DB_DRIVER_BUILDER_NOT_MATCH => '\'$message\' The database driver does not match with the builder. '); - return isset($messages[$code]) ? $messages[$code] : '$message'; - } -} -?> \ No newline at end of file diff --git a/wind/component/db/mysql/WindMysqlPdoAdapter.php b/wind/component/db/mysql/WindMysqlPdoAdapter.php deleted file mode 100644 index 719ab15f..00000000 --- a/wind/component/db/mysql/WindMysqlPdoAdapter.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindMysqlPdoAdapter extends PDO { - - /** - * 创建表 - * @param $tableName - * @param $values - */ - public function createTable($tableName, $values, $engine, $charset, $autoIncrement) { - $_sql = "CREATE TABLE IF NOT EXISTS $tableName ($values)ENGINE="; - $_sql .= $engine ? $engine : 'MyISAM'; - $_sql .= $charset ? " DEFAULT CHARSET=$charset" : ''; - $_sql .= $autoIncrement ? " AUTO_INCREMENT=$autoIncrement" : ''; - return $this->query($_sql); - } - - /** - * 设置链接使用字符集 - * @param string $charset - */ - public function setCharset($charset) { - if (!$charset) $charset = 'gbk'; - $this->query("set names " . $this->quote($charset) . ";"); - } - - /** - * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组 - * example: - * array('a','b','c') => ('a','b','c') - * array(array('a1','b1','c1'),array('a2','b2','c2')) - * => ('a1','b1','c1'),('a2','b2','c2') - * @param array $variable - * @param string $result - */ - public function filterArray($variable, $result = '') { - if (empty($variable) || !is_array($variable)) return; - $_result = ''; - foreach ($variable as $key => $value) { - if (is_array($value)) - $result = $this->filterArray($value, $result); - else { - $_result .= $this->quote($value) . ','; - } - } - if ($_result) { - $result .= $result ? ',(' . trim($_result, ',') . ')' : '(' . trim($_result, ',') . ')'; - } - return $result; - } - - /** - * 组装单条 key=value 形式的SQL查询语句值 insert/update - * @param $array - * @param $strip - * @return string - */ - public function sqlSingle($array) { - if (!is_array($array)) return ''; - $str = ''; - foreach ($array as $key => $val) { - $str .= ($str ? ', ' : ' ') . $this->fieldMeta($key) . '=' . $this->quote($val); - } - return $str; - } - - /** - * 过滤SQL元数据,数据库对象(如表名字,字段等) - * @param $data 元数据 - * @return string 经过转义的元数据字符串 - */ - private function fieldMeta($data) { - $data = str_replace(array('`', ' '), '', $data); - return ' `' . $data . '` '; - } -} -?> \ No newline at end of file diff --git a/wind/component/ftp/AbstractWindFtp.php b/wind/component/ftp/AbstractWindFtp.php deleted file mode 100644 index 31ef366c..00000000 --- a/wind/component/ftp/AbstractWindFtp.php +++ /dev/null @@ -1,185 +0,0 @@ - - * @author xiaoxiao - * @version 2011-8-1 xiaoxiao - */ -abstract class AbstractWindFtp { - protected $server = ''; - protected $port = 21; - protected $user = ''; - protected $pwd = ''; - protected $dir = ''; - protected $timeout = 10; - protected $rootPath = ''; - - protected $conn = null; - /** - * 初始化配置信息 - * @param array $config - * @return bool - */ - public function initConfig($config) { - if (!$config || !is_array($config)) return false; - isset($config['server']) && $this->server = $config['server']; - isset($config['port']) && $this->port = $config['port']; - isset($config['user']) && $this->user = $config['user']; - isset($config['pwd']) && $this->pwd = $config['pwd']; - isset($config['dir']) && $this->dir = $config['dir']; - isset($config['timeout']) && $this->timeout = $config['timeout']; - return true; - } - - /** - * 重命名文件 - * @param string $oldName - * @param string $newName - * @return boolean - */ - abstract public function rename($oldName, $newName); - /** - * 删除文件 - * @param string $filename - * @return boolean - */ - abstract public function delete($filename); - /** - * 上传文件 - * @param string $sourceFile - * @param string $desFile - * @param string $mode - * @return mixed - */ - abstract public function upload($sourceFile, $desFile, $mode); - /** - * 下载文件 - * @param string $filename - * @param string $localname - * @param string $mode - * @return string - */ - abstract public function download($filename); - /** - * 列出文件列表 - * @param string $dir - * @return array - */ - abstract public function fileList($dir = ''); - /** - * 关闭链接 - * @return boolean - */ - abstract public function close(); - - /** - * 传建文件夹 - * @param string $dir - * @return boolean - */ - abstract public function mkdir($dir); - - /** - * 更改当前目录 - * @param string $dir - * @return boolean - */ - abstract public function changeDir($dir); - - /** - * 获得文件大小 - * @param string $file - * @return boolean - */ - abstract public function size($file); - - /** - * 获得当前路径 - * @return string - */ - abstract protected function pwd(); - - /** - * 级联创建文件夹 - * @param string $dir - * @param string $permissions - * @return boolean - */ - public function mkdirs($dir, $permissions = 0777) { - $dir = explode('/', WindSecurity::escapeDir($dir)); - $dirs = ''; - $result = false; - $count = count($dir); - for ($i = 0; $i < $count; $i++) { - if (strpos($dir[$i], '.') === 0) continue; - $result = $this->mkdir($dir[$i], $permissions); - $this->changeDir($this->rootPath . $dirs . $dir[$i]); - $dirs .= "$dir[$i]/"; - } - $this->changeDir($this->rootPath); - return $result; - } - - - /** - * 检查文件是否存在 - * @param string $filename - * @return boolean - */ - public function file_exists($filename) { - $directory = substr($filename, 0, strrpos($filename, '/')); - $filename = str_replace("$directory/", '', $filename); - if ($directory) { - $directory = $this->rootPath . $directory . '/'; - } else { - $directory = $this->rootPath; - } - $this->changeDir($directory); - $list = $this->fileList(); - $this->changeDir($this->rootPath); - if (!empty($list) && in_array($filename, $list)) return true; - return false; - } - - /** - * 初始化根目录信息 - */ - protected function initRootPath() { - $this->rootPath = $this->pwd(); - if ($this->dir) { - $this->rootPath .= trim(str_replace('\\', '/', $this->dir), '/') . '/'; - } - $this->changeDir($this->rootPath); - } - - /** - * 检查文件 - * @param string $filename - * @return boolean - */ - protected function checkFile($filename) { - return (str_replace(array('..', '.php.'), '', $filename) != $filename || preg_match('/\.php$/i', $filename)); - } - - /** - * 获得文件后缀 - * - * @param string - * @return string - */ - protected function getExt($filename){ - if (false === strpos($filename, '.')) return 'txt'; - $x = explode('.', $filename); - return strtolower(end($x)); - } - - /** - * 显示错误信息 - * @param string $str - */ - protected function showError($str, $close = true) { - $close && $this->close(); - exit($str); - } -} \ No newline at end of file diff --git a/wind/component/ftp/WindFtp.php b/wind/component/ftp/WindFtp.php deleted file mode 100644 index 76959bc0..00000000 --- a/wind/component/ftp/WindFtp.php +++ /dev/null @@ -1,186 +0,0 @@ - - * author xiaoxiao - * version 2011-7-29 xiaoxiao - */ -class WindFtp extends AbstractWindFtp { - - /** - * 被动模式是否开启 - * var boolean - */ - private $isPasv = true; - - public function __construct($config = array()) { - $this->connection($config); - } - - private function connection($config = array()) { - $this->initConfig($config); - if (false === ($this->conn = ftp_connect($this->server, $this->port, $this->timeout))) { - $this->showError('The ftp ' . $this->server . ' cann\'t connection!'); - } - if (false == ftp_login($this->conn, $this->user, $this->pwd)) { - $this->showError('Login error: ' . $this->user); - } - if ($this->isPasv) { - ftp_pasv($this->conn, true); - } - $this->initRootPath(); - return true; - } - - /** - * 获得链接 - * return object - */ - private function getFtp() { - if (is_resource($this->conn)) return $this->conn; - $this->connection(); - return $this->conn; - } - - /** - * (non-PHPdoc) - * see AbstractWindFtp::rename() - */ - public function rename($oldName, $newName) { - return ftp_rename($this->getFtp(), $oldName, $newName); - } - - /* - * (non-PHPdoc) - * see AbstractWindFtp::delete() - */ - public function delete($filename) { - return ftp_delete($this->getFtp(), $filename); - } - - /** - * (non-PHPdoc) - * see AbstractWindFtp::upload() - */ - public function upload($sourceFile, $desFile, $mode) { - $mode = $this->getMode($sourceFile, $mode); - if (!in_array(($savedir = dirname($desFile)), array('.', '/'))) { - $this->mkdirs($savedir); - } - $desFile = $this->rootPath . WindSecurity::escapeDir($desFile); - $result = ftp_put($this->getFtp(), $desFile, $sourceFile, $mode); - if (false === $result) return false; - $this->chmod($desFile, 0644); - return $this->size($desFile); - } - - /** - * 从服务器上将文件$filename读取到本地的localname文件中 - * (non-PHPdoc) - * see AbstractWindFtp::download() - */ - public function download($filename, $localname = '', $mode = 'auto') { - $mode = $this->getMode($filename, $mode); - return ftp_get($this->getFtp(), $localname, $filename, $mode); - } - - /* - * (non-PHPdoc) - * see AbstractWindFtp::fileList() - */ - public function fileList($dir = '') { - return ftp_nlist($this->getFtp(), $dir); - } - - /* - * (non-PHPdoc) - * see AbstractWindFtp::close() - */ - public function close() { - is_resource($this->conn) && ftp_close($this->conn); - $this->conn = null; - return true; - } - - /* - * (non-PHPdoc) - * see AbstractWindFtp::initConfig() - */ - public function initConfig($config) { - if (!$config || !is_array($config)) return false; - parent::initConfig($config); - isset($config['ispasv']) && $this->isPasv = $config['ispasv']; - } - - /* - * (non-PHPdoc) - * see AbstractWindFtp::mkdir() - */ - public function mkdir($dir, $permissions = 0777) { - $result = ftp_mkdir($this->getFtp(), $dir); - if (!$result) return false; - return $this->chmod($result, $permissions); - } - - /** - * 赋权限 - * param string $file - * param int $permissions - * return boolean - */ - private function chmod($file, $permissions = 0777) { - return ftp_chmod($this->getFtp(), $permissions, $file); - } - - /* - * (non-PHPdoc) - * see AbstractWindFtp::pwd() - */ - protected function pwd() { - return ftp_pwd($this->getFtp()) . '/'; - } - - /* - * (non-PHPdoc) - * see AbstractWindFtp::changeDir() - */ - public function changeDir($dir) { - return ftp_chdir($this->getFtp(), $dir); - } - - /* - * (non-PHPdoc) - * see AbstractWindFtp::size() - */ - public function size($file) { - return ftp_size($this->getFtp(), $file); - } - - /** - * 获得后缀和模式 - * param string $filename - * param string $mode - * return string - */ - private function getMode($filename, $mode) { - $ext = $this->getExt($filename); - $mode = strtolower($mode); - if ($mode == 'auto') { - $ext = $this->getExt($filename); - $mode = $this->getModeMap($ext); - } - return (strtolower($mode) == 'ascii') ? FTP_ASCII : FTP_BINARY; - } - - /** - * 获得文件操作模式 - * param string - * return string - */ - private function getModeMap($ext){ - $exts = array('txt', 'text', 'php', 'phps', 'php4', 'js', 'css', - 'htm', 'html', 'phtml', 'shtml', 'log', 'xml'); - return (in_array($ext, $exts)) ? 'ascii' : 'binary'; - } -} \ No newline at end of file diff --git a/wind/component/ftp/WindSocketFtp.php b/wind/component/ftp/WindSocketFtp.php deleted file mode 100644 index 1719a0a9..00000000 --- a/wind/component/ftp/WindSocketFtp.php +++ /dev/null @@ -1,274 +0,0 @@ - - * author xiaoxiao - * version 2011-7-29 xiaoxiao - */ -@set_time_limit(1000); -class WindSocketFtp extends AbstractWindFtp { - private $tmpConnection; - - public function __construct($config = array()) { - $this->getConnection($config); - } - - /** - * 获得ftp链接 - * @param array $config - */ - private function getConnection($config) { - $this->initConfig($config); - $errno = 0; - $errstr = ''; - $this->conn = fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout); - if (!$this->conn || !$this->checkcmd()) { - $this->showError('ftp_connect_failed'); - } - stream_set_timeout($this->conn, $this->timeout); - - if (!$this->sendcmd('USER', $this->user)) { - $this->showError('ftp_user_failed'); - } - if (!$this->sendcmd('PASS', $this->pwd)) { - $this->showError('ftp_pass_failed'); - } - - $this->initRootPath(); - return true; - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::pwd() - */ - protected function pwd() { - $this->sendcmd('PWD', '', false); - if (!($path = $this->checkcmd(true)) || !preg_match("/^[0-9]{3} \"(.+?)\"/", $path, $matchs)) { - return '/'; - } - return $matchs[1] . ((substr($matchs[1], -1) == '/') ? '' : '/'); - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::upload() - */ - public function upload($localfile, $remotefile, $mode) { - if ($this->checkFile($localfile)) { - $this->showError("Error:illegal file type!({$localfile})"); - } - if ($this->checkFile($remotefile)) { - $this->showError("Error:illegal file type!({$remotefile})"); - } - if (!in_array(($savedir = dirname($remotefile)), array('.', '/'))) { - $this->mkdirs($savedir); - } - $remotefile = $this->rootPath . WindSecurity::escapeDir($remotefile); - if (!($fp = fopen($localfile, 'rb'))) { - $this->showError("Error:Cannot read file \"$localfile\""); - } - // 'I' == BINARY mode - // 'A' == ASCII mode - $mode != 'I' && $mode = 'A'; - $this->delete($remotefile); - if (!$this->sendcmd('TYPE', $mode)) { - $this->showError('Error:TYPE command failed'); - } - $this->openTmpConnection(); - $this->sendcmd('STOR', $remotefile); - while (!feof($fp)) { - fwrite($this->tmpConnection, fread($fp, 4096)); - } - fclose($fp); - $this->closeTmpConnection(); - - if (!$this->checkcmd()) { - $this->showError('Error:PUT command failed'); - } else { - $this->sendcmd('SITE CHMOD', base_convert(0644, 10, 8) . " $remotefile"); - } - return $this->size($remotefile); - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::download() - */ - public function download($localfile, $remotefile = '', $mode = 'I') { - if ($this->checkFile($localfile)) { - $this->showError("Error:illegal file type!({$localfile})"); - } - if ($this->checkFile($remotefile)) { - $this->showError("Error:illegal file type!({$remotefile})"); - } - $mode != 'I' && $mode = 'A'; - if (!$this->sendcmd('TYPE', $mode)) { - $this->showError('Error:TYPE command failed'); - } - $this->openTmpConnection(); - if (!$this->sendcmd('RETR', $remotefile)) { - $this->closeTmpConnection(); - return false; - } - if (!($fp = fopen($localfile, 'wb'))) { - $this->showError("Error:Cannot read file \"$localfile\""); - } - while (!feof($this->tmpConnection)) { - fwrite($fp, fread($this->tmpConnection, 4096)); - } - fclose($fp); - $this->closeTmpConnection(); - - if (!$this->checkcmd()) $this->showError('Error:GET command failed'); - return true; - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::size() - */ - public function size($file) { - $this->sendcmd('SIZE', $file, false); - if (!($size_port = $this->checkcmd(true))) { - $this->showError('Error:Check SIZE command failed'); - } - return preg_replace("/^[0-9]{3} ([0-9]+)\r\n/", "\\1", $size_port); - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::delete() - */ - public function delete($file) { - return $this->sendcmd('DELE', $this->rootPath . WindSecurity::escapeDir($file)); - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::rename() - */ - public function rename($oldname, $newname) { - if (!in_array(($savedir = dirname($newname)), array('.', '/'))) { - $this->mkdirs($savedir); - } - $oldname = $this->rootPath . WindSecurity::escapeDir($oldname); - $this->sendcmd('RNFR', $oldname); - return $this->sendcmd('RNTO', $newname); - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::mkdir() - */ - public function mkdir($dir) { - $base777 = base_convert(0777, 10, 8); - $result = $this->sendcmd('MKD', $dir); - return $this->sendcmd('SITE CHMOD', "$base777 $dir"); - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::changeDir() - */ - public function changeDir($dir) { - $dir = (($dir[0] != '/') ? '/' : '') . $dir; - if ($dir !== '/' && substr($dir, -1) == '/') { - $dir = substr($dir, 0, -1); - } - if (!$this->sendcmd('CWD', $dir)) { - $this->showError('ftp_cwd_failed'); - } - return true; - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::fileList() - */ - public function fileList($dir = '') { - $this->openTmpConnection(); - $this->sendcmd('NLST', $dir); - $list = array(); - while (!feof($this->tmpConnection)) { - $list[] = preg_replace('/[\r\n]/', '', fgets($this->tmpConnection, 512)); - } - $this->closeTmpConnection(); - if (!$this->checkcmd(true)) $this->showError('Error:LIST command failed'); - return $list; - } - - /* - * (non-PHPdoc) - * @see AbstractWindFtp::close() - */ - public function close() { - if (!$this->conn) return false; - if (!$this->sendcmd('QUIT') || !fclose($this->conn)) $this->showError('Error:QUIT command failed', false); - return true; - } - - /** - * 发送命令 - * @param string $cmd - * @param string $args - * @param boolean $check - * @return boolean - */ - private function sendcmd($cmd, $args = '', $check = true) { - !empty($args) && $cmd .= " $args"; - fputs($this->conn, "$cmd\r\n"); - if ($check === true && !$this->checkcmd()) return false; - return true; - } - - /** - * 检查命令状态 - * @param boolean $return - * @return boolean - */ - private function checkcmd($return = false) { - $resp = $rcmd = ''; - $i = 0; - do { - $rcmd = fgets($this->conn, 512); - $resp .= $rcmd; - } while (++$i < 20 && !preg_match('/^\d{3}\s/is', $rcmd)); - - if (!preg_match('/^[123]/', $rcmd)) return false; - return $return ? $resp : true; - } - - /** - * 链接临时句柄 - * @return boolean - */ - private function openTmpConnection() { - $this->sendcmd('PASV', '', false); - if (!($ip_port = $this->checkcmd(true))) { - $this->showError('Error:Check PASV command failed'); - } - if (!preg_match('/[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+/', $ip_port, $temp)) { - $this->showError("Error:Illegal ip-port format($ip_port)"); - } - $temp = explode(',', $temp[0]); - $server_ip = "$temp[0].$temp[1].$temp[2].$temp[3]"; - $server_port = $temp[4] * 256 + $temp[5]; - if (!$this->tmpConnection = fsockopen($server_ip, $server_port, $errno, $errstr, $this->timeout)) { - $this->showError("Error:Cannot open data connection to $server_ip:$server_port
Error:$errstr ($errno)"); - } - stream_set_timeout($this->tmpConnection, $this->timeout); - return true; - } - - /** - * 关闭临时链接对象 - * @return boolean - */ - private function closeTmpConnection() { - return fclose($this->tmpConnection); - } -} -?> \ No newline at end of file diff --git a/wind/component/log/WindDebug.php b/wind/component/log/WindDebug.php deleted file mode 100644 index 6eb0963d..00000000 --- a/wind/component/log/WindDebug.php +++ /dev/null @@ -1,175 +0,0 @@ - 2010-11-3 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -defined('RUNTIME_START') or define('RUNTIME_START', microtime(true)); -defined('USEMEM_START') or define('USEMEM_START', memory_get_usage()); -/** - * 调试工具 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindDebug { - - /** - * @var array 调试点 - */ - private static $breakpoint = array(); - /** - * @var int 保留的小数位数 - */ - const DECIMAL_DIGITS = 4; - - /** - * @var int 记录内存使用标记 - */ - const MEMORY = 'mem'; - /** - * @var int 记录程序运行时时间使用标记 - */ - const RUN_TIME = 'time'; - /** - * 设置调试点 - * @param string $point 调试点 - */ - public static function setBreakPoint($point = '') { - if (isset(self::$breakpoint[$point])) - return false; - self::$breakpoint[$point][self::RUN_TIME] = microtime(true); - self::$breakpoint[$point][self::MEMORY] = memory_get_usage(); - return true; - } - /** - * 移除调试点 - * @param string $point 调试点 - */ - public static function removeBreakPoint($point = '') { - if ($point) { - if (isset(self::$breakpoint[$point])) - unset(self::$breakpoint[$point]); - } else { - self::$breakpoint = array(); - } - } - - /** - * 取得系统运行所耗内存 - */ - public static function getMemUsage() { - $useMem = memory_get_usage() - USEMEM_START; - return $useMem ? round($useMem / 1024, self::DECIMAL_DIGITS) : 0; - } - - /** - * 取得系统运行所耗时间 - */ - public static function getExecTime() { - $useTime = microtime(true) - RUNTIME_START; - return $useTime ? round($useTime, self::DECIMAL_DIGITS) : 0; - } - - /** - * 获取调试点 - * @param $point - * @param $label - */ - public static function getBreakPoint($point, $label = '') { - if (!isset(self::$breakpoint[$point])) - return array(); - return $label ? self::$breakpoint[$point][$label] : self::$breakpoint[$point]; - } - - /** - * 调试点之间系统运行所耗内存 - * @param string $beginPoint 开始调试点 - * @param string $endPoint 结束调试点 - * @return float - */ - public static function getMemUsageOfp2p($beginPoint, $endPoint = '') { - if (!isset(self::$breakpoint[$beginPoint])) - return 0; - $endMemUsage = isset(self::$breakpoint[$endPoint]) ? self::$breakpoint[$endPoint][self::MEMORY] : memory_get_usage(); - $useMemUsage = $endMemUsage - self::$breakpoint[$beginPoint][self::MEMORY]; - return round($useMemUsage / 1024, self::DECIMAL_DIGITS); - } - - /** - * 调试点之间的系统运行所耗时间 - * @param string $beginPoint 开始调试点 - * @param string $endPoint 结束调试点 - * @return float - */ - public static function getExecTimeOfp2p($beginPoint, $endPoint = '') { - if (!isset(self::$breakpoint[$beginPoint])) - return 0; - $endTime = self::$breakpoint[$endPoint] ? self::$breakpoint[$endPoint][self::RUN_TIME] : microtime(true); - $useTime = $endTime - self::$breakpoint[$beginPoint][self::RUN_TIME]; - return round($useTime, self::DECIMAL_DIGITS); - } - - /** - * 堆栈情况 - * @param array $trace 堆栈引用,如异常 - * @return array - */ - public static function trace($trace = array()) { - $debugTrace = $trace ? $trace : debug_backtrace(); - $traceInfo = array(); - foreach ($debugTrace as $info) { - $info['args'] = self::traceArgs($info['args']); - $file = isset($info['file']) ? $info['file'] : ''; - $line = isset($info['line']) ? $info['line'] : ''; - $str = '[' . date("Y-m-d H:i:m") . '] ' . $file . ' (line:' . $line . ') '; - $str .= $info['class'] . $info['type'] . $info['function'] . '('; - $str .= implode(', ', $info['args']); - $str .= ")"; - $traceInfo[] = $str; - } - return $traceInfo; - } - /** - * 获取系统所加载的文件 - */ - public static function loadFiles() { - return get_included_files(); - } - - public static function debug($message = '', $trace = array(), $begin = '', $end = '') { - $runtime = self::getExecTime(); - $useMem = self::getMemUsage(); - $separate = "
"; - $trace = implode("{$separate}", self::trace($trace)); - $debug = ''; - $debug .= "{$message}{$separate}"; - $debug .= "Runtime:{$runtime}s{$separate}"; - $debug .= "Memory consumption:{$useMem}byte{$separate}"; - $debug .= "Stack conditions:{$separate}{$trace}{$separate}"; - if ($begin && $end) { - $PointUseTime = self::getExecTimeOfp2p($begin, $end); - $PointUseMem = self::getMemUsageOfp2p($begin, $end); - $debug .= "Between points {$begin} and {$end} debugging system conditions:{$separate}"; - $debug .= "Runtime:{$PointUseTime}s{$separate}"; - $debug .= "Memory consumption:{$PointUseMem}byte{$separate}"; - } - return $debug; - } - - private static function traceArgs($args = array()) { - foreach ($args as $key => $arg) { - if (is_array($arg)) - $args[$key] = 'array(' . implode(',', $arg) . ')'; - elseif (is_object($arg)) - $args[$key] = 'class ' . get_class($arg); - else - $args[$key] = $arg; - } - return $args; - } - -} -?> \ No newline at end of file diff --git a/wind/component/log/WindLogger.php b/wind/component/log/WindLogger.php deleted file mode 100644 index 60dac919..00000000 --- a/wind/component/log/WindLogger.php +++ /dev/null @@ -1,386 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - */ -class WindLogger extends WindModule { - const LEVEL_INFO = 1; - const LEVEL_TRACE = 2; - const LEVEL_DEBUG = 3; - const LEVEL_ERROR = 4; - const LEVEL_PROFILE = 5; - const WRITE_TYPE = 2; - const WRITE_LEVEL = 1; - const TOKEN_BEGIN = 'begin:'; - const TOKEN_END = 'end:'; - /** - * 每次当日志数量达到100的时候,就写入文件一次 - * @var int - */ - private $_autoFlush = 1000; - private $_logs = array(); - private $_logCount = 0; - private $_profiles = array(); - private $_logDir; - private $_maxFileSize = 100; - /** - * 0: 打印全部日志信息结果 - * 1: 按照level分文件存储日志记录 - * 2: 按照type分文件存储日志记录 - * @var int - */ - private $_writeType = 0; - private $_types = array(); - private $_levelMap = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error'); - - /** - * @param string $logDir - * @param int $writeType - */ - public function __construct($logDir = '', $writeType = 0) { - $this->setLogDir($logDir); - $this->_writeType = $writeType; - } - - /** - * 添加info级别的日志信息 - * @param string $msg - */ - public function info($msg, $type = 'wind.system', $flush = false) { - $this->log($msg, self::LEVEL_INFO, $type, $flush); - } - - /** - * 添加trace级别的日志信息 - * @param string $msg - */ - public function trace($msg, $type = 'wind.system', $flush = false) { - $this->log($msg, self::LEVEL_TRACE, $type, $flush); - } - - /** - * 添加debug的日志信息 - * @param string $msg - */ - public function debug($msg, $type = 'wind.system', $flush = false) { - $this->log($msg, self::LEVEL_DEBUG, $type, $flush); - } - - /** - * 添加Error级别的日志信息 - * @param string $msg - */ - public function error($msg, $type = 'wind.core', $flush = false) { - $this->log($msg, self::LEVEL_ERROR, $type, $flush); - } - - /** - * @param $msg - * @param $type - */ - public function profileBegin($msg, $type = 'wind.core', $flush = false) { - $this->log('begin:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); - } - - /** - * @param $msg - * @param $type - */ - public function profileEnd($msg, $type = 'wind.core', $flush = false) { - $this->log('end:' . trim($msg), self::LEVEL_PROFILE, $type, $flush); - } - - /** - * 记录日志信息,但不写入文件 - * @param string $msg 日志信息 - * @param const $logType 日志类别 - */ - public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flush = false) { - if (!$this->_logDir) - return; - if ($this->_writeType & self::WRITE_TYPE) - (count($this->_types) >= 5 || $this->_logCount >= $this->_autoFlush) && $this->flush(); - else - $this->_logCount >= $this->_autoFlush && $this->flush(); - if ($level === self::LEVEL_PROFILE) - $message = $this->_build($msg, $level, $type, microtime(true), - $this->getMemoryUsage(false)); - elseif ($level === self::LEVEL_DEBUG) - $message = $this->_build($msg, $level, $type, microtime(true)); - else - $message = $this->_build($msg, $level, $type); - $this->_logs[] = array($level, $type, $message); - $this->_logCount++; - if ($this->_writeType == self::WRITE_TYPE && !in_array($type, $this->_types)) - $this->_types[] = $type; - if ($flush) - $this->flush(); - } - - /** - * 将记录的日志列表信息写入文件 - * @param string $dst 日志被记录于何处 - * @return boolean - */ - public function flush() { - if (empty($this->_logs)) - return false; - Wind::import('WIND:component.utility.WindFile'); - $_l = $_logTypes = $_logLevels = array(); - $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', - self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', - self::LEVEL_PROFILE => 'profile'); - - foreach ($this->_logs as $key => $value) { - $_l[] = $value[2]; - $_logTypes[$value[1]][] = $value[2]; - $_logLevels[$value[0]][] = $value[2]; - } - if ($this->_writeType & 1) { - foreach ($_logLevels as $key => $value) { - if (!$fileName = $this->_getFileName($key)) - continue; - WindFile::write($fileName, join("", $value), 'a'); - } - } - if ($this->_writeType & 2) { - foreach ($_logTypes as $key => $value) { - if (!$fileName = $this->_getFileName($key)) - continue; - WindFile::write($fileName, join("", $value), 'a'); - } - } - if ($fileName = $this->_getFileName()) { - WindFile::write($fileName, join("", $_l), 'a'); - } - $this->_logs = array(); - $this->_logCount = 0; - return true; - } - - /** - * 返回内存使用量 - * @param $peak | 是否是内存峰值 - * @return int - */ - public function getMemoryUsage($peak = true) { - if ($peak && function_exists('memory_get_peak_usage')) - return memory_get_peak_usage(); - elseif (function_exists('memory_get_usage')) - return memory_get_usage(); - $pid = getmypid(); - if (strncmp(PHP_OS, 'WIN', 3) === 0) { - exec('tasklist /FI "PID eq ' . $pid . '" /FO LIST', $output); - return isset($output[5]) ? preg_replace('/[\D]/', '', $output[5]) * 1024 : 0; - } else { - exec("ps -eo%mem,rss,pid | grep $pid", $output); - $output = explode(" ", $output[0]); - return isset($output[1]) ? $output[1] * 1024 : 0; - } - } - - /** - * 组装日志信息 - * @param string $msg 日志信息 - * @param const $logType 日志类别 - * @return string - */ - private function _build($msg, $level, $type, $timer = 0, $mem = 0) { - $result = ''; - switch ($level) { - case self::LEVEL_INFO: - $result = $this->_buildInfo($msg); - break; - case self::LEVEL_ERROR: - $result = $this->_buildError($msg); - break; - case self::LEVEL_DEBUG: - $result = $this->_buildDebug($msg); - break; - case self::LEVEL_TRACE: - $result = $this->_buildTrace($msg); - break; - case self::LEVEL_PROFILE: - $result = $this->_buildProfile($msg, $type, $timer, $mem); - break; - default: - break; - } - return $result ? '[' . date('Y-m-d H:i:s') . '] ' . $result . "\r\n" : ''; - } - - /** - * @param $msg - * @param $type - * @param $timer - * @param $mem - */ - private function _buildProfile($msg, $type, $timer, $mem) { - $_msg = ''; - if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { - $_token = substr($msg, strlen(self::TOKEN_BEGIN)); - $_token = substr($_token, 0, strpos($_token, ':')); - $this->_profiles[] = array($_token, - substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); - } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { - $_msg = "PROFILE! Message:"; - $_token = substr($msg, strlen(self::TOKEN_END)); - $_token = substr($_token, 0, strpos($_token, ':')); - foreach ($this->_profiles as $key => $profile) { - if ($profile[0] !== $_token) - continue; - if ($profile[1]) - $_msg .= "\r\n\t" . $profile[1]; - else - $_msg .= "\r\n\t" . substr($msg, strpos($msg, ':', strlen(self::TOKEN_END)) + 1); - $_msg .= "\r\n\tTime:" . ($timer - $profile[3]) . "\r\n\tMem:" . ($mem - $profile[4]) . "\r\n\tType:$profile[2]"; - break; - } - unset($this->_profiles[$key]); - } - return $_msg; - } - - /** - * 组装info级别的信息输出格式 - * - * [2011-01-24 10:00:00] INFO! Message: $msg - * - * @param string $msg - * @return string - */ - private function _buildInfo($msg) { - return "INFO! Message: " . $msg; - } - - /** - * 组装堆栈trace的信息输出格式 - * - * [2011-01-24 10:00:00] TRACE! Message: $msg - * #1 trace1 - * #2 trace2 - * - * @param string $msg - * @return string - */ - private function _buildTrace($msg) { - return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace()); - } - - /** - * 组装debug信息输出 - * - * [2011-01-24 10:00:00] DEBUG! Message: $msg - * #1 trace1 - * #2 trace2 - * - * @param string $msg - * @return string - */ - private function _buildDebug($msg) { - return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace()); - } - - /** - *组装Error信息输出 - * - * [2011-01-24 10:00:00] ERROR! Message: $msg - * #1 trace1 - * #2 trace2 - * - * @param string $msg - * @return string - */ - private function _buildError($msg) { - return 'ERROR! Message: ' . $msg; - } - - /** - * 错误堆栈信息的获取及组装输出 - * - * #1 trace - * #2 trace - * - * @return string - */ - private function _getTrace() { - $num = 0; - $info[] = 'Stack trace:'; - $traces = debug_backtrace(); - foreach ($traces as $traceKey => $trace) { - if ($num >= 7) - break; - if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos( - $trace['file'], __CLASS__ . '.php') !== false) - continue; - $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: '; - $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function']; - if ($function == 'WindBase::log') - continue; - $args = array_map(array($this, '_buildArg'), $trace['args']); - $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')'; - } - return $info; - } - - /** - * 组装输出的trace中的参数组装 - * @param mixed $arg - */ - private function _buildArg($arg) { - switch (gettype($arg)) { - case 'array': - return 'Array'; - break; - case 'object': - return 'Object ' . get_class($arg); - break; - default: - return "'" . $arg . "'"; - break; - } - } - - /** - * 取得日志文件名 - * @return string - */ - private function _getFileName($suffix = '') { - $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; - $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; - if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { - $counter = 0; - do { - $counter++; - $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); - } while (is_file($_newFile)); - @rename($_logfile, $_newFile); - } - return $_logfile; - } - - public function __destruct() { - $this->flush(); - } - - /** - * @param string $logFile - */ - public function setLogDir($logDir) { - if (!is_dir($logDir)) - $logDir = Wind::getRealDir($logDir); - $this->_logDir = $logDir; - } - - /** - * @param field_type $_maxFileSize - */ - public function setMaxFileSize($maxFileSize) { - $this->_maxFileSize = (int) $maxFileSize; - } -} - - \ No newline at end of file diff --git a/wind/component/mail/WindMail.php b/wind/component/mail/WindMail.php deleted file mode 100644 index b4efd04b..00000000 --- a/wind/component/mail/WindMail.php +++ /dev/null @@ -1,898 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ - -/** - * 邮件发送类 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindMail { - - /** - * @var string 邮件内容仅文本 - */ - const ONLYTEXT = 1; - /** - * @var string 邮件内容仅HTML - */ - const ONLYHTML = 2; - /** - * @var string 邮件内容是文本和HTML - */ - const TEXTHTML = 3; - /** - * @var string 邮件内容有附件 - */ - const ATTACH = 4; - /** - * @var string 无邮件内容 - */ - const NONE = 5; - - /** - * @var array 邮件收件人 - */ - private $recipients = array(); - /** - * @var array 邮件头 - */ - private $mailHeader = array(); - /** - * @var array 邮件边界线 - */ - private $boundary = ''; - /** - * @var array 邮件附件 - */ - private $attachment = array(); - /** - * @var string 邮件字符集 - */ - private $charSet = 'gbk'; - - /** - * @var string 邮件mime类型 - */ - private $contentType = self::MIME_TEXT; - /** - * @var string 邮件消息体html展现方式 - */ - private $bodyHtml = ''; - /** - * @var string 邮件消息体文本展现方式 - */ - private $bodyText = ''; - /** - * @var string 是否是内嵌资源 - */ - private $embed = false; - /** - * @var string 邮件编码方式 - */ - private $encode = self::ENCODE_BASE64; - //常用邮件MIME - const CRLF = "\n"; - const TO = 'To'; - const CC = 'Cc'; - const BCC = 'Bcc'; - const FROM = 'From'; - const SUBJECT = 'Subject'; - const MESSAGEID = 'Message-Id'; - const CONTENTTYPE='Content-Type'; - const CONTENTENCODE = 'Content-Transfer-Encoding'; - const CONTENTID = 'Content-ID'; - const CONTENTPOSITION = 'Content-Disposition'; - const CONTENTDESCRIPT = 'Content-Description'; - const CONTENTLOCATION = 'Content-Location'; - const CONTENTLANGUAGE='Content-Language'; - const DATE = 'Date'; - //邮件MIME类型 - const MIME_OCTETSTREAM = 'application/octet-stream'; - const MIME_TEXT = 'text/plain'; - const MIME_HTML = 'text/html'; - const MIME_ALTERNATIVE = 'multipart/alternative'; - const MIME_MIXED = 'multipart/mixed'; - const MIME_RELATED = 'multipart/related'; - //邮件编码 - const ENCODE_7BIT = '7bit'; - const ENCODE_8BIT = '8bit'; - const ENCODE_QP = 'quoted-printable'; - const ENCODE_BASE64 = 'base64'; - const ENCODE_BINARY = 'binary'; - - const DIS_ATTACHMENT = 'attachment'; - const DIS_INLINE = 'inline'; - const LINELENGTH = 72; - - const SEND_SMTP = 'smtp'; - const SEND_PHP = 'php'; - const SEND_SEND = 'send'; - - public function send($type = self::SEND_SMTP,$config = array()){ - if(!in_array($type,array(self::SEND_SMTP,self::SEND_PHP,self::SEND_SEND))){ - throw new WindException('There is no way that you want to send e-mail'); - } - $class = Wind::import('Wind:component.mail.sender.Wind'.ucfirst($type).'Mail'); - /* @var $sender IWindSendMail */ - $sender = new $class($config); - $sender->send($this); - return true; - } - /** - * 创建邮件头 - * @return string - */ - public function createHeader(){ - $header = ''; - if(!isset($this->mailHeader[self::CONTENTTYPE])){ - $this->setContentType(null); - } - foreach($this->mailHeader as $key=>$value){ - $header .= $this->headerLine($key,$value); - } - return $header.self::CRLF; - } - - /** - * 创建邮件消息体 - * @return string - */ - public function createBody(){ - $mime = $this->getMimeType(); - if(self::ONLYTEXT === $mime){ - return self::encode($this->getBodyText(),$this->encode); - }elseif(self::ONLYHTML === $mime){ - return self::encode($this->getBodyHtml(),$this->encode).self::CRLF; - }elseif(self::TEXTHTML === $mime){ - $boundary = $this->boundaryLine(); - $body = $boundary.$this->getTextHeader().self::encode($this->getBodyText(),$this->encode).self::CRLF; - $body .= $boundary.$this->getHtmlHeader().self::encode($this->getBodyHtml(),$this->encode).self::CRLF; - return $body .= $this->boundaryEndLine(); - }elseif(self::ATTACH === $mime){ - $boundary = $this->boundaryLine(); - $body = ''; - if('' != ($text = $this->getBodyText())){ - $body .= $boundary.$this->getTextHeader().self::encode($text,$this->encode).self::CRLF; - } - if('' != ($html = $this->getBodyHtml())){ - $body .= $boundary.$this->getHtmlHeader().self::encode($html,$this->encode).self::CRLF; - } - $body .= $this->attach().self::CRLF; - return $body .= $this->boundaryEndLine(); - } - return ''; - } - - - - /** - * 设置邮件头 - * @param string $name 邮件头名称 - * @param string $value 邮件头对应的值 - * @param boolean $append 是否是追加 - * @return boolean - */ - public function setMailHeader($name, $value,$append = true) { - $value = is_array($value) ? $value : array($value); - if(false === $append){ - $this->mailHeader[$name] = $value; - return true; - } - if (!isset($this->mailHeader[$name])) { - $this->mailHeader[$name] = $value; - }else{ - foreach($value as $key=>$value){ - if(is_string($key)){ - $this->mailHeader[$name][$key]=$value; - }else{ - $this->mailHeader[$name][]=$value; - } - } - } - return true; - } - - /** - * 设置发件人 - * @param string $email 发件人邮箱 - * @param string $name 发件人姓名 - */ - public function setFrom($email, $name = null) { - $value = $name ? array($name => $email) : array($email); - $this->setMailHeader(self::FROM, $value,false); - } - - /** - * 设置收件人 - * @param string $email 收件人邮箱 - * @param string $name 收件人姓名 - */ - public function setTo($email, $name = null) { - $value = $name ? array($name => $email) : array($email); - $this->setMailHeader(self::TO, $value); - } - /** - * 设置抄送人 - * @param string $email 抄送人邮箱 - * @param string $name 抄送人姓名 - */ - public function setCc($email, $name = null) { - $value = $name ? array($name => $email) : array($email); - $this->setMailHeader(self::CC, $value); - } - /** - * 设置暗送人 - * @param string $email 暗送人邮箱 - * @param string $name 暗送人姓名 - */ - public function setBcc($email, $name = null) { - $value = $name ? array($name => $email) : array($email); - $this->setMailHeader(self::BCC, $value); - } - - /** - * 设置邮件主题 - * @param string $subject 主题 - */ - public function setSubject($subject) { - $this->setMailHeader(self::SUBJECT, $subject,false); - } - - /** - * 设置邮件日期 - * @param boolean $ifchinese 是否是中国日期 - */ - public function setDate($date = null,$ifchinese = true){ - if(!$date){ - Wind::import ( 'WIND:component.utility.date.WindDate' ); - $date = $ifchinese ? WindDate::getChinaDate() : WindDate::getRFCDate(); - } - $this->setMailHeader(self::DATE,$date ); - } - - /** - *设置邮件消息ID - */ - public function setMessageId() { - $this->setMailHeader(self::MESSAGEID, '<' . $this->createMessageId() . '>'); - } - - /** - * 设置邮件html展示内容 - * @param string $bodyHtml - */ - public function setBodyHtml($bodyHtml){ - $this->bodyHtml = $bodyHtml; - } - /** - * 设置邮件文本展示内容 - * @param string $bodyText - */ - public function setBodyText($bodyText){ - $this->bodyText = $bodyText; - } - - /** - * 设置邮件类型 - * @param string $type - */ - public function setContentType($type = null){ - if(!$type){ - $mime = $this->getMimeType(); - if(self::ONLYTEXT === $mime){ - $type = self::MIME_TEXT; - }elseif(self::ONLYHTML === $mime){ - $type = self::MIME_HTML; - }elseif(self::TEXTHTML === $mime){ - $type = self::MIME_ALTERNATIVE; - }elseif(self::ATTACH === $mime && $this->embed){ - $type = self::MIME_RELATED; - }elseif(self::ATTACH === $mime && !$this->embed){ - $type = self::MIME_MIXED; - }else{ - $type = self::MIME_TEXT; - } - } - if(self::MIME_TEXT == $type || self::MIME_HTML == $type){ - $contentType = sprintf("%s; charset=\"%s\"", $type, $this->charSet); - }elseif(self::MIME_RELATED == $type){ - $this->setBoundary(); - $contentType = sprintf("%s;%s type=\"text/html\";%s boundary=\"%s\"", self::MIME_RELATED, self::CRLF, self::CRLF, $this->getBoundary()); - }else{ - $this->setBoundary(); - $contentType = sprintf("%s;%s boundary=\"%s\"",$type,self::CRLF,$this->getBoundary()); - } - $this->contentType = $type; - $this->setMailHeader(self::CONTENTTYPE,$contentType,false); - } - - /** - * 设置是否是内嵌资源 - * @param boolean $embed - */ - public function setEmbed($embed = false){ - $this->embed = $embed; - } - - /** - * 设置邮件编码 - * @param string $encode - */ - public function setContentEncode($encode = self::ENCODE_BASE64){ - $this->encode = $encode; - $this->setMailHeader(self::CONTENTENCODE,$encode); - } - - /** - * 设置邮件字符 - * @param string $charset - */ - public function setCharset($charset){ - $this->charSet = $charset; - } - - /** - * 设置附件 - * @param string $stream 附件名或者附件内容 - * @param string $mime 附件类型 - * @param string $disposition 附件展现方式 - * @param string $encode 附件编码 - * @param string $filename 文件名 - * @param string $cid 内容ID - */ - public function setAttachment($stream, $mime = self::MIME_OCTETSTREAM, $disposition = self::DIS_ATTACHMENT, $encode = self::ENCODE_BASE64,$filename = null,$cid = 0){ - - $this->attachment[] = array( - $stream, - $mime, - $disposition, - $encode, - $filename, - $cid - ); - } - - /** - * 设置边界线 - */ - public function setBoundary() { - $this->boundary = '==_' . md5(microtime(true) . uniqid()); - } - - public function getMailHeader($name = null,$subname = null){ - if(!$name){ - return $this->mailHeader; - } - if(!isset($this->mailHeader[$name])){ - return ''; - } - $header = $this->mailHeader[$name]; - if(!$subname || !isset($header[$subname])){ - return $header; - } - return $header[$subname]; - } - - /** - * 取得发件人 - * @return array - */ - public function getFrom() { - if(isset($this->mailHeader[self::FROM])){ - $from = $this->mailHeader[self::FROM]; - return is_array($from) ? array_shift($from) : $from; - } - return ''; - } - /** - * 取得收件人 - * @return array - */ - public function getTo() { - return isset($this->mailHeader[self::TO]) ? $this->mailHeader[self::TO] : array(); - } - - /** - * 取得抄送的对象 - * @return array - */ - public function getCc() { - return isset($this->mailHeader[self::CC]) ? $this->mailHeader[self::CC] : array(); - } - - /** - * 取得暗送对象 - * @return array - */ - public function getBcc() { - return isset($this->mailHeader[self::BCC]) ? $this->mailHeader[self::BCC] : array(); - } - - /** - * 取得邮件主题 - * @return array - */ - public function getSubject() { - if(isset($this->mailHeader[self::SUBJECT])){ - $subject = $this->mailHeader[self::SUBJECT]; - return is_array($subject) ? array_shift($subject) : $subject; - } - return ''; - } - - /** - * 取得边界符 - * @return array - */ - public function getBoundary() { - return $this->boundary; - } - - /** - * 取得mime类型 - * @return string - */ - public function getMimeType(){ - if('' != $this->getBodyText() && '' == $this->getBodyHtml() && false == $this->hasAttachment()){ - return self::ONLYTEXT; - }elseif('' == $this->getBodyText() && '' != $this->getBodyHtml() && false == $this->hasAttachment()){ - return self::ONLYHTML; - }elseif('' != $this->getBodyText() && '' != $this->getBodyHtml() && false == $this->hasAttachment()){ - return self::TEXTHTML; - }elseif($this->hasAttachment()){ - return self::ATTACH; - }else{ - return self::NONE; - } - return 0; - } - - /** - * 取得真实的收件人 - * @return array - */ - public function getRecipients() { - $this->buildRecipients($this->getTo()); - $this->buildRecipients($this->getCc()); - $this->buildRecipients($this->getBcc()); - return $this->recipients; - } - - /** - * 取得消息中的html - * @return string - */ - public function getBodyHtml(){ - return trim($this->bodyHtml); - } - - /** - * 取得消息中的文本 - * @return string - */ - public function getBodyText(){ - return trim($this->bodyText); - } - - /** - * 取得文本头 - * @return string - */ - public function getTextHeader(){ - $textHeader = self::CONTENTTYPE.': text/plain; charset='.$this->charSet.self::CRLF; - return $textHeader .= self::CONTENTENCODE.': '.$this->encode.self::CRLF; - } - - /** - * 取得html头 - * @return string - */ - public function getHtmlHeader(){ - $htmlHeader = self::CONTENTTYPE.': text/html; charset='.$this->charSet.self::CRLF; - return $htmlHeader .= self::CONTENTENCODE.': '.$this->encode.self::CRLF.self::CRLF; - } - - /** - * 取得附件的头 - * @param string $mime mime头类型 - * @param string $name 文件名 - * @param string $encode 编码 - * @param string $disposition 附件展现方式 - * @param string $cid 内容ID - * @return string - */ - public function getAttachHeader($mime,$name,$encode = self::ENCODE_BASE64,$disposition = 'attachment',$cid = 0){ - $attachHeader = sprintf(self::CONTENTTYPE.": %s; name=\"%s\"%s", $mime, $name, self::CRLF); - $attachHeader .= sprintf(self::CONTENTENCODE.": %s%s", $encode, self::CRLF); - if($disposition == 'inline') { - $attachHeader .= sprintf(self::CONTENTID.": <%s>%s", $cid, self::CRLF); - } - return $attachHeader .= sprintf(self::CONTENTPOSITION.": %s; filename=\"%s\"%s%s", $disposition, $name, self::CRLF,self::CRLF); - } - - /** - * 获到文件中的内容 - * @param string $file 文件名 - * @param string $encode 编码方式 - * @return string - */ - public function getStreamFromFile ($file, $encode = self::ENCODE_BASE64) { - $fp = fopen($file, 'rb'); - $magic_quotes = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - $steam = fread($fp,filesize($file)); - fclose($fp); - set_magic_quotes_runtime($magic_quotes); - return $steam; - } - - /** - * 上传附件 - * @return string - */ - public function attach() { - $attach = ''; - foreach($this->attachment as $key => $value){ - list($stream,$mime,$disposition,$encode,$filename,$cid) = $value; - $filename = $filename ? $filename : (is_file($stream) ? $stream : 'attachment_'.$key); - $attachHeader = $this->getAttachHeader($mime,$filename,$encode,$disposition,$cid); - $boundary = $this->boundaryLine(); - if(is_file($stream)){ - $stream = $this->getStreamFromFile($stream); - } - $attach .= $boundary.$attachHeader.$this->encode($stream,$encode).self::CRLF; - } - return $attach; - } - - /** - * 过滤mime头 - * @param string $header - * @return string - */ - public function filterHeader($header) { - return strtr(trim($header),array("\r"=>'',"\n"=>'',"\r\n"=>'')); - } - - /** - * 获取边界线 - * @return string - */ - public function boundaryLine() { - return self::CRLF . '--' . $this->getBoundary() . self::CRLF; - } - - /** - * 获取结束边界线 - * @return string - */ - public function boundaryEndLine() { - return self::CRLF . '--' . $this->getBoundary() . '--' . self::CRLF; - } - - /** - * 对字符进行编码 - * @param string $string 要编码的字符串 - * @param string $encode 编码的方式 - * @return string - */ - public function encode($string,$encode = self::ENCODE_BASE64){ - switch($encode) { - case self::ENCODE_BASE64: return self::encodeBase64($string); - case self::ENCODE_7BIT: - case self::ENCODE_8BIT: - case self::ENCODE_BINARY:return $string; - case self::ENCODE_QP:return self::EncodeQP($string); - default:return $string; - } - return $string.self::CRLF; - } - - /** - * 对mime头进行编码 - * @param string $string 要编码的字符串 - * @param string $encode 编码的方式 - * @return string - */ - public function encodeHeader($header,$encode=self::ENCODE_BASE64){ - switch($encode) { - case self::ENCODE_BASE64: return self::encodeBase64Header($this->filterHeader($header),$this->charSet); - case self::ENCODE_7BIT: - case self::ENCODE_8BIT: - case self::ENCODE_BINARY:return $header; - case self::ENCODE_QP:return self::encodeQpHeader($this->filterHeader($header),$this->charSet); - default:return $header; - } - return $header; - } - /** - * 对mime头进行quoted-printable编码 - * @param string $string 要编码的字符串 - * @param string $chunklen 分割字符串中每块的长度 - * @param string $end 每个字符块后面的填充符 - * @return string - */ - public static function encodeQpHeader($string, $charset,$chunkLen = self::LINELENGTH,$end = self::CRLF){ - $prefix = sprintf('=?%s?Q?', $charset); - $chunkLen = $chunkLen-strlen($prefix)-3; - $string = self::_encodeQp($string); - $string = strtr($string,array('_'=>'5F',' '=>'=20','?'=>'=3F')); - $lines[] = $tmp = ''; - while(strlen($string) > 0) { - $culLen = max(count($lines)-1, 0); - $token = self::getNextQpToken($string); - $string = substr($string, strlen($token)); - $tmp .= $token; - if('=20' == $token) { - if(strlen($lines[$culLen].$tmp) > $chunkLen) { - $lines[$culLen+1] = $tmp; - } else { - $lines[$culLen] .= $tmp; - } - $tmp = ''; - } - if(0 == strlen($string)) { - $lines[$culLen] .= $tmp; - } - } - for($i = 0; $i < count($lines); $i++) { - $lines[$i] = ' '.$prefix.$lines[$i].'?='; - } - return trim(implode($end, $lines)); - } - /** - * 对mime头进行base64编码 - * @param string $string 要编码的字符串 - * @param string $chunklen 分割字符串中每块的长度 - * @param string $end 每个字符块后面的填充符 - * @return string - */ - public static function encodeBase64Header($string,$charset, $chunkLen = self::LINELENGTH,$end = self::CRLF){ - $prefix = '=?' . $charset . '?B?'; - $suffix = '?='; - $length = $chunkLen - strlen($prefix) - strlen($suffix); - $encodedString = self::encodeBase64($string, $length, $end); - $encodedString = $prefix . strtr($encodedString,array($end=>$suffix . $end . ' ' . $prefix)) . $suffix; - return $encodedString; - } - /** - * quoted-printable编码 - * @param string $string 要编码的字符串 - * @param string $chunklen 分割字符串中每块的长度 - * @param string $end 每个字符块后面的填充符 - * @return string - */ - public static function encodeQp($string, $chunklen = self::LINELENGTH,$end = self::CRLF){ - $endodeString = ''; - $string = self::_encodeQp($string); - while ($string) { - $plen = $chunklen < ($plen = strlen($string)) ? $chunklen : $plen; - if (false !== ($pos = strrpos(substr($string, 0, $plen), '=')) && $pos >= $plen - 2) { - $plen = $pos; - } - 0 < $plen && ' ' == $string[$plen - 1] && --$plen; - $endodeString .= substr($string, 0, $plen) . '=' . $end; - $string = substr($string, $plen); - } - $endodeString = rtrim($endodeString, $end); - $endodeString = rtrim($endodeString, '='); - return $endodeString; - } - /** - * base64编码 - * @param string $string 要编码的字符串 - * @param string $chunklen 分割字符串中每块的长度 - * @param string $end 每个字符块后面的填充符 - * @return string quoted-printable - */ - public static function encodeBase64($string,$chunklen = self::LINELENGTH,$end = self::CRLF){ - return chunk_split(base64_encode($string), $chunklen, $end); - } - /** - * quoted-printable 对照表 - * @return string - */ - public static function getQpTable(){ - return array( - "\x00"=>"=00","\x01"=>"=01","\x02"=>"=02","\x03"=>"=03", - "\x04"=>"=04","\x05"=>"=05","\x06"=>"=06","\x07"=>"=07", - "\x08"=>"=08","\x09"=>"=09","\x0A"=>"=0A","\x0B"=>"=0B", - "\x0C"=>"=0C","\x0D"=>"=0D","\x0E"=>"=0E","\x0F"=>"=0F", - "\x10"=>"=10","\x11"=>"=11","\x12"=>"=12","\x13"=>"=13", - "\x14"=>"=14","\x15"=>"=15","\x16"=>"=16","\x17"=>"=17", - "\x18"=>"=18","\x19"=>"=19","\x1A"=>"=1A","\x1B"=>"=1B", - "\x1C"=>"=1C","\x1D"=>"=1D","\x1E"=>"=1E","\x1F"=>"=1F", - "\x7F"=>"=7F","\x80"=>"=80","\x81"=>"=81","\x82"=>"=82", - "\x83"=>"=83","\x84"=>"=84","\x85"=>"=85","\x86"=>"=86", - "\x87"=>"=87","\x88"=>"=88","\x89"=>"=89","\x8A"=>"=8A", - "\x8B"=>"=8B","\x8C"=>"=8C","\x8D"=>"=8D","\x8E"=>"=8E", - "\x8F"=>"=8F","\x90"=>"=90","\x91"=>"=91","\x92"=>"=92", - "\x93"=>"=93","\x94"=>"=94","\x95"=>"=95","\x96"=>"=96", - "\x97"=>"=97","\x98"=>"=98","\x99"=>"=99","\x9A"=>"=9A", - "\x9B"=>"=9B","\x9C"=>"=9C","\x9D"=>"=9D","\x9E"=>"=9E", - "\x9F"=>"=9F","\xA0"=>"=A0","\xA1"=>"=A1","\xA2"=>"=A2", - "\xA3"=>"=A3","\xA4"=>"=A4","\xA5"=>"=A5","\xA6"=>"=A6", - "\xA7"=>"=A7","\xA8"=>"=A8","\xA9"=>"=A9","\xAA"=>"=AA", - "\xAB"=>"=AB","\xAC"=>"=AC","\xAD"=>"=AD","\xAE"=>"=AE", - "\xAF"=>"=AF","\xB0"=>"=B0","\xB1"=>"=B1","\xB2"=>"=B2", - "\xB3"=>"=B3","\xB4"=>"=B4","\xB5"=>"=B5","\xB6"=>"=B6", - "\xB7"=>"=B7","\xB8"=>"=B8","\xB9"=>"=B9","\xBA"=>"=BA", - "\xBB"=>"=BB","\xBC"=>"=BC","\xBD"=>"=BD","\xBE"=>"=BE", - "\xBF"=>"=BF","\xC0"=>"=C0","\xC1"=>"=C1","\xC2"=>"=C2", - "\xC3"=>"=C3","\xC4"=>"=C4","\xC5"=>"=C5","\xC6"=>"=C6", - "\xC7"=>"=C7","\xC8"=>"=C8","\xC9"=>"=C9","\xCA"=>"=CA", - "\xCB"=>"=CB","\xCC"=>"=CC","\xCD"=>"=CD","\xCE"=>"=CE", - "\xCF"=>"=CF","\xD0"=>"=D0","\xD1"=>"=D1","\xD2"=>"=D2", - "\xD3"=>"=D3","\xD4"=>"=D4","\xD5"=>"=D5","\xD6"=>"=D6", - "\xD7"=>"=D7","\xD8"=>"=D8","\xD9"=>"=D9","\xDA"=>"=DA", - "\xDB"=>"=DB","\xDC"=>"=DC","\xDD"=>"=DD","\xDE"=>"=DE", - "\xDF"=>"=DF","\xE0"=>"=E0","\xE1"=>"=E1","\xE2"=>"=E2", - "\xE3"=>"=E3","\xE4"=>"=E4","\xE5"=>"=E5","\xE6"=>"=E6", - "\xE7"=>"=E7","\xE8"=>"=E8","\xE9"=>"=E9","\xEA"=>"=EA", - "\xEB"=>"=EB","\xEC"=>"=EC","\xED"=>"=ED","\xEE"=>"=EE", - "\xEF"=>"=EF","\xF0"=>"=F0","\xF1"=>"=F1","\xF2"=>"=F2", - "\xF3"=>"=F3","\xF4"=>"=F4","\xF5"=>"=F5","\xF6"=>"=F6", - "\xF7"=>"=F7","\xF8"=>"=F8","\xF9"=>"=F9","\xFA"=>"=FA", - "\xFB"=>"=FB","\xFC"=>"=FC","\xFD"=>"=FD","\xFE"=>"=FE", - "\xFF"=>"=FF" - ); - } - /** - * 在quoted-printable编码中过滤等号 - * @param string $string 取得编码的字符串 - * @return string - */ - public static function _encodeQp($string){ - $string = strtr($string,array('='=>'=3D')); - return strtr($string,self::getQpTable()); - } - /** - * 生成mime邮件头的消息ID - * @return string - */ - public function createMessageId() { - if (array() != ($from = $this->getFrom())) { - $user = is_array($from) ? $from[0] : $from; - } elseif (isset($_SERVER['REMOTE_ADDR'])) { - $user = $_SERVER['REMOTE_ADDR']; - } else { - $user = getmypid(); - } - $rand = mt_rand(); - if ($this->recipients) { - $recipient = array_rand($this->recipients); - } else { - $recipient = 'No recipient'; - } - if (isset($_SERVER["SERVER_NAME"])) { - $host = $_SERVER["SERVER_NAME"]; - } else { - $host = php_uname('n'); - } - return sha1(time() . $user . $rand . $recipient) . '@' . $host; - } - - /** - * 清空邮件头 - * @param string $header - */ - public function clearMailHeader($header = null){ - if($header){ - if(isset($this->mailHeader[$header])){ - unset($this->mailHeader[$header]); - } - }else{ - $this->mailHeader = array(); - } - } - /** - * 清空附件 - */ - public function clearAttachment(){ - $this->attachment = array(); - } - - /** - * 清空收件人 - */ - public function clearRecipients(){ - $this->recipients = array(); - } - - /** - * 清空边界线 - */ - public function clearBoundary(){ - $this->boundary = ''; - } - - /** - * 清空html格式的邮件正文 - */ - public function clearBodyHtml(){ - $this->bodyHtml = ''; - } - - /** - * 清空text格式的邮件正文 - */ - public function clearBodyText(){ - $this->bodyText = ''; - } - - /** - * 清空邮件头、附件、收件人、边界线、html和text格式的邮件正文; - */ - public function clearAll(){ - $this->clearMailHeader(); - $this->clearRecipients(); - $this->clearAttachment(); - $this->clearBoundary(); - $this->clearBodyHtml(); - $this->clearBodyText(); - } - /** - * 构建收件人列表 - * @param string $data - * @return array(); - */ - private function buildRecipients($data = array()) { - if(empty($data) || !is_array($data)){ - return array(); - } - foreach ($data as $key => $value) { - if (is_string($key)) { - $this->recipients[] = $value.' '.$key; - } else { - $this->recipients[] = $value; - } - } - return $this->recipients; - } - - /** - * 生成mime邮件头 - * @param string $name mime头 - * @param string $value mime值 - * @return string - */ - private function headerLine($name,$value){ - if(is_array($value)){ - $tmp = ''; - foreach($value as $key=>$_value){ - $_value = is_string($key) ? $key.' '.$_value : $_value; - $tmp .= $tmp ? ','.$_value : $_value; - } - return $name.': '.$tmp.self::CRLF; - - }else{ - return $name .': '.$value.self::CRLF; - } - return ''; - } - - /** - * 判断邮件是否有附件 - * @return boolean - */ - private function hasAttachment(){ - return count($this->attachment) > 0; - } - - /** - * 取得下一个quoted-printable - * @param string $string - * @return string - */ - private static function getNextQpToken($string){ - return '=' == substr($string, 0, 1) ? substr($string, 0, 3) : substr($string, 0, 1); - } -} \ No newline at end of file diff --git a/wind/component/mail/protocol/WindImap.php b/wind/component/mail/protocol/WindImap.php deleted file mode 100644 index 2e0dd161..00000000 --- a/wind/component/mail/protocol/WindImap.php +++ /dev/null @@ -1,663 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -Wind::import('WIND:component.mail.protocol.WindSocket'); -/** - * imap协议封装 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindImap { - const CRLF = "\r\n"; - /** - * @var string w命令标签 - */ - const TAG = 'Tag'; - - /*--------imap中邮件标记---------*/ - - /** - * @var string 已被阅读 - */ - const SEEN = '\seen'; - /** - * @var string 已被回复 - */ - const ANSWERED = '\Answered'; - - /** - * @var string 标识为紧急 - */ - const FLAGGED = '\Flagged'; - /** - * @var string 标识为已删除 - */ - const DELETED = '\Deleted'; - /** - * @var string 草稿 - */ - const DRAFT = '\Draft'; - /** - * @var string 新邮件 - */ - const RECENT = '\Recent'; - /*--------imap中邮件标记--------*/ - - /*---------imap中邮件标记类型(store/stripstore方法flags参数)--------*/ - /** - * @var string 邮件的一组标志 - */ - const FLAGS = 'FLAGS'; - /** - * @var string 表示一组邮件的标志 - */ - const SLIENT = 'FLAGS.SLIENT'; - /*---------imap中邮件标记类型(store/stripstore方法flags参数)--------*/ - - /*--------fetch函数中参数$dataname的值---------*/ - /** - * @var string 按照一定格式的邮件摘要,包括邮件标志、RFC822.SIZE、自身的时间和信封信息。 - */ - const ALL = 'ALL'; - /** - * @var string 返回邮件体文本格式和大小的摘要信息 - */ - const BODY = 'BODY'; - /** - * @var string 返回邮件的一些摘要,包括邮件标志、RFC822.SIZE、和自身的时间 - */ - const FAST = 'FAST'; - /** - * @var string 要信息,包括邮件标志、RFC822.SIZE、自身的时间和BODYSTRUCTURE的信息。 - */ - const FULL = 'FULL'; - - /** - * @var string 此邮件的标志 - */ - const FLAG = 'FLAGS'; - /** - * @var string 邮件的[MIME-IMB]的体结构。 - */ - const BODYSTRUCTUR = 'BODYSTRUCTUR'; - /** - * @var string 自身的时间。 - */ - const INTERNALDATE = 'INTERNALDATE'; - /** - * @var string 等同于BODY[]。 - */ - const RFC822 = 'RFC822'; - /** - * @var string 邮件的[RFC-2822]大小 - */ - const RFC822SIZE = 'RFC822.SIZE'; - /** - * @var string 等同于BODY.PEEK[HEADER], - */ - const RFC822HEADER = 'RFC822.HEADER'; - /** - * @var string 功能上等同于BODY[TEXT] - */ - const RFC822TEXT = 'RFC822.TEXT'; - /** - * @var string 返回邮件的UID号,UID号是唯一标识邮件的一个号码。 - */ - const UID = 'UID'; - /*--------fetch函数中参数$dataname的值---------*/ - - /*--------header中的field--------*/ - /** - * @var string 日期 - */ - const DATE = 'Date'; - /** - * @var string 发件人 - */ - const FROM = 'From'; - /** - * @var string 收件人 - */ - const TO = 'To'; - /** - * @var string 抄送地址 - */ - const CC = 'Cc'; - /** - * @var string 抄送地址 - */ - const BCC = 'Bcc'; - /** - * @var string 发送地址 - */ - const DELIVERED = 'Delivered-To'; - /** - * @var string 回复地址 - */ - const REPLY = 'Reply-To'; - /** - * @var string 主题 - */ - const SUBEJCT = 'Subject'; - /** - * @var string MIME内容的类型 - */ - const CONTENTTYPE = 'Content-Type'; - /** - * @var string 内容的传输编码方式 - */ - const CONTENTENCODE = 'Content-Transfer-Encoding'; - /** - * @var string MIME版本 - */ - const MIMEVERSION = 'MIME-Version'; - /** - * @var string 消息ID - */ - const MESSAGEID = 'Message-Id'; - - /** - * @var string 传输路径 - */ - const RECEIVED = 'Received'; - /** - * @var string 回复地址 - */ - const RETURNPATH = 'Return-Path'; - /*--------header中的field--------*/ - - /*--------status命令中所用参数--------*/ - /** - * @var string 邮箱中的邮件总数 - */ - const S_MESSAGES = 'MESSAGES'; - /** - * @var string 邮箱中标志为\RECENT的邮件数 - */ - const S_RECENT = 'RECENT'; - /** - * @var string 可以分配给新邮件的下一个UID - */ - const S_UIDNEXT = 'UIDNEXT'; - /** - * @var string 邮箱的UID有效性标志 - */ - const S_UIDVALIDITY = 'UIDVALIDITY'; - /** - * @var string 邮箱中没有被标志为\UNSEEN的邮件数 - */ - const S_UNSEEN = 'UNSEEN'; - /*--------status命令中所用参数--------*/ - - /*--------search命令中所用参数--------*/ - /** - * @var string 返回所有的匹配 - */ - CONST SH_ALL = 'ALL'; - /** - * @var string 返回新的邮件 - */ - CONST SH_NEW = 'NEW'; - /** - * @var string 返回邮件中打了\Answered标记的邮件 - */ - CONST SH_ANSWERED = 'ANSWERED'; - /** - * @var string 返回邮件中指字暗送的邮件 - */ - CONST SH_BCC = 'BCC'; - /** - * @var string 返回指定日期已前的邮件 - */ - CONST SH_BEFORE = 'BEFORE'; - /** - * @var string 返回有主体的邮件 - */ - CONST SH_BODY = 'BODY'; - /** - * @var string 返回邮件中打了\Deleted标记的邮件 - */ - CONST SH_DELETED = 'DELETED'; - /** - * @var string 返回邮件中打了\Flagged标记的邮件 - */ - CONST SH_FLAGGED = 'FLAGGED'; - /** - * @var string 返回指定发件人字段的邮件 - */ - CONST SH_FROM = 'FROM'; - /** - * @var string 返回邮件消息中指定keywork的邮件 - */ - CONST SH_KEYWORD = 'KEYWORD'; - /** - * @var string 返回邮件中打了\Recent标记的邮件 - */ - CONST SH_RECENT = 'RECENT'; - /** - * @var string 返回邮件中打了\Seen标记的邮件 - */ - CONST SH_SEEN = 'SEEN'; - /** - * @var string 返回指定日期之后的邮件 - */ - CONST SH_SINCE = 'SINCE'; - /** - * @var string 返回邮件中文本指定字符串的邮件 - */ - CONST SH_TEXT = 'TEXT'; - /** - * @var string 返回指定收件人字段的邮件 - */ - CONST SH_TO = 'TO'; - /** - * @var string 返回邮件中没有打\Answered标记的邮件 - */ - CONST SH_UNANSWERED = 'UNANSWERED'; - /** - * @var string 返回邮件中没有打\Deleted标记的邮件 - */ - CONST SH_UNDELETED = 'UNDELETED'; - /** - * @var string 返回邮件中没有指定关键字的邮件 - */ - CONST SH_UNKEYWORD = 'UNKEYWORD'; - /** - * @var string 返回邮件中没有打\Seen标记的邮件 - */ - CONST SH_UNSEEN = 'UNSEEN'; - /** - * @var string 返回邮件中没有打\UNFLAGGED标记的邮件 - */ - CONST SH_UNFLAGGED = 'UNFLAGGED'; - /*--------search命令中所用参数--------*/ - - /******body中的section********/ - const TEXT = 'TEXT'; - const HEADER = 'HEADER'; - /******body中的section********/ - /** - * @var WindSocket imap邮件服务器 - */ - protected $imap = null; - protected $seperate = ' '; - protected $request = array(); - protected $resonse = array(); - - private $tag = 0; - public function __construct($host, $port) { - $this->imap = new WindSocket($host, $port); - } - - /** - * 打开一个imap连接 - * @return string - */ - public function open() { - $this->imap->open(); - return $this->response('*'); - } - - /** - * 登陆 - * @param string $username - * @param string $password - * @return string - */ - public function login($username, $password) { - return $this->communicate("LOGIN {$username} {$password}"); - } - - /** - * 创建指定名字的新邮箱。邮箱名称通常是带路径的文件夹全名。 - * @param string $folder; - * @param string - */ - public function create($folder) { - return $this->communicate("CREATE {$folder}"); - } - - /** - * 除指定名字的文件夹。文件夹名字通常是带路径的文件夹全名, - * 当邮箱被删除后,其中的邮件也不复存在。 - * @param string $folder - * @return string - */ - public function delete($folder) { - return $this->communicate("DELETE {$folder}"); - } - - /** - * RENAME命令可以修改文件夹的名称,它使用两个参数:当前邮箱名和新邮箱名, - * 两个参数的命名符合标准路径命名规则。 - * @param string $old 当前邮箱名 - * @param string $new 新邮箱名, - * @return string - */ - public function rename($old, $new) { - return $this->communicate("RENAME {$old} {$new}"); - } - - /** - * LIST命令用于列出邮箱中已有的文件夹,有点像操作系统的列目录命令 - * @param string $base 用户登陆目录 - * @param string $template 显示的邮箱名。可以使用通配符"*"。 - * @return string - */ - public function folderOfmail($base = '', $template = '*') { - return $this->communicate("LIST {$base} {$template}"); - } - - /** - * 选定某个邮箱(Folder),表示即将对该邮箱(Folder)内的邮件作操作。 - * 邮箱标志的当前状态也返回给了用户,同时返回的还有一些关于邮件和邮箱的附加信息。 - * @param string $folder - */ - public function select($folder) { - return $this->communicate("SELECT $folder"); - } - /** - * 读取邮件的文本信息,且仅用于显示的目的。 - * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 - * @param string $datanames - */ - public function fetch($mail, $datanames = self::ALL) { - return $this->communicate("FETCH {$mail} {$datanames}"); - } - - /** - * 读取邮件的头信息 - * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 - * @return string - */ - public function fetchHeader($mail) { - return $this->communicate("FETCH {$mail} BODY[HEADER]"); - } - /** - * 读取邮件的头的字段信息,可能造成不安全,慎用 - * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 - * @param string $field 头字段(DATE\SUBJECT\FROM\TO\MESSAGEID\CONTENTTYPE) - * @return string - */ - public function fetchHeaderFields($mail, $field = self::DATE) { - $field = is_array($field) ? implode(' ', $field) : $field; - return $this->communicate("FETCH {$mail} BODY[HEADER.FIELDS ({$field})]"); - } - /** - * 读取邮件的头已排除字段信息 - * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 - * @param string $field 头字段(DATE\SUBJECT\FROM\TO\MESSAGEID\CONTENTTYPE) - * @return string - */ - public function fetchHeaderNotFields($mail, $field = self::DATE) { - $field = is_array($field) ? implode(' ', $field) : $field; - return $this->communicate("FETCH {$mail} BODY[HEADER.FIELDS.NOT ({$field})]"); - } - /** - * 读取邮件的MIME - * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 - * @return string - */ - public function fetchMime($mail) { - return $this->communicate("FETCH {$mail} BODY[MIME]"); - } - /** - * 读取邮件的Text - * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 - * @return string - */ - public function fetchText($mail) { - return $this->communicate("FETCH {$mail} BODY[TEXT]"); - } - - /** - * 返回邮件的中的某一指定部分,返回的部分用section来表示, - * section部分包含的信息通常是代表某一部分的一个数字或者是下面的某一个部分: - * HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。 - * 如果section部分是空的话,那就代表返回全部的信息,包括头信息。 - * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 - * @param int|string $section 返回的部分 - * @return string - */ - public function fetchBySection($mail, $section = self::TEXT) { - return $this->communicate("FETCH {$mail} BODY[$section]"); - } - - /** - * 返回邮件的中的某一指定部分,返回的部分用section来表示, - * section部分包含的信息通常是代表某一部分的一个数字或者是下面的某一个部分: - * HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。 - * 如果section部分是空的话,那就代表返回全部的信息,包括头信息。 - * @param int|string $mail 希望读取的邮件号或者邮冒号分隔的区段 - * @param int $start 返回的部分的开始 - * @param int $end 返回的部分的结束 - * @param int:string $section 返回的部分 - * @return string - */ - public function fetchPartialOfSection($mail, $start, $end, $section = self::TEXT) { - return $this->communicate("FETCH {$mail} BODY[$section]<{$start}.{$end}>"); - } - - /** - * 修改指定邮件的属性,包括给邮件打上已读标记、删除标记等 - * @param INT|string $mail - * @param string $flags imap中的邮件标记,值为SLIENT和FLAGS两种类型 - * @param STRING|ARRAY $attribute 标记属性(DELETED\ANSWERED\RECENT\DRAFT\FLAGGED) - * @reutrn string - */ - public function store($mail, $flags = self::FLAGS, $attribute = self::ANSWERED) { - $attribute = is_array($attribute) ? implode(' ', $attribute) : $attribute; - return $this->communicate("STORE {$mail} +" . self::FLAGS . " ($attribute)"); - } - /** - * 修改指定邮件的属性,包括给邮件打上已读标记、删除标记等 - * @param INT|string $mail - * @param string $flags imap中的邮件标记,值为SLIENT和FLAGS两种类型 - * @param STRING|ARRAY $attribute 标记属性(DELETED\ANSWERED\RECENT\DRAFT\FLAGGED) - * @reutrn string - */ - public function stripStore($mail, $flags = self::FLAGS, $attribute = self::DELETED) { - $attribute = is_array($attribute) ? implode(' ', $attribute) : $attribute; - return $this->communicate("STORE {$mail} -" . self::FLAGS . " ($attribute)"); - } - /** - * 结束对当前Folder(文件夹/邮箱)的访问, - * 关闭邮箱该邮箱中所有标志为DELETED的邮件就被从物理上删除 - */ - public function close() { - return $this->communicate("CLOSE"); - } - - /** - * 不关闭邮箱的情况下删除所有的标志为、DELETED的邮件。 - * EXPUNGE删除的邮件将不可以恢复。 - */ - public function expunge() { - return $this->communicate("EXPUNGE"); - } - /** - * 以只读方式打开邮箱 - * @param string $mailbox 邮箱 - * @return string - */ - public function examine($mailbox) { - return $this->communicate("EXAMINE $mailbox"); - } - - /** - * 在客户机的活动邮箱列表中增加一个邮箱 - * @param string $mailbox 希望添加的邮箱名。 - */ - public function subscribe($mailbox) { - return $this->communicate("SUBSCRIBE $mailbox"); - } - - /** - * 来从活动列表中去掉一个邮箱 - * @param string $mailbox 希望去掉的邮箱名。 - */ - public function unsubscribe($mailbox) { - return $this->communicate("UNSUBSCRIBE $mailbox"); - } - - /** - * 修正了LIST命令,LIST返回用户$HOME目录下所有的文件, - * 但LSUB命令只显示那些使用SUBSCRIBE命令设置为活动邮箱的文件 - * @param string $folder 邮箱路径 - * @param string $mailbox 邮箱名。 - * @return string - */ - public function lsub($folder, $mailbox) { - return $this->communicate("LSUB {$mailbox} {$mailbox}"); - } - - /** - * 查询邮箱的当前状态 - * @param string $mailbox 需要查询的邮箱名 - * @param string $params 客户机需要查询的项目列表,S_MESSAGES\S_RECENT\S_UIDNEXT\S_UIDVALIDITY\S_UNSEEN - * @return string - */ - public function status($mailbox, $params = self::S_MESSAGES) { - - $params = is_array($params) ? implode(' ', $params) : $params; - return $this->communicate("STATUS {$mailbox} ({$params})"); - } - - /** - * 在邮箱设置一个检查点,确保内存中的磁盘缓冲数据都被写到了磁盘上。 - */ - public function check() { - return $this->communicate("CHECK"); - } - - /** - * 根据搜索条件在处于活动状态的邮箱中搜索邮件,然后显示匹配的邮件编号。 - * @param string $criteria 查询条件参数,明确查询的关键字 - * @param string $value 查询条件参数,明确查询的关键字的值 - * @param string $charset 字符集标志,缺省的标志符是US-ASCⅡ - * @return string - */ - public function search($criteria = self::SH_ALL, $value = null) { - $search = $criteria; - if ($value) { - $search .= ' ' . $value; - } - return $this->communicate("SEARCH {$search}"); - } - - /** - * UID号是唯一标识邮件系统中邮件的32位证书。 - * 通常这些命令都使用顺序号来标识邮箱中的邮件, - * 使用UID可以使IMAP客户机记住不同IMAP会话中的邮件。 - */ - public function uid() { - return $this->communicate("UID"); - } - - /** - * 把邮件从一个邮箱复制到另一个邮箱 - * @param int $soruce 希望从活动邮箱中复制的邮件的标号 - * @param string $dst 望邮件被复制到的邮箱 - * @return string - */ - public function copy($soruce, $dst) { - return $this->communicate("COPY {$soruce} {$dst}"); - } - - /** - * 返回IMAP服务器支持的功能列表, - * 服务器收到客户机发送的CAPABILITY命令后将返回该服务器所支持的功能。 - */ - public function capability() { - return $this->communicate("CAPABILITY"); - } - /** - * 结束本次IMAP会话。 - */ - public function logout() { - $this->communicate("LOGOUT"); - } - - /** - * 发送imap会话请求命令 - * @param string $request - */ - public function request($request) { - $this->request[] = $request; - $this->setTag(); - return $this->imap->request($this->getTag() . ' ' . $request . self::CRLF); - } - /** - * imap会话响应请求 - * @param int $timeout - */ - public function responseLine($timeout = null) { - if (null !== $timeout) { - $this->imap->setSocketTimeOut((int) $timeout); - } - return $this->imap->responseLine(); - } - - /** - * 验证请求 - * @param boolean $multi - * @param int $timeout - * @return string - */ - public function response($endTag = '*', $timeout = null) { - $response = ''; - while ('' != ($_response = $this->responseLine($timeout))) { - list($tag, $status, $info) = explode(' ', $_response, 3); - if (in_array($status, array('NO', "BAD"))) { - throw new WindException($_response); - } - $response .= $_response; - $this->resonse[] = $_response; - if ($endTag == $tag) { - break; - } - } - if (empty($response)) throw new WindException('No response'); - return $response; - } - - /** - * 一次imap会号 - * @param string $request 请求 - * @param string $response 响应 - * @return string - */ - public function communicate($request, &$response = null) { - $this->request($request); - return $response = $this->response($this->getTag()); - } - /** - * 在imap会话中设置新标答 - */ - public function setTag() { - $this->tag++; - } - /** - * 取得imap会号中的标签 - * @return string - */ - public function getTag() { - return self::TAG . $this->tag; - } - - public function __destruct() { - if ($this->imap) { - $this->logout(); - $this->imap->close(); - $this->imap = null; - } - } - -} \ No newline at end of file diff --git a/wind/component/mail/protocol/WindPop3.php b/wind/component/mail/protocol/WindPop3.php deleted file mode 100644 index 6a807a87..00000000 --- a/wind/component/mail/protocol/WindPop3.php +++ /dev/null @@ -1,260 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -Wind::import ( 'WIND:component.mail.protocol.WindSocket' ); -/** - * pop3协议 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindPop3 { - const CRLF = "\r\n"; - /** - * @var WindSocket pop3邮件服务器 - */ - protected $pop3 = null; - protected $seperate = ' '; - protected $request = array(); - protected $resonse = array(); - - public function __construct($host, $port) { - $this->pop3 = new WindSocket($host, $port); - } - - /** - * 打开pop3服务器,建立连接 - * @return string - */ - public function open() { - $this->pop3->open(); - return $this->response(); - } - - /** - * 登陆pop3 - * @param string $username 用户名 - * @param string $password 密码 - * @return string - */ - public function login($username, $password) { - $this->communicate("USER $username"); - return $this->communicate("PASS $password"); - } - - /** - * 处理请求 server 回送邮箱统计资料,如邮件数、 邮件总字节数 - * @return string - */ - public function stat() { - return $this->communicate('STAT', false, true); - } - - /** - * 处理 server 返回用于该指定邮件的唯一标识, 如果没有指定,返回所有的。 - * @param int $n 指定邮件 - * @return string - */ - public function uidl($n = null) { - $request = $n ? "UIDL $n" : 'UIDL'; - $ifmulti = $n ? false : true; - return $this->communicate($request, $ifmulti, true); - } - - /** - * 处理 server 返回指定邮件的大小等 - * @param int $n 指定邮件 - * @return string - */ - public function getList($n = null) { - $request = $n ? "LIST $n" : 'LIST'; - $ifmulti = $n ? false : true; - return $this->communicate($request, $ifmulti, true); - } - - /** - * 处处理 server 返回邮件的全部文本 - * @param int $n 指定邮件 - * @return string - */ - public function retr($n) { - return $this->communicate("RETR $n", true); - } - /** - * 处理 server 标记删除,QUIT 命令执行时才真正删除 - * @param int $n 指定邮件 - * @return string - */ - public function dele($n) { - return $this->communicate("DELE $n"); - } - /** - * 处理撤消所有的 DELE 命令 - * @return string - */ - public function rset() { - return $this->communicate("RSET"); - } - - /** - * 处理 返回 n 号邮件的前 m 行内容,m 必须是自然数 - * @param int $n 指定邮件 - * @param int $m 指定邮件前多少行 - * @return string - */ - public function top($n, $m = null) { - $request = $m ? 'TOP ' . (int) $n . ' ' . (int) $m : 'TOP ' . (int) $n; - return $this->communicate($request, true); - } - - /** - * 处理 server 返回一个肯定的响应 - * @return string - */ - public function noop() { - return $this->communicate("NOOP"); - } - - /** - * 希望结束会话。如果 server 处于"处理" 状态, - * 则现在进入"更新"状态,删除那些标记成删除的邮件。 - * 如果 server 处于"认可"状态,则结束会话时 server - * 不进入"更新"状态 。 - * @return string - */ - public function quit() { - return $this->communicate("QUIT"); - } - - /** - * 结否会话,关闭pop3服务器 - */ - public function close() { - $this->quit(); - $this->pop3->close(); - $this->pop3 = null; - } - /** - * pop3响应请求 - * @param int $timeout - */ - public function responseLine($timeout = null) { - if (null !== $timeout) { - $this->pop3->setSocketTimeOut((int) $timeout); - } - return $this->pop3->responseLine(); - } - - /** - * 外理响应内容 - * @param string $response - * @return Array - */ - public function buildResponse($response) { - if (empty($response)) { - return array(); - } - $response = explode("\n", $response); - $_response = array(); - foreach ($response as $line) { - if (empty($line)) { - continue; - } - list($key, $value) = explode($this->seperate, trim($line), 2); - $key ? $_response[(int) $key] = $value : $_response[] = $value; - } - return $_response; - } - - /** - * 进行一次网络传输通信 - * @param string $request 发竤的请求命令 - * @param boolean $ifmulti 是否返回多行响应文本,否则为一行 - * @param baoolean $ifbuild 是否对响应进行处理 - * @return array - */ - public function communicate($request, $ifmulti = false, $ifbuild = false) { - $this->request($request); - return $ifbuild ? $this->buildResponse($this->response($ifmulti)) : $this->response($ifmulti); - } - - /** - * 发送pop3命令 - * @param string $request - */ - public function request($request) { - $this->request[] = $request; - return $this->pop3->request($request . self::CRLF); - } - - /** - * 验证请求 - * @param boolean $multi - * @param int $timeout - * @return string - */ - public function response($multi = false, $timeout = null) { - $ok = $this->responseLine($timeout); - if (empty($ok) || !is_string($ok)) { - throw new WindException('Read Failed'); - } - if ('+OK' !== substr($ok, 0, 3)) { - throw new WindException('Request Failed!Pleae See Failed Info:' . $ok); - } - if (true === $multi) { - $response = ''; - while ('' != ($_response = $this->responseLine($timeout))) { - if ('.' === trim($_response)) { - break; - } - $response .= $_response; - $this->resonse[] = $_response; - } - } else { - $this->resonse[] = $ok; - if (strpos($ok, $this->seperate)) { - list(, $response) = explode($this->seperate, $ok, 2); - } else { - $response = $ok; - } - } - if(empty($response)) throw new WindException('No response'); - return $response; - } - - /** - * 获取解析后的内容 - * @param $content - * @param $sep - */ - public function getMailContent($content,$sep = "\n\n"){ - $content = explode($sep,$content); - $content[0] = explode("\n",$content[0]); - $headers = array(); - foreach($content[0] as $value){ - $_value = explode(':',$value); - $headers[$_value[0]] = trim($_value[1]); - } - $encode = $headers['Content-Transfer-Encoding']; - if('base64' == $encode){ - $content = base64_decode($content[1]); - }else{ - $content = $content[1]; - } - return array($headers,$content); - } - - public function __destruct() { - if ($this->pop3) { - $this->close(); - } - } - -} -?> \ No newline at end of file diff --git a/wind/component/mail/protocol/WindSmtp.php b/wind/component/mail/protocol/WindSmtp.php deleted file mode 100644 index 895387b8..00000000 --- a/wind/component/mail/protocol/WindSmtp.php +++ /dev/null @@ -1,211 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -Wind::import ( 'WIND:component.mail.protocol.WindSocket' ); -/** - * 邮件传输协议操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSmtp { - const CRLF = "\r\n"; - /** - * @var WindSocket - */ - protected $smtp = null; - protected $request = array(); - protected $resonse = array(); - - public function __construct($host, $port,$timeout = 60) { - $this->smtp = new WindSocket($host, $port ,$timeout); - } - - /** - * 打开smtp服务器,建立连接 - * @return string - */ - public function open() { - $this->smtp->open(); - return $this->checkResponse(220); - } - - /** - * 向服务器标识用户身份 - * @param string $host 身份 - * @return string - */ - public function ehlo($host) { - $this->request('EHLO ' . $host); - return $this->checkResponse(250); - } - - /** - * 进行用户身份认证 - * @param string $username 用户名 - * @param string $password 密码 - * @return string - */ - public function authLogin($username, $password) { - $this->request('AUTH LOGIN'); - $this->checkResponse(array(334)); - $this->request(base64_encode($username)); - $this->checkResponse(array(334)); - $this->request(base64_encode($password)); - return $this->checkResponse(array(235)); - } - - /** - * 指定的地址是发件人地址 - * @param string $from 邮件发送者 - * @return string - */ - public function mailFrom($from) { - $this->request('MAIL FROM:' . '<' . $from . '>'); - return $this->checkResponse(250); - } - /** - * 指定的地址是收件人地址 - * @param string $to 邮件发送者 - * @return string - */ - public function rcptTo($to) { - $this->request('RCPT TO:' . '<' . $to . '>'); - return $this->checkResponse(array(250, 251)); - } - - /** - * 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令 - * @param string $user - * @return string - */ - public function very($user) { - $this->request('VRFY ' . $user); - return $this->checkResponse(array(250, 251, 252)); - } - /** - * 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用 - * @param string $name - * @return string - */ - public function expn($name) { - $this->request('EXPN ' . $name); - $response = $this->checkResponse(250); - $entries = explode(self::CRLF, $response); - while (list(, $l) = each($entries)) { - $list[] = substr($l, 4); - } - return $list; - } - - /** - * 无操作,服务器应响应 OK - * @return string - */ - public function noop() { - $this->request('NOOP'); - return $this->checkResponse(250); - } - - /** - * 在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以 CRLF.CRLF 结束 - * @param string $data 发送的数据 - * @return string - */ - public function data($data) { - $this->request('DATA'); - $this->checkResponse(354); - $data = str_replace("\r\n", "\n", $data); - $data = str_replace("\r", "\n", $data); - $lines = explode("\n", $data); - foreach ($lines as $line) { - if (0 === strpos($line, '.')) { - $line = '.' . $line; - } - $this->request($line); - } - $this->request('.'); - return $this->checkResponse(250); - } - /** - * 重置会话,当前传输被取消 - * @return string - */ - public function rset() { - $this->request('RSET'); - return $this->checkResponse(array(250, 220)); - } - /** - * 结束会话 - * @return string - */ - public function quit() { - $this->request('QUIT'); - return $this->checkResponse(221); - } - - /** - * 关闭smtp服务器 - */ - public function close() { - $this->smtp->close(); - $this->smtp = null; - } - - /** - * smtp响应请求 - * @param int $timeout - */ - public function responseLine($timeout = null) { - if (null !== $timeout) { - $this->smtp->setSocketTimeOut((int) $timeout); - } - return $this->smtp->responseLine(); - } - - /** - * 发送smtp命令 - * @param string $request - */ - public function request($request) { - $this->request[] = $request.self::CRLF; - return $this->smtp->request($request . self::CRLF); - } - - /** - * 验证请求 - * @param string $expect - * @param int $timeout - * @return string - */ - public function checkResponse($expect, $timeout = null) { - $response = ''; - $expect = is_array($expect) ? $expect : array($expect); - while ('' != ($_response = $this->responseLine($timeout))) { - $response .= $_response; - $this->resonse[] = $_response; - list($code, $info) = preg_split('/([\s-]+)/', $_response, 2); - if(null === $code || !in_array($code, $expect)) throw new WindException($info); - if (" " == substr($_response, 3, 1)) { - break; - } - } - if(empty($response)) throw new WindException('No response'); - return $response; - } - - - - public function __destruct() { - if ($this->smtp) { - $this->close(); - } - } - -} \ No newline at end of file diff --git a/wind/component/mail/protocol/WindSocket.php b/wind/component/mail/protocol/WindSocket.php deleted file mode 100644 index c54a09af..00000000 --- a/wind/component/mail/protocol/WindSocket.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ - -/** - * socket套接字操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSocket { - - protected $host = '127.0.0.1'; - protected $port = 80; - protected $timeout = 5; - protected $errno = 0; - protected $errstr = ''; - protected $socket = null; - - public function __construct($host = '127.0.0.1', $port = 80, $timeout = 5) { - $this->setHost($host); - $this->setPort($port); - $this->setTimeout($timeout); - } - - /** - * 打开一个连接 - */ - public function open() { - if (null == $this->socket) { - $this->socket = fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout); - } - } - - /** - * 发送请求 - * @param string $request - */ - public function request($request) { - return fputs($this->socket, $request); - } - - /** - * 响应请求 - * @return string - */ - public function response() { - $response = ''; - while (!feof($this->socket)) { - $response .= fgets($this->socket); - } - return $response; - } - - /** - * 响应请求,只返回一行 - * @return string - */ - public function responseLine() { - return feof($this->socket) ? '' : fgets($this->socket); - } - - /** - *关闭连接 - */ - public function close() { - if ($this->socket) { - fclose($this->socket); - $this->socket = null; - } - return true; - } - /** - * 获取请求中的错误 - * @return string - */ - public function getError() { - return $this->errstr ? $this->errno . ':' . $this->errstr : ''; - } - - /** - * 取得socket操作对象 - * @return resource - */ - public function getSocket(){ - return $this->socket; - } - - /** - * 设置主机 - * @param string $host - */ - public function setHost($host) { - $this->host = $host; - - } - /** - * 设置端口 - * @param string $port - */ - public function setPort($port) { - $this->port = $port; - } - /** - * 设置超时 - * @param int $timeout - */ - public function setTimeout($timeout) { - $this->timeout = $timeout; - } - - public function setSocketTimeOut($timeout) { - return stream_set_timeout($this->socket, $timeout); - } -} \ No newline at end of file diff --git a/wind/component/mail/sender/IWindSendMail.php b/wind/component/mail/sender/IWindSendMail.php deleted file mode 100644 index 2ca37f43..00000000 --- a/wind/component/mail/sender/IWindSendMail.php +++ /dev/null @@ -1,15 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -interface IWindSendMail{ - /** - * 发送邮件 - * @param WindMail $mail 邮件消息封装对象 - */ - public function send(WindMail $mail); -} \ No newline at end of file diff --git a/wind/component/mail/sender/WindPhpMail.php b/wind/component/mail/sender/WindPhpMail.php deleted file mode 100644 index 04f69ade..00000000 --- a/wind/component/mail/sender/WindPhpMail.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -Wind::import('WIND:component.mail.sender.IWindSendMail'); -/** - * 使用php内部函数发送邮件 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindPhpMail implements IWindSendMail{ - - public function send(WindMail $mail){ - $recipients = $mail->getRecipients(); - $to = $this->getToAsString($recipients); - return mail($to,$mail->getSubject(),$mail->createBody(),$mail->createHeader()); - } - - public function getToAsString($recipients = array()){ - $to = ''; - foreach($recipients as $key=>$value){ - $_value = is_string($key) ? $key.' '.$_value : $_value; - $to .= $to ? ', '.$_value : $_value; - } - return $to; - - } -} \ No newline at end of file diff --git a/wind/component/mail/sender/WindSendMail.php b/wind/component/mail/sender/WindSendMail.php deleted file mode 100644 index e6f98882..00000000 --- a/wind/component/mail/sender/WindSendMail.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -Wind::import('WIND:component.mail.sender.IWindSendMail'); -/** - * 使用sendmail发送邮件 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSendMail implements IWindSendMail{ - /** - * @var string sendmail命令路径 - */ - private $sendMail = '/usr/sbin/sendmail'; - /** - * @var string 发送者 - */ - private $sender = ''; - /** - * @var string 工作进程 - */ - private $process = null; - /** - * @param string $sendMail 工作进程 - * @param string $sender 发送者 - */ - public function __construct(array $config=null){ - if(isset($config['sendMail'])){ - $this->sendMail = $config['sendMail']; - } - if(isset($config['sender'])){ - $this->sender = $config['sender']; - } - } - /** - * 发送邮件 - * @param WindMail $mail mail信息封装对象 - * @return string - */ - public function send(WindMail $mail) { - $this->open(); - $this->transData($mail->createHeader()); - $this->transData($mail->createBody()); - return $this->close() ? false : true; - } - /** - * 开启一个sendmail进进程 - */ - public function open(){ - if($this->sender){ - $mailCmd = sprintf("%s -oi -f %s -t", escapeshellcmd($this->sendMail), escapeshellarg($this->sender)); - }else{ - $mailCmd = sprintf("%s -oi -t", escapeshellcmd($this->sendMail)); - } - $this->process = popen($mailCmd, 'w'); - } - - /** - * 传输数据 - * @param string $data 数据 - */ - public function transData($data){ - fputs($this->process,$data); - } - - - /** - * 关闭一个进程 - * @return number - */ - public function close(){ - return pclose($this->process); - } - - public function __destruct(){ - $this->process = null; - } -} \ No newline at end of file diff --git a/wind/component/mail/sender/WindSmtpMail.php b/wind/component/mail/sender/WindSmtpMail.php deleted file mode 100644 index d645702d..00000000 --- a/wind/component/mail/sender/WindSmtpMail.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -Wind::import('WIND:component.mail.sender.IWindSendMail'); -Wind::import ( 'WIND:component.mail.protocol.WindSmtp' ); -/** - * 邮件发送 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSmtpMail implements IWindSendMail{ - /** - * @var WindSmtp 邮件发送服务器 - */ - protected $smtp = null; - /** - * @var boolean 是否启用验证 - */ - protected $auth = true; - /** - * @var string 邮件主机名 - */ - protected $name = 'localhost'; - /** - * @var string 邮件用户名 - */ - protected $username = ''; - /** - * @var string 邮件密码 - */ - protected $password = ''; - - public function __construct(array $config){ - $defautConfig = array('host'=>'127.0.0.1','port'=>'25','name'=>'localhost','auth'=>true); - $config = array_merge($defautConfig,$config); - if(!isset($config['host']) || !isset($config['port'])){ - throw new WindException('The mail host or port is not exist'); - } - if($config['auth'] && (!isset($config['user']) || !isset($config['password']))){ - throw new WindException('In the verification mode, the user name and password is blank or wrong'); - } - $this->auth = $config['auth']; - $this->name = $config['name']; - $this->smtp = new WindSmtp($config['host'],$config['port']); - $this->smtp->open(); - $this->setAuthParams($config['user'],$config['password']); - } - - /** - * 发送邮件 - * @param WindMail $mail 邮件消息封装对象 - */ - public function send(WindMail $mail){ - $this->smtp->ehlo($this->name); - if($this->auth){ - $this->smtp->authLogin($this->username,$this->password); - } - $this->smtp->mailFrom($mail->getFrom()); - foreach($mail->getRecipients() as $rcpt){ - $this->smtp->rcptTo($rcpt); - } - $header = $mail->createHeader(); - $body = $mail->createBody(); - $data = $header.$body; - $this->smtp->data($header.$body); - $this->smtp->quit(); - } - - /** - * 设置验证参数 - * @param string $username 用户名 - * @param string $password 密码 - */ - public function setAuthParams($username,$password){ - $this->username = $username; - $this->password = $password; - } - - - - public function __destruct(){ - $this->smtp->close(); - $this->smtp = null; - } -} \ No newline at end of file diff --git a/wind/component/parser/IWindConfigParser.php b/wind/component/parser/IWindConfigParser.php deleted file mode 100644 index 0695ad50..00000000 --- a/wind/component/parser/IWindConfigParser.php +++ /dev/null @@ -1,27 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindConfigParser { - - /** - * 解析文件,保存缓存,返回解析结果 - * - * 1、缺省的配置文件,采用XML格式解析返回 - * 2、如果输入的配置文件格式没有提供支持,则抛出异常 - * 3、根据格式进行解析 - * 4、参数三$isApp 用来配置该解析式组件格式的解析还是应用配置的解析, - * 如果是应用解析需要进行merge操作,如果是组件解析则不用 - * - * @param string $name 解析后保存的文件名字 - * @param string $configPath 待解析文件的绝对路径 - * @param string $append 追加的文件 - * @param AbstractWindCache $cache 缓存策略 - * @return array 解析成功返回的数据 - */ - public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null); - -} \ No newline at end of file diff --git a/wind/component/parser/WindConfigParser.php b/wind/component/parser/WindConfigParser.php deleted file mode 100644 index 624dae50..00000000 --- a/wind/component/parser/WindConfigParser.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @author xiaoxia xu - * @version $Id$ - * @package - */ -class WindConfigParser implements IWindConfigParser { - /** - * 配置文件支持的格式白名单 - */ - const CONFIG_XML = '.XML'; - const CONFIG_PHP = '.PHP'; - const CONFIG_INI = '.INI'; - const CONFIG_PROPERTIES = '.PROPERTIES'; - - /** - * 配置解析对象队列 - * @var array object $configParser - */ - private $configParsers = array(); - - /** - * 解析组件的配置文件 - * - * 如果用户没有传入别名,则每次都执行解析 - * 如果用户传入别名,判断是否传入了追加的文件名 - * 如果传入了追加的文件名,则判断该文件的内容中是否存在以别名为key的值 - * 如果有该值则返回该值,否则继续 - * 如果没有传入追加的文件名,则判断该别名命名的缓存文件是否存在 - * 如果存在则返回该文件内容,否则继续 - * 如果没有传入别名,则继续 - * - * 如果该缓存文件不存在,则判断如果不是以追加的方式,并且已经存在该缓存文件,则返回该缓存文件 - * 如果都不存在,则执行解析,并根据是否追加的条件,进行追加或是新建。 - * - * @param string $configPath 待解析的文件路径 - * @param string $alias 解析后保存的key名 - * @param string $append 追加的文件 - * @param AbstractWindCache $cache 缓存策略 - * @return array 解析结果 - */ - public function parse($configPath, $alias = '', $append = '', AbstractWindCache $cache = null) { - if ($config = $this->getCache($alias, $append, $cache)) return $config; - $config = $this->doParser($configPath); - $this->setCache($alias, $append, $cache, $config); - return $config; - } - - /** - * 设置配置缓存 - * @param string $alias - * @param string $append - * @param AbstractWindCache $cache - */ - private function setCache($alias, $append, $cache, $data) { - if (!$alias || !$cache) return; - if ($append) { - $_config = (array) $cache->get($append); - $_config[$alias] = $data; - $cache->set($append, $_config); - } else { - $cache->set($alias, $data); - } - } - - /** - * 返回配置缓存 - * @param string alias - * @param string append - * @param AbstractWindCache cache - * @return array - */ - private function getCache($alias, $append, $cache) { - if (!$alias || !$cache) return array(); - if (!$append) return $cache->get($alias); - - $config = $cache->get($append); - return isset($config[$alias]) ? $config[$alias] : array(); - } - - /** - * 创建配置文件解析器 - * - * @access private - */ - private function createParser($type) { - switch ($type) { - case self::CONFIG_XML: - Wind::import("WIND:component.parser.WindXmlParser"); - return new WindXmlParser(); - break; - case self::CONFIG_INI: - Wind::import("WIND:component.parser.WindIniParser"); - return new WindIniParser(); - break; - case self::CONFIG_PROPERTIES: - Wind::import("WIND:component.parser.WindPropertiesParser"); - return new WindPropertiesParser(); - break; - default: - throw new WindException('\'ConfigParser\' failed to initialize.'); - break; - } - } - - /** - * 执行解析并返回解析结果 - * 接收一个配置文件路径,根据路径信息初始化配置解析器,并解析该配置 - * 以数组格式返回配置解析结果 - * - * @param string $configFile 解析的文件路径 - * @return array 返回解析结果 - */ - private function doParser($configFile) { - if (!is_file($configFile)) throw new WindException( - '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); - $ext = strtoupper(strrchr($configFile, '.')); - if ($ext == self::CONFIG_PHP) return @include ($configFile); - if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); - return $this->configParsers[$ext]->parse($configFile); - } -} \ No newline at end of file diff --git a/wind/component/parser/WindIniParser.php b/wind/component/parser/WindIniParser.php deleted file mode 100644 index c9a8974d..00000000 --- a/wind/component/parser/WindIniParser.php +++ /dev/null @@ -1,147 +0,0 @@ - 2010-12-13 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * ini 格式文件解析 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindIniParser { - - /** - * @var string 分割数组标识 - */ - protected $separator = '.'; - - /** - * 解析数据 - * @param string $filename ini格式文件 - * @param boolean $process 处理指令 - * @param boolean $build 是否按指定格式返回 - * @return boolean - */ - public function parse($filename, $process = true, $build = true) { - if (!is_file($filename)) { - return array(); - } - $data = parse_ini_file($filename, $process); - return $build ? $this->buildData($data) : $data; - } - - /** - * 构建数据 - * @param array $data - * @return array - */ - public function buildData(&$data) { - foreach ((array)$data as $key => $value) { - if (is_array($value)) { - $data[$key] = $this->formatDataArray($value); - } else { - $this->formatDataFromString($key, $value, $data); - } - } - return $data; - } - - /** - * 将每行ini文件转换成数组 - * @param string $key ini文件中的键 - * @param string $value ini文件中的值 - * @param array $data - * @return array - */ - public function toArray($key, $value, &$data = array()) { - if (empty($key) && empty($value)) return array(); - if (strpos($key, $this->separator)) { - $start = substr($key, 0, strpos($key, $this->separator)); - $end = substr($key, strpos($key, $this->separator) + 1); - $data[$start] = array(); - $this->toArray($end, $value, $data[$start]); - } else { - $data[$key] = $value; - } - return $data; - } - - /** - * 解析ini格式文件成数组 - * @param array $original 原始数组 - * @param array $data 解析后的数组 - * @return array - */ - public function formatDataArray(&$original, &$data = array()) { - foreach ((array)$original as $key => $value) { - $tmp = $this->toArray($key, $value); - foreach ($tmp as $tkey => $tValue) { - if (is_array($tValue)) { - if (!isset($data[$tkey])) { - $data[$tkey] = array(); - } - $this->formatDataArray($tValue, $data[$tkey]); - } else { - $data[$tkey] = $tValue; - } - } - } - return $data; - } - - /** - * 从字符串中合并数组 - * @param string $key - * @param string $value - * @param array $data - * return array - */ - public function formatDataFromString($key, $value, &$data) { - $tmp = $this->toArray($key, $value); - if(false == strpos($key, $this->separator)){ - return $tmp; - } - $start = substr($key, 0, strpos($key, $this->separator)); - if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { - $data[$start] = $tmp[$start]; - } else { - foreach ($data as $d_key => $d_value) { - if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { - continue; - } - foreach ($tmp[$d_key] as $a => $b) { - $this->merge($a, $b, $data[$start]); - } - } - } - unset($data[$key]); - return $data; - } - - /** - * 合并格式化的数组 - * @param string $key - * @param mixed $value - * @param array $data - * @return array - */ - private function merge($key, $value, &$data = array()) { - if (is_array($value)) { - $v_key = array_keys($value); - $c_key = $v_key[0]; - if (is_array($value[$c_key])) { - $this->merge($c_key, $value[$c_key], $data[$key]); - } else { - $data[$key][$c_key] = $value[$c_key]; - } - } else { - $data[$key] = $value; - } - return $data; - } -} \ No newline at end of file diff --git a/wind/component/parser/WindPropertiesParser.php b/wind/component/parser/WindPropertiesParser.php deleted file mode 100644 index 074119c6..00000000 --- a/wind/component/parser/WindPropertiesParser.php +++ /dev/null @@ -1,214 +0,0 @@ - 2010-12-13 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * properties格式文件解析 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindPropertiesParser { - - const COMMENT = '#'; - const LPROCESS = '['; - const RPROCESS = ']'; - private $separator = '.'; - - public function __construct() { - - } - - /** - * 解析properties文件里的内容 - * @param string $filename 文件名 - * @param boolean $process 是否处理指令 - * @param boolean $build 是否按格式解析数据 - * @return array - */ - public function parse($filename, $process = true, $build = true) { - $data = $this->parse_properties_file($filename, $process); - return $build ? $this->buildData($data) : $data; - } - - private function delComment($filename, $process) { - - } - - /** - * 载入一个由 filename 指定的 properties 文件, - * 并将其中的设置作为一个联合数组返回。 - * 如果将最后的 process参数设为 TRUE, - * 将得到一个多维数组,包括了配置文件中每一节的名称和设置。 - * process_sections 的默认值是 true。 - * @param string $filename 文件名 - * @param unknown_type $process 是否处理指令 - * @return array - */ - public function parse_properties_file($filename, $process = true) { - if (!is_file($filename) || !in_array(substr($filename, strrpos($filename, '.') + 1), array('properties'))) { - return array(); - } - $fp = fopen($filename, 'r'); - $content = fread($fp, filesize($filename)); - fclose($fp); - $content = explode("\n", $content); - $data = array(); - $last_process = $current_process = ''; - foreach ($content as $key => $value) { - $value = str_replace(array("\n", "\r"), '', trim($value)); - if (0 === strpos(trim($value), self::COMMENT) || in_array(trim($value), array('', "\t", "\n"))) { - continue; - } - $tmp = explode('=', $value, 2); - if (0 === strpos(trim($value), self::LPROCESS) && (strlen($value) - 1) === strrpos($value, self::RPROCESS)) { - if ($process) { - $current_process = $this->trimChar(trim($value), array(self::LPROCESS, self::RPROCESS)); - $data[$current_process] = array(); - $last_process = $current_process; - } - continue; - } - $tmp[0] = trim($tmp[0]); - $tmp[1] = trim($tmp[1], '\'"'); - - if ($last_process) { - count($tmp) > 1 ? $data[$last_process][$tmp[0]] = $tmp[1] : $data[$last_process][$tmp[0]] = ''; - } else { - count($tmp) > 1 ? $data[$tmp[0]] = $tmp[1] : $data[$tmp[0]] = ''; - } - } - return $data; - - } - - /** - * 解析数据 - * @param array $data - * @return array - */ - public function buildData(&$data) { - foreach ((array)$data as $key => $value) { - if (is_array($value)) { - $data[$key] = $this->formatDataArray($value); - } else { - $this->formatDataFromString($key, $value, $data); - } - } - return $data; - } - - /** - * 将proterties文件每行转换成数组 - * @param string $key ini文件中的键 - * @param string $value ini文件中的值 - * @param array $data - * @return array - */ - public function toArray($key, $value, &$data = array()) { - if (empty($key) && empty($value)) return array(); - if (strpos($key, $this->separator)) { - $start = substr($key, 0, strpos($key, $this->separator)); - $end = substr($key, strpos($key, $this->separator) + 1); - $data[$start] = array(); - $this->toArray($end, $value, $data[$start]); - } else { - $data[$key] = $value; - } - return $data; - } - - /** - * 将原始数组合并成新的数组 - * @param array $original 原始数组 - * @param array $data 合并后的数组 - * @return array - */ - public function formatDataArray(&$original, &$data = array()) { - foreach ((array)$original as $key => $value) { - $tmp = $this->toArray($key, $value); - foreach ($tmp as $tkey => $tValue) { - if (is_array($tValue)) { - if (!isset($data[$tkey])) { - $data[$tkey] = array(); - } - $this->formatDataArray($tValue, $data[$tkey]); - } else { - $data[$tkey] = $tValue; - } - } - } - return $data; - } - - /** - * 从字符串中合并数组 - * @param string $key - * @param string $value - * @param array $data - * return array - */ - public function formatDataFromString($key, $value, &$data) { - $tmp = $this->toArray($key, $value); - if(false == strpos($key, $this->separator)){ - return $tmp; - } - $start = substr($key, 0, strpos($key, $this->separator)); - if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) { - $data[$start] = $tmp[$start]; - } else { - foreach ($data as $d_key => $d_value) { - if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) { - continue; - } - foreach ($tmp[$d_key] as $a => $b) { - $this->merge($a, $b, $data[$start]); - } - } - } - unset($data[$key]); - return $data; - } - - /** - * 合并格式化的数组 - * @param string $key - * @param mixed $value - * @param array $data - * @return array - */ - private function merge($key, $value, &$data = array()) { - if (is_array($value)) { - $v_key = array_keys($value); - $c_key = $v_key[0]; - if (is_array($value[$c_key])) { - $this->merge($c_key, $value[$c_key], $data[$key]); - } else { - $data[$key][$c_key] = $value[$c_key]; - } - } else { - $data[$key] = $value; - } - return $data; - } - - /** - * 去除字符串头和尾中指定字符 - * @param string $str - * @param mixed $char - * @return string - */ - private function trimChar($str, $char = ' ') { - $char = is_array($char) ? $char : array($char); - foreach ($char as $value) { - $str = trim($str, $value); - } - return $str; - } - -} \ No newline at end of file diff --git a/wind/component/parser/WindXmlParser.php b/wind/component/parser/WindXmlParser.php deleted file mode 100644 index cee4d7a6..00000000 --- a/wind/component/parser/WindXmlParser.php +++ /dev/null @@ -1,109 +0,0 @@ - 2010-12-13 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * xml文件解析 - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindXmlParser { - - /** - * @var string 节点名称 - */ - const NAME = 'name'; - - /** - * @var Domdocument DOM解析器 - */ - private $dom = null; - - /** - * @param string $version xml版本 - * @param string $encode xml编码 - */ - public function __construct($version = '1.0', $encode = 'utf-8') { - if (!class_exists('DOMDocument')) throw new WindException('DOMDocument is not exist.'); - $this->dom = new DOMDocument($version, $encode); - } - - /** - * @param string $filename xml 文件名 - * @param int $option 解析选项 - * @return array - */ - public function parse($filename, $option = null) { - if (!is_file($filename)) return array(); - $this->dom->load($filename, $option); - return $this->getChilds($this->dom->documentElement); - } - - /** - * 获得节点的所有子节点 - * - * 子节点包括属性和子节点(及文本节点), - * 子节点的属性将会根据作为该节点的一个属性元素存放,如果该子节点中含有标签列表,则会进行一次合并。 - * 每个被合并的列表项都作为一个单独的数组元素存在。 - * - * @param DOMElement $node 要解析的XMLDOM节点 - * @return array 返回解析后该节点的数组 - */ - public function getChilds($node) { - if (!$node instanceof DOMElement) return array(); - $childs = array(); - foreach ($node->childNodes as $node) { - $tempChilds = $attributes = array(); - ($node->hasAttributes()) && $attributes = $this->getAttributes($node); - if (3 == $node->nodeType) { - $value = trim($node->nodeValue); - (is_numeric($value) || $value) && $childs[0] = $value;//值为0的情况 - } - if (1 !== $node->nodeType) continue; - - $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; - $tempChilds = $this->getChilds($node); - $tempChilds = array_merge($attributes, $tempChilds); - if (empty($tempChilds)) $tempChilds = ''; - - $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; - if (!isset($childs[$nodeName])) { - $childs[$nodeName] = $tempChilds; - continue; - } else { - $element = $childs[$nodeName]; - $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( - $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); - continue; - } - } - return $childs; - } - - /** - * 获得节点的属性 - * - * 该属性将不包含属性为name的值--规则(name的值将作为解析后数组的key值索引存在) - * - * @param DOMElement $node - * @return array 返回属性数组 - */ - public function getAttributes($node) { - if (!$node instanceof DOMElement || !$node->hasAttributes()) return array(); - $attributes = array(); - foreach ($node->attributes as $attribute) { - if (self::NAME != $attribute->nodeName) { - $attributes[$attribute->nodeName] = (string) $attribute->nodeValue; - } - } - return $attributes; - } -} -?> diff --git a/wind/component/router/AbstractWindRouter.php b/wind/component/router/AbstractWindRouter.php deleted file mode 100644 index 536b8458..00000000 --- a/wind/component/router/AbstractWindRouter.php +++ /dev/null @@ -1,170 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class AbstractWindRouter extends WindHandlerInterceptorChain { - protected $moduleKey = 'm'; - protected $controllerKey = 'c'; - protected $actionKey = 'a'; - protected $module; - protected $controller = 'index'; - protected $action = 'run'; - - protected $currentRoute = null; - - /** - * 解析请求参数,并返回路由结果 - * @return string - */ - abstract public function route(); - - /** - * 创建Url,并返回 - * @return string - */ - abstract public function assemble(); - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - if ($this->_config) { - $this->module = $this->getConfig('module', 'default-value', $this->module); - $this->controller = $this->getConfig('controller', 'default-value', $this->controller); - $this->action = $this->getConfig('action', 'default-value', $this->action); - $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); - $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); - $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); - } - } - - /** - * 设置路由变量信息 - * - * @param string $params - */ - protected function setParams($params) { - foreach ($params as $key => $value) { - if ($this->actionKey === $key) - $this->setAction($value); - elseif ($this->controllerKey === $key) - $this->setController($value); - elseif ($this->moduleKey === $key) - $this->setModule($value); - else { - $this->getRequest()->setAttribute($value, $key); - } - } - } - - /** - * 添加路由协议对象,如果添加的路由协议已经存在则抛出异常 - * @param Object $routeInstance - * @throws WindException - * @return - */ - public function addRoute($routeInstance, $current = false) { - if ($current) - $this->currentRoute = $routeInstance; - $this->addInterceptors($routeInstance); - } - - /** - * 获得业务操作 - * @return string - */ - public function getAction() { - return $this->action; - } - - /** - * 获得业务对象 - * @return string - */ - public function getController() { - return $this->controller; - } - - /** - * 设置action信息 - * @param string $action - * @return - */ - public function setAction($action) { - $this->action = $action; - } - - /** - * 设置controller信息 - * @param string $controller - * @return - */ - public function setController($controller) { - $this->controller = $controller; - } - - /** - * @return the $module - */ - public function getModule() { - return $this->module; - } - - /** - * @param string $module - */ - public function setModule($module) { - $this->module = $module; - } - - /** - * @return the $moduleKey - */ - public function getModuleKey() { - return $this->moduleKey; - } - - /** - * @return the $controllerKey - */ - public function getControllerKey() { - return $this->controllerKey; - } - - /** - * @return the $actionKey - */ - public function getActionKey() { - return $this->actionKey; - } - - /** - * @param field_type $moduleKey - */ - public function setModuleKey($moduleKey) { - $this->moduleKey = $moduleKey; - } - - /** - * @param field_type $controllerKey - */ - public function setControllerKey($controllerKey) { - $this->controllerKey = $controllerKey; - } - - /** - * @param field_type $actionKey - */ - public function setActionKey($actionKey) { - $this->actionKey = $actionKey; - } - -} \ No newline at end of file diff --git a/wind/component/router/WindRouter.php b/wind/component/router/WindRouter.php deleted file mode 100644 index 11c5dfa7..00000000 --- a/wind/component/router/WindRouter.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindRouter extends AbstractWindRouter { - - /* (non-PHPdoc) - * @see IWindRouter::route() - */ - public function route() { - $this->setCallBack(array($this, 'defaultRoute')); - $params = $this->getHandler()->handle(); - $this->setParams($params); - } - - /* (non-PHPdoc) - * @see AbstractWindRouter::assemble() - */ - public function assemble() { - // TODO Auto-generated method stub - } - - /** - * 默认路由规则 - */ - public function defaultRoute() { - $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); - $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, - $this->controller); - $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); - return $params; - } - -} - -?> \ No newline at end of file diff --git a/wind/component/router/WindUrlRewriteRouter.php b/wind/component/router/WindUrlRewriteRouter.php deleted file mode 100644 index 6481a873..00000000 --- a/wind/component/router/WindUrlRewriteRouter.php +++ /dev/null @@ -1,346 +0,0 @@ - - * @author xiaoxiao - * @version 2011-8-12 xiaoxiao - */ -class WindUrlRewriteRouter extends AbstractWindRouter { - private $urlPatttern = ''; - private $keyValueSep = ''; - private $separator = ''; - private $suffix = ''; - private $isRewrite = 0; - private $keyPrefix = ''; - private $baseUrl = ''; - private $patterns = array(); - - /** - * 是否开启重写 - * - * @return boolean - */ - public function isRewrite() { - return $this->isRewrite == '1' || $this->isRewrite == 'true'; - } - - /* - * (non-PHPdoc) - * @see AbstractWindRouter::parse() - */ - public function parse() { - $this->isRewrite() && $this->parseUrl(); - $this->setModule($this->getUrlParamValue('module', $this->getModule())); - $this->setController($this->getUrlParamValue('controller', $this->getController())); - $this->setAction($this->getUrlParamValue('action', $this->getAction())); - } - - /** - * 解析Url - * - * 没有配置解析规则,直接返回 - * 获得则匹配RequestUri,根据用户的配置分隔符分割信息 - * 同时设置到超全局变量$_GET中 - */ - public function parseUrl() { - if (!$this->isRewrite()) - return; - $url = array(); - if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { //http协议 - $pathInfo = $this->getRequest()->getServer('PATH_INFO'); - if ($pathInfo && !empty($pathInfo)) { - $url = rtrim($pathInfo, $this->suffix); - } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { - $scriptName = $this->getRequest()->getScriptUrl(); - if (0 === strpos($url, $scriptName)) { - $url = substr($url, strlen($scriptName)); - } - $url = rtrim($url, $this->suffix); - } - $url = trim($url, '?/'); - $url && $params = $this->doParserUrl($url); - } else { // 命令行下 - $i = 0; - $args = $this->getRequest()->getServer('argv', array()); - while (isset($args[$i]) && isset($args[$i + 1])) { - $params[$args[$i]] = $args[$i + 1]; - $i += 2; - } - } - foreach ($params as $k => $v) { - !isset($_GET[$k]) && $_GET[$k] = $v; - } - } - - /** - * 构造返回Url地址 - * - * 将根据是否开启url重写来分别构造相对应的url - * - * @param string $action 执行的操作 - * @param string $controller 执行的controller - * @param array $params 附带的参数 - * @return string - */ - public function buildUrl($action = '', $controller = '', $params = array()) { - list($module, $controller, $action) = $this->resolveMvc($action, $controller); - $m = $this->getConfig('module', 'url-param'); - $c = $this->getConfig('controller', 'url-param'); - $a = $this->getConfig('action', 'url-param'); - $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); - return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( - $params, '', '&'); - } - - /** - * 解析module, controller, action - * 如果不存在该值,则采用配置的默认值 - * - * @param AbstractWindRouter $urlRouter - * @param string $action - * @param string $controller - * @return array - */ - private function resolveMvc($action, $controller) { - list($controller, $module) = WindHelper::resolveController($controller); - !$module && $module = $this->getConfig('module', 'default-value'); - !$controller && $controller = $this->getConfig('controller', 'default-value'); - !$action && $action = $this->getConfig('action', 'default-value'); - return array($module, $controller, $action); - } - - /** - * 构造重写的url - * @param string $m - * @param string $c - * @param string $action - * @param string $params - * @return string - */ - private function buildRewriteUrl($params) { - $url = $this->urlPatttern; - foreach ($this->patterns as $key => $value) { - if ('*' == $value[0]) { - $url = str_replace($value, $this->buildNomalKeys($params), $url); - } else { - $url = $this->buildVars($value, $params, $url); - } - } - return $this->baseUrl . '/' . $url . $this->suffix; - } - - /** - * 构建变量 不是* - * - * @param string $value - * @param array $params - * @param string $url - * @return string - */ - private function buildVars($value, &$params, $url) { - $keys = explode($this->keyValueSep, $value); - $values = array(); - foreach ($keys as $v) { - if (!isset($params[$v])) - continue; - $values[] = $params[$v]; - unset($params[$v]); - } - return str_replace($keys, $values, $url); - } - - /** - * 构建rewriteurl的参数部分 - * @param array $params - * @param string $parentKey - * @param boolean $first 只有第一级的变量才加前缀 - * @return string - */ - private function buildNomalKeys($params, $parentKey = '', $first = true) { - $tmp = array(); - foreach ($params as $k => $v) { - if (is_int($k) && $this->keyPrefix != null && $first) { - $k = urlencode($this->keyPrefix . $k); - } - if (!empty($parentKey)) - $k = $parentKey . '[' . $k . ']'; - if (is_array($v)) { - array_push($tmp, $this->buildNomalKeys($v, $k, false)); - } else { - array_push($tmp, $k . $this->keyValueSep . urlencode($v)); - } - } - return implode($this->separator, $tmp); - } - - /** - * 执行匹配 - * patterns中的匹配模式去匹配url中的信息 - * urlPatterns中可以根据需求将mca进行组合配置。 - * - * - htm - / - - - myvar_ - 1 - - * url-pattern中:*匹配表示其他的变量信息 - * 用户也可以将自己的其他信息添加到格式中比如m/c-a/tid/* - * suffix : url的后缀 - * separator: 变量分隔符 - * key-value-sep: key和value的分隔符,默认和separator一致 - * key-prefix: 数字索引的前缀 - * is-rewrite: 是否采用rewrite机制 - * - * 遍历url模式:采用separator配置的分隔符获得该模式数组 - * 如果模式是*,则代表该位置开始往后为为传递的变量信息 - * 如果模式不是*,则代表该位置为特殊模式。 - * 如果含有key-value-sep配置的分隔符: 则分别对url中相同key下的值和模式中的值分别做分割,对应的模式下获得的数组作为key,url中获得数组作为value - * 如果不含:则该值就作为Key,url对应位置上的值作为value - * - * @param string 待分析匹配的路径信息 - * @return array - */ - private function doParserUrl($url) { - if (!$url) - return array(); - if (is_string($url)) { - $url = explode($this->separator, trim($url, $this->separator)); - } - $vars = array(); - foreach ($this->patterns as $key => $value) { - if ('*' == $value[0]) - $this->parseNomalKeys($key, $url, $vars); - else { - if (!isset($url[$key])) - continue; - if (false === strrpos($value, $this->keyValueSep)) { - $vars[$value] = $url[$key]; - continue; - } - $keys = explode($this->keyValueSep, $value); - $values = explode($this->keyValueSep, $url[$key]); - foreach ($keys as $pos => $key) { - isset($values[$pos]) && $vars[$key] = $values[$pos]; - } - } - } - return $vars; - } - - /** - * 解析url普通参数 - * 如果separator和key-value-sep配置相同:则采用每两个元素为一对key-value的规则获得变量 - * 如果不相同:则将会以每个元素为key-value的组合,之间的分隔符以key-value-sep划分,如果没有该分隔符,则默认该值的索引为数字索引。 - * 如果为没有分隔符:则该值索引以数字索引给出,同时该数字索引将会根据用户是否配置key前缀key-prefix来给出key。 - * 如果有分隔符:则该值将会用分隔符分割获得的两个值来分别作为key和value. - * @param int $key - * @param array $urlParams - * @param array $params - */ - private function parseNomalKeys($key, $urlParams, &$params) { - $pos = 0; - while (isset($urlParams[$key])) { - if ($this->separator == $this->keyValueSep) { - if (isset($urlParams[$key + 1])) { - $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); - $key += 2; - } - continue; - } - if (false === strrpos($urlParams[$key], $this->keyValueSep)) { - $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); - $pos++; - } else { - list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); - $this->parseKey($params, $k, urldecode($v)); - } - $key += 1; - } - } - - /** - * 解析url的parama信息中的key值 - * - * 如果key值不存在'[',']'字符,则该key为字符串,直接返回 - * 如果key值存在,并且'['和']'之前没有字符,则表示该key是将是一个数组,并且键值自增,返回array($key) - * 如果key值存在,并且'['和']'之前有字符,则表示该key是一个数组,并且'['和']'其中的字符是该数组中的键值,返回array(key值, 键值) - * - * //TODO 需要考虑多维数组的情况 - * @param string $key - * @return string|array 返回匹配的结果 - */ - private function parseKey(&$params, $key, $value) { - if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { - $params[$key] = $value; - return; - } - $name = substr($key, 0, $pos); - if ($pos2 === $pos + 1) { - $params[$name][] = $value; - return; - } else { - $key = substr($key, $pos + 1, $pos2 - $pos - 1); - $params[$name][$key] = $value; - return; - } - } - - /* - * (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); - $usrConfig && $config = array_merge($config, $usrConfig); - parent::setConfig($config); - $this->urlPatttern = $this->getConfig('url-pattern'); - $this->separator = $this->getConfig('separator'); - $this->keyValueSep = $this->getConfig('key-value-sep'); - $this->keyValueSep == "" && $this->keyValueSep = $this->separator; - $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); - $this->isRewrite = $this->getConfig('is-rewrite'); - $this->keyPrefix = $this->getConfig('key-prefix'); - $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); - $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); - if (!$this->isRewrite()) - $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); - } - - /** - * 返回路由的配置信息 - * - * @param urlParam - * @param defaultValue - * @return string - */ - private function getUrlParamValue($type, $defaultValue = '') { - if ($_param = $this->getConfig($type, 'url-param')) { - $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); - $tmp = $this->getRequest()->getRequest($_param, $defaultValue); - return !$tmp ? $defaultValue : $tmp; - } - return $defaultValue; - } - - /* (non-PHPdoc) - * @see AbstractWindRouter::route() - */ - public function route() { - // TODO Auto-generated method stub - - } - - /* (non-PHPdoc) - * @see AbstractWindRouter::assemble() - */ - public function assemble() { - // TODO Auto-generated method stub - - - } - -} diff --git a/wind/component/router/route/AbstractWindRoute.php b/wind/component/router/route/AbstractWindRoute.php deleted file mode 100644 index a01947a9..00000000 --- a/wind/component/router/route/AbstractWindRoute.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class AbstractWindRoute extends WindModule { - - /** - * 根据匹配的路由规则,构建Url - * - * @return string - */ - abstract public function build(); - - /** - * 路由规则匹配方法,返回匹配到的参数列表 - * - * @return array - */ - abstract public function match(); - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::handle() - */ - public function handle() { - $args = func_get_args(); - $this->result = call_user_func_array(array($this, 'match'), $args); - if ($this->result !== null) { - return $this->result; - } - if (null !== ($handler = $this->interceptorChain->getHandler())) { - $this->result = call_user_func_array(array($handler, 'handle'), $args); - } else { - $this->result = $this->interceptorChain->execute(); - } - return $this->result; - } -} - -?> \ No newline at end of file diff --git a/wind/component/router/route/WindRewriteRoute.php b/wind/component/router/route/WindRewriteRoute.php deleted file mode 100644 index 3a9eeb86..00000000 --- a/wind/component/router/route/WindRewriteRoute.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindRewriteRoute extends AbstractWindRoute { - - /* (non-PHPdoc) - * @see AbstractWindRoute::build() - */ - public function build() { - // TODO Auto-generated method stub - - - } - - /* (non-PHPdoc) - * @see AbstractWindRoute::match() - */ - public function match() { - // TODO Auto-generated method stub - - - } - -} - -?> \ No newline at end of file diff --git a/wind/component/router/route/WindRoute.php b/wind/component/router/route/WindRoute.php deleted file mode 100644 index 98a44499..00000000 --- a/wind/component/router/route/WindRoute.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindRoute extends AbstractWindRoute { - /** - * 属性名称 - * - * @var array - */ - protected $params = array(); - /** - * 正则表达式 - * - * @var string - */ - protected $pattern; - /** - * 用于反响生成Url的表达式 - * - * @var string - */ - protected $reverse; - - /* (non-PHPdoc) - * @see IWindRoute::match() - */ - public function match() { - //TODO - } - - /* (non-PHPdoc) - * @see IWindRoute::build() - */ - public function build() { - // TODO Auto-generated method stub - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->setParams($this->getConfig('params')); - $this->setPattern($this->getConfig('pattern')); - $this->setReverse($this->getConfig('reverse')); - } - -} -?> \ No newline at end of file diff --git a/wind/component/upload/AbstractWindUpload.php b/wind/component/upload/AbstractWindUpload.php deleted file mode 100644 index baf5a346..00000000 --- a/wind/component/upload/AbstractWindUpload.php +++ /dev/null @@ -1,249 +0,0 @@ - 2010-12-13 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:component.utility.Security'); -Wind::import('WIND:component.utility.WindFile'); -/** - * the last known user to change this file in the repository <$LastChangedBy: yishuo $> - * @author Qian Su - * @version $Id: AbstractWindUpload.php 1994 2011-06-16 04:19:05Z yishuo $ - * @package - */ -abstract class AbstractWindUpload { - - /** - * 是否有错误产生 - * @var boolean - */ - protected $hasError = false; - - /** - * 错误信息 - * @var array - */ - protected $errorInfo = array('type' => array(), 'size' => array(), 'upload' => array()); - - /** - * 允许的类型 - * @var array - */ - protected $allowType = array();//允许上传的类型及对应的大小,array(ext=>size); - - /** - * 上传文件 - * @param string $saveDir - * @param string $fileName - * @param array $allowType 格式为 array(ext=>size) size单位为b - * @return array|string - */ - public function upload($saveDir, $preFileName = '', $allowType = array()) { - $this->setAllowType($allowType); - $uploaddb = array(); - foreach ($_FILES as $key => $value) { - if (is_array($value['name'])) { - $temp = $this->multiUpload($key, $saveDir, $preFileName); - $uploaddb[$key] = isset($uploaddb[$key]) ? array_merge((array)$uploaddb[$key], $temp) : $temp; - } else { - $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName); - } - } - return 1 == count($uploaddb) ? array_shift($uploaddb) : $uploaddb; - } - - /** - * 单个控件 - * 一个表单中只有一个上传文件的控件 - */ - private function simpleUpload($key, $saveDir, $preFileName = '') { - return $this->doUp($key, $_FILES[$key], $saveDir, $preFileName); - } - - /** - * 多个控件 - * 一个表单中拥有多个上传文件的控件 - */ - private function multiUpload($key, $saveDir, $preFileName = '') { - $uploaddb = array(); - $files = $_FILES[$key]; - $num = count($files['name']); - for($i = 0; $i < $num; $i ++) { - $one = array(); - $one['name'] = $files['name'][$i]; - $one['tmp_name'] = $files['tmp_name'][$i]; - $one['error'] = $files['error'][$i]; - $one['size'] = $files['size'][$i]; - $one['type'] = $files['type'][$i]; - if (!($upload = $this->doUp($key, $one, $saveDir, $preFileName))) continue; - $uploaddb[] = $upload; - } - return $uploaddb; - } - - /** - * 执行上传操作 - * @param string $tmp_name - * @param string $filename - * @return bool - */ - abstract protected function postUpload($tmp_name, $filename); - - /** - * 返回是否含有错误 - * @return boolean - */ - public function hasError() { - return $this->hasError; - } - - /** - * 返回错误信息 - * @param string $errorType - * @return string|mixed - */ - public function getErrorInfo($errorType = '') { - return isset($this->errorInfo[$errorType]) ? $this->errorInfo[$errorType] : $this->errorInfo; - } - - /** - * 设置允许上传的类型 - * @param array $allowType - * @return - */ - public function setAllowType($allowType) { - $allowType && $this->allowType = $allowType; - } - - /** - * 檢查文件是否允許上傳 - * @param string $ext - * @return bool - */ - protected function checkAllowType($ext) { - $allowType = array_keys((array)$this->allowType); - return $allowType ? in_array($ext, $allowType) : true; - } - - /** - * 检查上传文件的大小 - * @param string $type - * @param string $uploadSize - * @return bool - */ - protected function checkAllowSize($type, $uploadSize) { - if ($uploadSize < 0) return false; - if (!$this->allowType || !$this->allowType[$type]) return true; - return $uploadSize < $this->allowType[$type]; - } - - - /** - * 获得文件名字 - * @param array $attInfo - * @param string $preFileName - * @return string - */ - protected function getFileName($attInfo, $preFileName = '') { - $fileName = mt_rand(1, 10) . time() . substr(md5(time() . $attInfo['attname'] . mt_rand(1, 10)), 10, 15) . '.' . $attInfo['ext']; - return $preFileName ? $preFileName . $fileName : $fileName; - } - - /** - * 获得保存路径 - * @param string $fileName - * @param string $saveDir - * @return string - */ - protected function getSavePath($fileName, $saveDir) { - return $saveDir ? rtrim($saveDir, '\\/') . '/' . $fileName : $fileName; - } - - /** - * 判断是否有上传文件 - * @param string $tmp_name - * @return boolean - */ - protected function isUploadFile($tmp_name) { - if (!$tmp_name || $tmp_name == 'none') { - return false; - } elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmp_name) && !is_uploaded_file(str_replace('\\\\', '\\', $tmp_name))) { - return false; - } else { - return true; - } - } - - /** - * 初始化上传的文件信息 - * @param string $key - * @param string $value - * @param string $preFileName 前缀 - */ - protected function initUploadInfo($key, $value, $preFileName, $saveDir) { - $arr = array('attname' => $key, 'name' => $value['name'], 'size' => $value['size'], 'type' => $value['type'], 'ifthumb' => 0, 'fileuploadurl' => ''); - $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1)); - $arr['filename'] = $this->getFileName($arr, $preFileName); - $arr['fileuploadurl'] = $this->getSavePath($arr['filename'], $saveDir); - return $arr; - } - - - /** - * 判断是否使图片,如果使图片则返回 - * @param string $ext; - * @return boolean - */ - protected function isImage($ext) { - return in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'swf')); - } - - - /** - * 创建文件夹 - * @param string $path - * @return boolean - */ - protected function createFolder($path) { - if (!is_dir($path)) { - $this->createFolder(dirname($path)); - @mkdir($path); - @chmod($path, 0777); - @fclose(@fopen($path . '/index.html', 'w')); - @chmod($path . '/index.html', 0777); - } - return true; - } - - /** - * 执行上传操作 - * - * @param array $value - * @return array - */ - protected function doUp($key, $value, $saveDir, $preFileName) { - if (!$this->isUploadFile($value['tmp_name'])) return array(); - $upload = $this->initUploadInfo($key, $value, $preFileName, $saveDir); - - if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'])) { - $this->errorInfo['type'][$key][] = $upload; - $this->hasError = true; - return array(); - } - if (!$this->checkAllowSize($upload['ext'], $upload['size'])) { - $upload['maxSize'] = $this->allowType[$upload['ext']]; - $this->errorInfo['size'][$key][] = $upload; - $this->hasError = true; - return array(); - } - if (!($uploadSize = $this->postUpload($value['tmp_name'], $upload['fileuploadurl']))) { - $this->errorInfo['upload'][$key][] = $upload; - $this->hasError = true; - return array(); - } - $upload['size'] = intval($uploadSize); - return $upload; - } -} \ No newline at end of file diff --git a/wind/component/upload/WindCurlUpload.php b/wind/component/upload/WindCurlUpload.php deleted file mode 100644 index 65931c06..00000000 --- a/wind/component/upload/WindCurlUpload.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @author Qian Su - * @version $Id: WindCurlUpload.php 1710 2011-03-08 12:09:38Z weihu $ - * @package - * tags - */ -class WindCurlUpload extends AbstractWindUpload { - - public function upload($newName, $path) { - - } - - public function hasError() { - - } - - public function getErrorInfo($type = '') { - - } - - /* (non-PHPdoc) - * @see AbstractWindUpload::postUpload() - */ - protected function postUpload($tmp_name, $filename) { - // TODO Auto-generated method stub - - - } - -} \ No newline at end of file diff --git a/wind/component/upload/WindFormUpload.php b/wind/component/upload/WindFormUpload.php deleted file mode 100644 index 1d7d1445..00000000 --- a/wind/component/upload/WindFormUpload.php +++ /dev/null @@ -1,45 +0,0 @@ - 2011-7-18 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - * @package - */ -class WindFormUpload extends AbstractWindUpload { - - public function __construct($allowType = array()) { - $this->setAllowType($allowType); - } - - /* - * (non-PHPdoc) - * @see AbstractWindUpload::postUpload() - */ - protected function postUpload($tmp_name, $filename) { - if (strpos($filename, '..') !== false || strpos($filename, '.php.') !== false || preg_match('/\.php$/', $filename)) { - exit('illegal file type!'); - } - $this->createFolder(dirname($filename)); - if (function_exists("move_uploaded_file") && @move_uploaded_file($tmp_name, $filename)) { - @unlink($tmp_name); - @chmod($filename, 0777); - return filesize($filename); - } elseif (@copy($tmp_name, $filename)) { - @unlink($tmp_name); - @chmod($filename, 0777); - return filesize($filename); - } elseif (is_readable($tmp_name)) { - Wind::import('WIND:component.utility.WindFile'); - WindFile::write($filename, WindFile::read($tmp_name)); - @unlink($tmp_name); - if (file_exists($filename)) { - @chmod($filename, 0777); - return filesize($filename); - } - } - return false; - } - -} \ No newline at end of file diff --git a/wind/component/upload/WindFtpUpload.php b/wind/component/upload/WindFtpUpload.php deleted file mode 100644 index a44f712c..00000000 --- a/wind/component/upload/WindFtpUpload.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @author xiaoxiao - * @version 2011-7-29 xiaoxiao - */ -class WindFtpUpload extends AbstractWindUpload { - private $config = array(); - - private $ftp = null; - - public function __construct($config) { - $this->setConfig($config); - } - - /** - * (non-PHPdoc) - * @see AbstractWindUpload::postUpload() - */ - protected function postUpload($tmp_name, $filename) { - $ftp = $this->getFtpConnection(); - if (!($size = $ftp->upload($tmp_name, $filename))) return false; - @unlink($tmp_name); - return $size; - } - - /** - * 设置配置文件 - * @param array $config - * @return bool - */ - public function setConfig($config) { - if (!is_array($config)) return false; - $this->config = $config; - return true; - } - - /** - * 获得ftp链接对象 - * @return AbstractWindFtp - */ - private function getFtpConnection() { - if (is_object($this->ftp)) return $this->ftp; - if (function_exists('ftp_connect')) { - Wind::import("COM:ftp.WindFtp"); - $this->ftp = new WindFtp($this->config); - return $this->ftp; - } - Wind::import("COM:ftp.WindSocketFtp"); - $this->ftp = new WindSocketFtp($this->config); - return $this->ftp; - } -} \ No newline at end of file diff --git a/wind/component/utility/WindArray.php b/wind/component/utility/WindArray.php deleted file mode 100644 index 6f8fe1ce..00000000 --- a/wind/component/utility/WindArray.php +++ /dev/null @@ -1,83 +0,0 @@ - 2010-11-7 - *@link http://www.phpwind.com - *@copyright Copyright © 2003-2110 phpwind.com - *@license - */ - -/** - * 数组工具类 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Su Qian - * @version $Id$ - * @package - */ -class WindArray { - - /** - * 按指定key合并两个数组 - * @param string key 合并数组的参照值 - * @param array $array1 要合并数组 - * @param array $array2 要合并数组 - * @return array 返回合并的数组 - */ - public static function mergeArrayWithKey($key, array $array1, array $array2) { - if (!$key || !$array1 || !$array2) { - return array(); - } - $array1 = self::rebuildArrayWithKey($key, $array1); - $array2 = self::rebuildArrayWithKey($key, $array2); - $tmp = array(); - foreach ($array1 as $key => $array) { - if (isset($array2[$key])) { - $tmp[$key] = array_merge($array, $array2[$key]); - unset($array2[$key]); - } else { - $tmp[$key] = $array; - } - } - return array_merge($tmp, (array) $array2); - } - - /** - * 按指定key合并两个数组 - * @param string key 合并数组的参照值 - * @param array $array1 要合并数组 - * @param array $array2 要合并数组 - * @return array 返回合并的数组 - */ - public static function filterArrayWithKey($key, array $array1, array $array2) { - if (!$key || !$array1 || !$array2) { - return array(); - } - $array1 = self::rebuildArrayWithKey($key, $array1); - $array2 = self::rebuildArrayWithKey($key, $array2); - $tmp = array(); - foreach ($array1 as $key => $array) { - if (isset($array2[$key])) { - $tmp[$key] = array_merge($array, $array2[$key]); - } - } - return $tmp; - } - - /** - * 按指定KEY重新生成数组 - * @param string key 重新生成数组的参照值 - * @param array $array 要重新生成的数组 - * @return array 返回重新生成后的数组 - */ - public static function rebuildArrayWithKey($key, array $array) { - if (!$key || !$array) { - return array(); - } - $tmp = array(); - foreach ($array as $_array) { - if (isset($_array[$key])) { - $tmp[$_array[$key]] = $_array; - } - } - return $tmp; - } -} \ No newline at end of file diff --git a/wind/component/utility/WindFile.php b/wind/component/utility/WindFile.php deleted file mode 100644 index 80e8b9c3..00000000 --- a/wind/component/utility/WindFile.php +++ /dev/null @@ -1,254 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - */ -class WindFile { - - /** - * @var string 以读的方式打开文件,具有较强的平台移植性 - */ - const READ = 'rb'; - - /** - * @var string 以读写的方式打开文件,具有较强的平台移植性 - */ - const READWRITE = 'rb+'; - - /** - * @var string 以写的方式打开文件,具有较强的平台移植性 - */ - const WRITE = 'wb'; - - /** - * @var string 以读写的方式打开文件,具有较强的平台移植性 - */ - const WRITEREAD = 'wb+'; - - /** - * @var string 以追加写入方式打开文件,具有较强的平台移植性 - */ - const APPEND_WRITE = 'ab'; - - /** - * @var string 以追加读写入方式打开文件,具有较强的平台移植性 - */ - const APPEND_WRITEREAD = 'ab+'; - - /** - * 保存文件 - * @param string $fileName 保存的文件名 - * @param mixed $data 保存的数据 - * @param boolean $isBuildReturn 是否组装保存的数据是return $params的格式,如果没有则以变量声明的方式保存 - * @param string $method 打开文件方式 - * @param boolean $ifLock 是否对文件加锁 - */ - public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = 'rb+', $ifLock = true) { - $temp = " $value) { - if (!preg_match('/^\w+$/', $key)) - continue; - $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n"; - } - $temp .= "\r\n?>"; - } else { - ($isBuildReturn) && $temp .= " return "; - $temp .= WindString::varToString($data) . ";\r\n?>"; - } - return self::write($fileName, $temp, $method, $ifLock); - } - - /** - * 写文件 - * - * @param string $fileName 文件绝对路径 - * @param string $data 数据 - * @param string $method 读写模式 - * @param bool $ifLock 是否锁文件 - * @param bool $ifCheckPath 是否检查文件名中的“..” - * @param bool $ifChmod 是否将文件属性改为可读写 - * @return int 返回写入的字节数 - */ - public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) { - $fileName = WindSecurity::escapePath($fileName); - touch($fileName); - if (!$handle = fopen($fileName, $method)) - return false; - $ifLock && flock($handle, LOCK_EX); - $writeCheck = fwrite($handle, $data); - $method == self::READWRITE && ftruncate($handle, strlen($data)); - fclose($handle); - $ifChmod && chmod($fileName, 0777); - return $writeCheck; - } - - /** - * 读取文件 - * - * @param string $fileName 文件绝对路径 - * @param string $method 读取模式 - * @return string - */ - public static function read($fileName, $method = self::READ) { - $fileName = WindSecurity::escapePath($fileName); - $data = ''; - if (false !== ($handle = fopen($fileName, $method))) { - flock($handle, LOCK_SH); - $data = fread($handle, filesize($fileName)); - fclose($handle); - } - return $data; - } - - /** - * 按目录删除文件 - * @param string $dir 目录 - * @param boolean $ifexpiled 是否过期 - * @deprecated - * @return boolean - */ - public static function clearDir($dir, $ifexpiled = false) { - //TODO 删除掉是否过期相关处理,不要将外部业务需求,耦合进工具库方法 - if (!$handle = @opendir($dir)) - return false; - while (false !== ($file = readdir($handle))) { - if ('.' === $file[0] || '..' === $file[0]) - continue; - $fullPath = $dir . DIRECTORY_SEPARATOR . $file; - if (is_dir($fullPath)) { - self::clearDir($fullPath, $ifexpiled); - } else if (($ifexpiled && ($mtime = filemtime($fullPath)) && $mtime < time()) || !$ifexpiled) { - self::delFile($fullPath); - } - } - closedir($handle); - false === $ifexpiled && rmdir($dir); - return true; - } - - /** - * 批量删除文件 - * @param string $path - * @param string $delDir - * @param int $level - * @return string - */ - public static function delFiles($path, $delDir = false, $level = 0) { - $path = rtrim($path, DIRECTORY_SEPARATOR); - if (!$handler = opendir($path)) { - return false; - } - while (false !== ($filename = readdir($handler))) { - if ("." != $filename && ".." != $filename) { - if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { - if (substr($filename, 0, 1) != '.') { - self::delFiles($path . DIRECTORY_SEPARATOR . $filename, $delDir, $level + 1); - } - } else { - self::delFile($path . DIRECTORY_SEPARATOR . $filename); - } - } - } - closedir($handler); - true == $delDir && $level > 0 && rmdir($path); - return true; - } - - /** - * 取得文件的mime类型 - * @param string $fileName 文件名 - * @return string - */ - public static function getMimeType($fileName) { - //TODO WindMimeTypes.php 被删掉了,有bug - $suffix = self::getFileSuffix($fileName); - $mimes = require WIND_PATH . '/component/utility/WindMimeTypes.php'; - if (isset($mimes[$suffix])) { - return is_array($mimes[$suffix]) ? current($mimes[$suffix]) : $mimes[$suffix]; - } else { - throw new WindException('Sorry, can not find the corresponding mime type of the file'); - } - return false; - } - - /** - * 取得目录的迭代 - * @param string $dir 目录名 - * @return DirectoryIterator - */ - public static function getDirectoryIterator($dir) { - return new DirectoryIterator($dir); - } - - /** - * 取得文件信息 - * @param unknown_type $fileName - * @return string|number - */ - public static function getFileInfo($fileName) { - if (false === is_file($fileName)) { - return array(); - } - $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); - $fileInfo['path'] = $fileName; - $fileInfo['size'] = filesize($fileName); - $fileInfo['ctime'] = filectime($fileName); - $fileInfo['atime'] = fileatime($fileName); - $fileInfo['mtime'] = filemtime($fileName); - $fileInfo['readable'] = is_readable($fileName); - $fileInfo['writable'] = is_writable($fileName); - $fileInfo['executable'] = is_executable($fileName); - $fileInfo['right'] = fileperms($fileName); - $fileInfo['group'] = filegroup($fileName); - $fileInfo['owner'] = fileowner($fileName); - $fileInfo['mime'] = self::getMimeType($fileName); - return $fileInfo; - } - - /** - * 取得目录信息 - * @param unknown_type $dir - * @return string|multitype: - */ - public static function getDirectoryInfo($dir) { - if (false !== is_dir($dir)) { - return array(); - } - return stat($dir); - } - - /** - * 删除文件 - * @param string $filename - * @return boolean - */ - public static function delFile($filename) { - return @unlink($filename); - } - - /** - * 取得文件后缀 - * @param string $filename - * @return string - */ - public static function getFileSuffix($filename) { - $filename = explode($filename, '.'); - return $filename[count($filename) - 1]; - } - - /** - * 取得真实的目录 - * @param string $path 路径名 - * @return string - */ - public static function appendSlashesToDir($path) { - return rtrim($path, '\\/') . DIRECTORY_SEPARATOR; - } - -} \ No newline at end of file diff --git a/wind/component/utility/WindHtmlHelper.php b/wind/component/utility/WindHtmlHelper.php deleted file mode 100644 index a2850db7..00000000 --- a/wind/component/utility/WindHtmlHelper.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHtmlHelper { - - /** - * Convert special characters to HTML entities - * - * @param string $text | - * @return string | string The converted string - */ - public static function encode($text) { - return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); - } - - /** - * Convert special characters to HTML entities - * - * @param array $data - * @return array - */ - public static function encodeArray($data) { - $_tmp = array(); - $_charset = Wind::getApp()->getRequest()->getCharset(); - foreach ($data as $key => $value) { - if (is_string($key)) - $key = htmlspecialchars($key, ENT_QUOTES, $_charset); - if (is_string($value)) - $value = htmlspecialchars($value, ENT_QUOTES, $_charset); - elseif (is_array($value)) - $value = self::encodeArray($value); - $_tmp[$key] = $value; - } - return $_tmp; - } - -} - -?> \ No newline at end of file diff --git a/wind/component/utility/WindImage.php b/wind/component/utility/WindImage.php deleted file mode 100644 index 25935081..00000000 --- a/wind/component/utility/WindImage.php +++ /dev/null @@ -1,303 +0,0 @@ - - * @author xiaoxiao - * @version 2011-8-10 xiaoxiao - */ -class WindImage { - - /** - * 生成略缩图 - * - * @param string $srcFile 源图片 - * @param string $dstFile 略缩图保存位置 - * @param int $dstW 略缩图宽度 - * @param string $dstH 略缩图高度 - * @param string $isProportion 略缩图是否等比略缩 - * @return array|boolean - */ - public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) { - if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false; - list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']); - if (!$imagecreate) return false; - $imgwidth = $minitemp['width']; - $imgheight = $minitemp['height']; - - $srcX = $srcY = $dstX = $dstY =0; - if (!$isProportion) { - $dsDivision = $imgheight / $imgwidth; - $fixDivision = $dstH / $dstW; - if ($dsDivision > $fixDivision) { - $tmp = $imgwidth * $fixDivision; - $srcY = round(($imgheight - $tmp) / 2); - $imgheight = $tmp; - } else { - $tmp = $imgheight / $fixDivision; - $srcX = round(($imgwidth - $tmp) / 2); - $imgwidth = $tmp; - } - } - $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']); - - if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) { - $black = imagecolorallocate($thumb, 0, 0, 0); - imagecolortransparent($thumb, $black); - } - $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight); - self::makeImg($minitemp['type'], $thumb, $dstFile); - imagedestroy($thumb); - return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']); - } - - /** - * 给图片制作水印 - * 水印的位置可以为: - * array(0 => '随机位置', 1 => '顶部居左', 2 => '顶部居中', 3 => '顶部居右', 4 => '底部居左', 5 => '底部居中', 6 => '底部居右', 7 => '中心位置') - * - * @param string $source - * @param int|array $waterPos 水印的位置 - * @param string $waterImg 图片水印:水印图片的位置 - * @param string $waterText 水印的文字 - * @param array $attribute 文字水印的属性,只对文字水印有效 - * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小') - * - * @param string $waterPct 水印透明度,从0到100,0完全透明,100完全不透明 - * @param string $waterQuality 图片质量--jpeg - * @param string $dstsrc 目标文件位置 - * @return boolean - */ - public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) { - $sourcedb = $waterdb = array(); - if (false === ($sourcedb = self::getImgInfo($source))) return false; - if (!$waterImg && !$waterText) return false; - imagealphablending($sourcedb['source'], true); - if ($waterImg) { - $waterdb = self::getImgInfo($waterImg); - list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1); - if ($waterdb['type'] == 'png') { - $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']); - imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']); - imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']); - $sourcedb['source'] = $tmp; - } else { - imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct); - } - } elseif ($waterText) { - list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute); - empty($waterFont) && $waterFont = 12; - $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); //取得使用 TrueType 字体的文本的范围 - $waterdb['width'] = $temp[2] - $temp[6]; - $waterdb['height'] = $temp[3] - $temp[7]; - unset($temp); - list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2); - if (strlen($color) != 7) return false; - $R = hexdec(substr($color, 1, 2)); - $G = hexdec(substr($color, 3, 2)); - $B = hexdec(substr($color, 5)); - self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset); - imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText); - } - $dstsrc && $source = $dstsrc; - self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality); - isset($waterdb['source']) && imagedestroy($waterdb['source']); - imagedestroy($sourcedb['source']); - return true; - } - - /** - * 文字水印的属性设置过滤 - * 返回为: - * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小') - * @param array $attribute - * @return array - */ - private static function checkAttribute($attribute) { - $attribute = is_string($attribute) ? array($attribute) : $attribute; - if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8'; - if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000'; - if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12; - return $attribute; - } - - /** - * 判断是否需要转编码, - * 判断依据为,编码格式为utf-8 - * - * @param string $charset - * @return boolean - */ - private static function changeCharset($charset) { - $charset = strtolower($charset); - return !in_array($charset, array('utf8', 'utf-8')); - } - - /** - * 获得打水印的位置 - * 如果传入的是数组,则两个元素分别为水印的宽度x和高度y - * - * @param int|array $pos - * @param array $sourcedb - * @param array $waterdb - * @param int $markType 水印类型,1为图片水印,2为文字水印 - * @return array - */ - private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) { - if (is_array($waterPos)) return $waterPos; - $wX = $wY = 0; - switch (intval($waterPos)) { - case 0 : - $wX = rand(0, ($sourcedb['width'] - $waterdb['width'])); - $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']); - break; - case 1 : - $wX = 5; - $wY = $markType == 1 ? 5 : $waterdb['height']; - break; - case 2: - $wX = ($sourcedb['width'] - $waterdb['width']) / 2; - $wY = $markType == 1 ? 5 : $waterdb['height']; - break; - case 3: - $wX = $sourcedb['width'] - $waterdb['width'] - 5; - $wY = $markType == 1 ? 5 : $waterdb['height']; - break; - case 4: - $wX = 5; - $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; - break; - case 5: - $wX = ($sourcedb['width'] - $waterdb['width']) / 2; - $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; - break; - case 6: - $wX = $sourcedb['width'] - $waterdb['width'] - 5; - $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5; - break; - default: - $wX = ($sourcedb['width'] - $waterdb['width']) / 2; - $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2; - break; - } - return array($wX, $wY); - } - - /** - * 获得略缩图的信息 - * - * @param string $srcFile 源文件 - * @param int $dstW 目标文件的宽度 - * @param int $dstH 目标文件的高度 - * @param boolean $isProportion 是否定比略缩 - * @return array|boolean - */ - private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) { - if (false === ($imgdata = self::getImgInfo($srcFile))) return false; - if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false; - - $imgdata['dstW'] = $dstW; - $imgdata['dstH'] = $dstH; - if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) { - $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']); - } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) { - $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']); - } elseif ($dstW > 0 && $dstH > 0) { - if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) { - $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']); - } - if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) { - $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']); - } - } else { - $imgdata = false; - } - return $imgdata; - } - - /** - * 获得图片的信息,返回图片的源及图片的高度和宽度 - * - * @param string $srcFile 图像地址 - * @return array|boolean - */ - public static function getImgInfo($srcFile) { - if (false === ($imgdata = self::getImgSize($srcFile))) return false; - $imgdata['type'] = self::getTypes($imgdata['type']); - if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false; - $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type']; - $imgdata['source'] = $imagecreatefromtype($srcFile); - !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']); - !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']); - return $imgdata; - } - - /** - * 获得图片的类型及宽高 - *
-	 * 图片type:
-	 * 1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,
-	 * 11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
-	 * 
- * @param string $srcFile 图像地址 - * @param string $srcExt 图像后缀 - * @return array|boolean 返回图像的类型及高度和宽度 - */ - private static function getImgSize($srcFile, $srcExt = null) { - empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1)); - $srcdata = array(); - $exts = array('jpg', 'jpeg', 'jpe', 'jfif'); - in_array($srcExt, $exts) && $srcdata['type'] = 2; - if (false === ($info = getimagesize($srcFile))) return false; - list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info; - if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false; - return $srcdata; - } - - /** - * 获得创建图像的方法 - * - * @param string $imagetype 图片类型 - * @return array - */ - private static function getImgcreate($imagetype) { - if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) { - return array('imagecreatetruecolor', 'imagecopyresampled'); - } - if (function_exists('imagecreate') && function_exists('imagecopyresized')) { - return array('imagecreate', 'imagecopyresized'); - } - return array('', ''); - } - - /** - * 创建图像 - * - * @param string $type 图像类型 - * @param resource $image 图像源 - * @param string $filename 图像保存名字 - * @param int $quality 创建jpeg的时候用到 - * @return boolean - */ - private static function makeImg($type, $image, $filename, $quality = '75') { - $makeimage = 'image' . $type; - if (!function_exists($makeimage)) return false; - if ($type == 'jpeg') { - $makeimage($image, $filename, $quality); - } else { - $makeimage($image, $filename); - } - return true; - } - - /** - * 图片的对应类型 - * - * @param int $id 图片类型ID - * @return string - */ - private static function getTypes($id) { - $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp'); - return isset($imageTypes[$id]) ? $imageTypes[$id] : ''; - } -} \ No newline at end of file diff --git a/wind/component/utility/WindPack.php b/wind/component/utility/WindPack.php deleted file mode 100644 index e0b7aa6a..00000000 --- a/wind/component/utility/WindPack.php +++ /dev/null @@ -1,397 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - */ -class WindPack { - /** - * @var string 使用正则打包 - */ - const STRIP_SELF = 'stripWhiteSpaceBySelf'; - /** - * @var string 利用php自身的函数打包 - */ - const STRIP_PHP = 'stripWhiteSpaceByPhp'; - /** - * @var string 通过token方式打包 - */ - const STRIP_TOKEN = 'stripWhiteSpaceByToken'; - private $packList = array(); - private $contentInjectionPosition; - private $contentInjectionCallBack = ''; - - /** - * 将指定文件类型且指定文件夹下的所指定文件打包成一个易阅读的文件, - * @param mixed $dir 要打包的目录 - * @param string $dst 文件名 - * @param string $packMethod 打包方式 - * @param boolean $compress 是否压缩 - * @param string $absolutePath 文件路径 - * @param array $ndir 不须要打包的目录 - * @param array $suffix 不永许打包的文件类型 - * @return string - */ - public function packFromDir($dir, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { - if (empty($dst) || empty($dir)) { - return false; - } - $suffix = is_array($suffix) ? $suffix : array( - $suffix); - if (!($content = $this->readContentFromDir($packMethod, $dir, $absolutePath, $ndir, $suffix, $nfile))) { - return false; - } - $fileSuffix = WindFile::getFileSuffix($dst); - $replace = $compress ? ' ' : "\n"; - $content = implode($replace, $content); - $content = $this->callBack($content, $replace); - $content = $this->stripNR($content, $replace); - $content = $this->stripPhpIdentify($content, ''); - $content = $this->stripImport($content, ''); - $content = $this->getContentBySuffix($content, $fileSuffix, $replace); - WindFile::write($dst, $content); - return true; - } - - /** - * @param mixed $fileList - * @param string $dst - * @param method $packMethod - * @param boolean $compress - * @param string $absolutePath - * @return string|string - */ - public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true, $absolutePath = '') { - if (empty($dst) || empty($fileList)) { - return false; - } - $content = array(); - $this->readContentFromFileList($fileList, $packMethod, $absolutePath, $content); - $fileSuffix = WindFile::getFileSuffix($dst); - $replace = $compress ? ' ' : "\n"; - $content = implode($replace, $content); - $content = $this->callBack($content, $replace); - $content = $this->stripNR($content, $replace); - $content = $this->stripPhpIdentify($content, ''); - //$content = $this->stripImport($content, ''); - $content = $this->getContentBySuffix($content, $fileSuffix, $replace); - WindFile::write($dst, $content); - return true; - } - - /** - * 通过php自身方式去除指定文件的注释及空白 - * @param string $filename 文件名 - */ - public function stripWhiteSpaceByPhp($filename) { - return php_strip_whitespace($filename); - } - - /** - * 通过正则方式去除指定文件的注释及空白 - * @param string $filename - * @param boolean $compress - * @return string - */ - public function stripWhiteSpaceBySelf($filename, $compress = true) { - $content = $this->getContentFromFile($filename); - $content = $this->stripComment($content, ''); - return $this->stripSpace($content, ' '); - } - - /** - * 通过token方式去除指定文件的注释及空白 - * @param string $filename - * @return string - */ - public function stripWhiteSpaceByToken($filename) { - $content = $this->getContentFromFile($filename); - $compressContent = ''; - $lastToken = 0; - foreach (token_get_all($content) as $key => $token) { - if (is_array($token)) { - if (in_array($token[0], array( - T_COMMENT, - T_WHITESPACE, - T_DOC_COMMENT))) { - continue; - } - $compressContent .= ' ' . $token[1]; - } else { - $compressContent .= $token; - } - $lastToken = $token[0]; - } - return $compressContent; - } - - /** - * 从各个目录中取得对应的每个文件的内容 - * @param string $packMethod 打包方式 - * @param mixed $dir 目录名 - * @param string $absolutePath 绝对路径名 - * @param array $ndir 不须要打包的文件夹 - * @param array $suffix 不须要打包的文件类型 - * @param array $nfile 不须要打包的文件 - * @return array - */ - public function readContentFromDir($packMethod = WindPack::STRIP_PHP, $dir = array(), $absolutePath = '', $ndir = array('.','..','.svn'), $suffix = array(), $nfile = array()) { - static $content = array(); - if (empty($dir) || false === $this->isValidatePackMethod($packMethod)) { - return false; - } - $dir = is_array($dir) ? $dir : array( - $dir); - foreach ($dir as $_dir) { - $_dir = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $_dir : $_dir; - if (is_dir($_dir)) { - $handle = dir($_dir); - while (false != ($tmp = $handle->read())) { - $name = WindFile::appendSlashesToDir($_dir) . $tmp; - if (is_dir($name) && !in_array($tmp, $ndir)) { - $this->readContentFromDir($packMethod, $name, $absolutePath, $ndir, $suffix, $nfile); - } - if (is_file($name) && !in_array(WindFile::getFileSuffix($name), $suffix) && !in_array($file = basename($name), $nfile)) { - $content[] = $this->$packMethod($name); - $this->setPackList($file, $name); - } - } - $handle->close(); - } - } - return $content; - } - - /** - * 从文件列表中取得对应的每个文件的内容 - * @param mixed $fileList - * @param method $packMethod - * @param string $absolutePath - * @return array: - */ - public function readContentFromFileList($fileList, $packMethod = WindPack::STRIP_PHP, $absolutePath = '', &$content = array()) { - if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) { - return array(); - } - $fileList = is_array($fileList) ? $fileList : array( - $fileList); - foreach ($fileList as $key => $value) { - if (is_array($value) && isset($value[1])) { - $parents = class_parents($value[1]); - $_fileList = $this->buildFileList($parents, $fileList); - $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); - $implements = class_implements($value[1]); - $_fileList = $this->buildFileList($implements, $fileList); - $this->readContentFromFileList($_fileList, $packMethod, $absolutePath, $content); - if (key_exists($key, $this->getPackList())) continue; - $file = is_dir($absolutePath) ? WindFile::appendSlashesToDir($absolutePath) . $key : $key; - if (is_file($file)) { - $content[] = $this->$packMethod($file); - $this->setPackList($key, $value); - } - } - } - } - - /** - * 去除注释 - * @param string $content 要去除的内容 - * @param mixed $replace 要替换的文本 - * @return string - */ - public function stripComment($content, $replace = '') { - return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content); - } - - /** - * 去除换行 - * @param string $content 要去除的内容 - * @param mixed $replace 要替换的文本 - * @return string - */ - public function stripNR($content, $replace = array('\n','\r\n','\r')) { - return preg_replace('/[\n\r]+/', $replace, $content); - } - - /** - * 去除空格符 - * @param string $content 要去除的内容 - * @param mixed $replace 要替换的文本 - * @return string - */ - public function stripSpace($content, $replace = ' ') { - return preg_replace('/[ ]+/', $replace, $content); - } - - /** - * 去除php标识 - * @param string $content - * @param mixed $replace - * @return string - */ - public function stripPhpIdentify($content, $replace = '') { - return preg_replace('/(?:<\?(?:php)*)|(\?>)/i', $replace, $content); - } - - /** - * 根据指定规则替换指定内容中相应的内容 - * @param string $content - * @param string $rule - * @param $mixed $replace - * @return string - */ - public function stripStrByRule($content, $rule, $replace = '') { - return preg_replace("/$rule/", $replace, $content); - } - - /** - * 去除多余的文件导入信息 - * @param string $content - * @param mixed $replace - * @return string - */ - public function stripImport($content, $replace = '') { - $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content, $matchs); - if ($matchs[1]) { - foreach ($matchs[1] as $key => $value) { - $name = substr($value, strrpos($value, '.') + 1); - if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) { - $strip = str_replace(array( - '(', - ')'), array( - '\(', - '\)'), addslashes($matchs[0][$key])) . '[\t ]*;'; - $content = $this->stripStrByRule($content, $strip, $replace); - } - } - } - return $content; - } - - /** - * 取得被打包的文件列表 - * @return array: - */ - public function getPackList() { - return $this->packList; - } - - /** - *从文件读取内容 - * @param string $filename 文件名 - * @return string - */ - public function getContentFromFile($filename) { - if (is_file($filename)) { - $content = ''; - $fp = fopen($filename, "r"); - while (!feof($fp)) { - $line = fgets($fp); - if (in_array(strlen($line), array( - 2, - 3)) && in_array(ord($line), array( - 9, - 10, - 13))) continue; - $content .= $line; - } - fclose($fp); - return $content; - } - return false; - } - - /** - * 根据文件后缀得取对应的mime内容 - * @param string $content 要打包的内容内容 - * @param string $suffix 文件后缀类型 - * @param string $replace - * @return string - */ - public function getContentBySuffix($content, $suffix, $replace = ' ') { - switch ($suffix) { - case 'php': - $content = ''; - break; - default: - $content = ''; - break; - } - return $content; - } - - private function buildFileList($list, $fileList) { - $_temp = array(); - foreach ($list as $fileName) { - foreach ($fileList as $key => $value) { - if ($value[1] == $fileName) { - $_temp[$key] = $value; - break; - } - } - } - return $_temp; - } - - /** - * @param $contentInjectionCallBack the $contentInjectionCallBack to set - * @param string $position 调用位置(before|after) - * @author Qiong Wu - */ - public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') { - if (!in_array($position, array( - 'before', - 'after'))) $position = 'before'; - $this->contentInjectionPosition = $position; - $this->contentInjectionCallBack = $contentInjectionCallBack; - } - - /** - * 回调函数调用 - * @param string $content - * @param string $replace - * @return string - */ - public function callBack($content, $replace = '') { - if ($this->contentInjectionCallBack !== '') { - $_content = call_user_func_array($this->contentInjectionCallBack, array( - $this->getPackList())); - if ($this->contentInjectionPosition == 'before') { - $content = $replace . $_content . $content; - } elseif ($this->contentInjectionPosition == 'after') { - $content .= $replace . $_content . $replace; - } - } - return $content; - } - - private function isValidatePackMethod($packMethod) { - return method_exists($this, $packMethod) && in_array($packMethod, array( - WindPack::STRIP_PHP, - WindPack::STRIP_SELF, - WindPack::STRIP_TOKEN)); - } - - /** - * 添加被打包的文件到列表 - * @param string $key - * @param string $value - */ - private function setPackList($key, $value) { - if (isset($this->packList[$key])) { - if (is_array($this->packList[$key])) { - array_push($this->packList[$key], $value); - } else { - $tmp_name = $this->packList[$key]; - $this->packList[$key] = array( - $tmp_name, - $value); - } - } else { - $this->packList[$key] = $value; - } - } -} diff --git a/wind/component/utility/WindSecurity.php b/wind/component/utility/WindSecurity.php deleted file mode 100644 index 2048283f..00000000 --- a/wind/component/utility/WindSecurity.php +++ /dev/null @@ -1,300 +0,0 @@ - - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSecurity { - - /** - * Convert special characters to HTML entities - * @param array $data - * @return array - */ - public static function escapeHTMLForArray($data) { - $_tmp = array(); - $_charset = Wind::getApp()->getRequest()->getCharset(); - foreach ($data as $key => $value) { - if (is_string($key)) - $key = htmlspecialchars($key, ENT_QUOTES, $_charset); - if (is_string($value)) - $value = htmlspecialchars($value, ENT_QUOTES, $_charset); - elseif (is_array($value)) - $value = self::escapeHTMLForArray($value); - $_tmp[$key] = $value; - } - return $_tmp; - } - - /** - * Convert special characters to HTML entities - * @param string $str - * @return string - */ - public static function escapeHTML($str) { - if (is_array($str)) - return self::escapeHTMLForArray($str); - return htmlspecialchars($str, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); - } - - /** - * 过滤标签 - * @param $param - * @return string - */ - public static function stripTags($str, $allowTags = "") { - return strip_tags($str, $allowTags); - } - - /** - * 路径转换 - * @param $fileName - * @param $ifCheck - * @return string - */ - public static function escapePath($fileName, $ifCheck = true) { - if (!self::_escapePath($fileName, $ifCheck)) { - throw new WindException('file name is illegal'); - } - return $fileName; - } - - /** - * 目录转换 - * @param string $dir - * @return string - */ - public static function escapeDir($dir) { - $dir = strtr($dir, - array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', - ';' => '')); - return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); - } - - /** - * 通用多类型转换 - * @param mixed $value - * @return mixed - */ - public static function escapeChar($value) { - if (is_array($value)) { - foreach ($value as $key => $sub) { - $value[$key] = self::escapeChar($sub); - } - } elseif (is_int($value)) { - $value = (int) $value; - } elseif (is_string($value)) { - $value = self::escapeString($value); - } - return $value; - } - - /** - * 字符转换 - * @param string $string - * @return string - */ - public static function escapeString($string) { - $string = strtr($string, - array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', - "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', - '>' => '>', '"' => '"', "'" => ''')); - return preg_replace( - array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), - array('', '&'), $string); - } - - /** - * 该函数可用于转义拥有特殊意义的字符,比如 SQL 中的 ( )、[ ] 以及 *。 - * @param string $string - * @return string - */ - public static function quotemeta($string) { - return quotemeta($string); - } - - /** - * 对字符串转义 - * @param string $value - * @return string - */ - public function checkInputValue($value, $key = '') { - if (is_int($value)) { - $value = (int) $value; - } elseif (is_string($value)) { - $value = "'" . addslashes($value) . "'"; - } elseif (is_float($value)) { - $value = (float) $value; - } elseif (is_object($value) || is_array($value)) { - $value = "'" . addslashes(serialize($value)) . "'"; - } - return $value; - } - - /** - * 对cookie/post/get方式的值添加反斜线 - * @param string $str - * @return string - */ - public static function addSlashesForInput($str) { - if (!get_magic_quotes_gpc()) { - $str = addslashes($str); - } - return $str; - } - - /** - * 对从db或者file里面读取的内容添加反斜线 - * @return string - */ - public static function addSlashesForOutput($str) { - if (!get_magic_quotes_runtime()) { - $str = addslashes($str); - } - return $str; - } - - /** - * 添加反斜线,转义字符 - * @param mixed $value 要处理的数组 - * @param boolean $gpc 是否是get/cookie/post传递过来的值 - * @param boolean $df 是否是database/file传递过来的值 - * @return string - */ - public static function addSlashes($value, $gpc = false, $df = false) { - if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable))) { - return $value; - } - if (is_string($value)) { - if (false === $gpc && true === $df) { - return self::addSlashesForOutput($value); - } - if (false === $df && true === $gpc) { - return self::addSlashesForInput($value); - } - return addslashes($value); - } - foreach ($value as $key => $_value) { - $value[$key] = self::addSlashes($_value, $gpc, $df); - } - return $value; - } - - /** - * 去除反 斜线 - * @param mixed $array - * @return string - */ - public static function stripSlashes($value) { - if (!$value) - return $value; - if (is_string($value)) - return stripslashes($value); - if (!is_array($value) && !($value instanceof Traversable)) - return $value; - foreach ($value as $key => $_value) { - $value[$key] = self::stripSlashes($_value); - } - return $value; - } - - /** - * 通用多类型混合转义函数 - * @param $var - * @param $strip - * @param $isArray - * @return mixture - */ - public static function sqlEscape($var, $strip = true, $isArray = false) { - if (is_array($var)) { - if (!$isArray) - return " '' "; - foreach ($var as $key => $value) { - $var[$key] = trim(self::sqlEscape($value, $strip)); - } - return $var; - } elseif (is_numeric($var)) { - return " '" . $var . "' "; - } else { - return " '" . addslashes($strip ? stripslashes($var) : $var) . "' "; - } - } - - /** - * 通过","字符连接数组转换的字符 - * @param $array - * @param $strip - * @return string - */ - public static function sqlImplode($array, $strip = true) { - return implode(',', self::sqlEscape($array, $strip, true)); - } - - /** - * 组装单条 key=value 形式的SQL查询语句值 insert/update - * @param $array - * @param $strip - * @return string - */ - public static function sqlSingle($array, $strip = true) { - if (!is_array($array)) - return ''; - $array = self::sqlEscape($array, $strip, true); - $str = ''; - foreach ($array as $key => $val) { - $str .= ($str ? ', ' : ' ') . self::sqlMetadata($key) . '=' . $val; - } - return $str; - } - - /** - * 组装多条 key=value 形式的SQL查询语句 insert - * @param $array - * @param $strip - * @return string - */ - public static function sqlMulti($array, $strip = true) { - if (!is_array($array)) { - return ''; - } - $str = ''; - foreach ($array as $val) { - if (!empty($val) && is_array($val)) { - $str .= ($str ? ', ' : ' ') . '(' . self::sqlImplode($val, $strip) . ') '; - } - } - return $str; - } - - /** - * 过滤SQL元数据,数据库对象(如表名字,字段等) - * @param $data 元数据 - * @param $tlists 白名单 - * @return string 经过转义的元数据字符串 - */ - public static function sqlMetadata($data, $tlists = array()) { - if (empty($tlists) || !in_array($data, $tlists)) { - $data = str_replace(array('`', ' '), '', $data); - } - return ' `' . $data . '` '; - } - - /** - * 私用路径转换 - * @param string $fileName - * @param boolean $ifCheck - * @return boolean - */ - private static function _escapePath($fileName, $ifCheck = true) { - $tmpname = strtolower($fileName); - $tmparray = array('://' => '', "\0" => ''); - $ifCheck && $tmparray['..'] = ''; - if (strtr($tmpname, $tmparray) != $tmpname) { - return false; - } - return true; - } - -} \ No newline at end of file diff --git a/wind/component/utility/WindString.php b/wind/component/utility/WindString.php deleted file mode 100644 index eb41cd5e..00000000 --- a/wind/component/utility/WindString.php +++ /dev/null @@ -1,242 +0,0 @@ - 2010-12-17 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * 字符串格式化 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindString { - const UTF8 = 'utf8'; - const GBK = 'gbk'; - /** - * 截取字符串 - * @param string $string 要截取的字符串编码 - * @param int $start 开始截取 - * @param int $length 截取的长度 - * @param string $charset 原妈编码 - * @param boolean $dot 是否显示省略号 - * @return string 截取后的字串 - */ - public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) { - return self::UTF8 == $charset ? self::utf8_substr($string, $start, $length, $dot) : self::gbk_substr( - $string, $start, $length, $dot); - } - - /** - * 求取字符串长度 - * @param string $string 要计算的字符串编码 - * @param string $charset 原始编码 - * @return int - */ - public static function strlen($string, $charset = self::UTF8) { - $len = strlen($string); - $i = $count = 0; - while ($i < $len) { - ord($string[$i]) > 129 ? self::UTF8 == $charset ? $i += 3 : $i += 2 : $i++; - $count++; - } - return $count; - } - - /** - * 将变量的值转换为字符串 - * - * @param mixed $input 变量 - * @param string $indent 缩进 - * @return string - */ - public static function varToString($input, $indent = '') { - switch (gettype($input)) { - case 'string': - return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'"; - case 'array': - $output = "array(\r\n"; - foreach ($input as $key => $value) { - $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString( - $value, $indent . "\t"); - $output .= ",\r\n"; - } - $output .= $indent . ')'; - return $output; - case 'boolean': - return $input ? 'true' : 'false'; - case 'NULL': - return 'NULL'; - case 'integer': - case 'double': - case 'float': - return "'" . (string) $input . "'"; - } - return 'NULL'; - } - - public static function jsonEncode($value) { - if (!function_exists('json_encode')) { - Wind::import('Wind:component.utility.json.WindEncoder'); - return WindDecoder::decode($value); - } - return json_encode($value); - } - - public static function jsonDecode($value) { - if (!function_exists('json_decode')) { - Wind::import('Wind:component.utility.json.WindEncoder'); - return WindEncoder::encode($value); - } - return json_decode($value); - } - - public static function jsonSimpleEncode($var) { - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - case 'NULL': - return 'null'; - case 'integer': - return (int) $var; - case 'double': - case 'float': - return (float) $var; - case 'string': - return '"' . addslashes( - str_replace(array("\n", "\r", "\t"), '', addcslashes($var, '\\"'))) . '"'; - case 'array': - if (count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - $properties = array(); - foreach ($var as $name => $value) { - $properties[] = self::jsonSimpleEncode(strval($name)) . ':' . self::jsonSimpleEncode( - $value); - } - return '{' . join(',', $properties) . '}'; - } - $elements = array_map(array('WindString', 'jsonSimpleEncode'), $var); - return '[' . join(',', $elements) . ']'; - } - return false; - } - - /** - * 以utf8格式截取的字符串编码 - * @param string $string 要截取的字符串编码 - * @param int $start 开始截取 - * @param int $length 截取的长度 - * @param boolean $dot 是否显示省略号 - * @return string - */ - public static function utf8_substr($string, $start, $length = null, $dot = false) { - if (empty($string) || !is_int($start) || ($length && !is_int($length))) { - return ''; - } - $strlen = strlen($string); - $length = $length ? $length : $strlen; - $substr = ''; - $chinese = $word = 0; - for ($i = 0, $j = 0; $i < $start; $i++) { - if (0xa0 < ord(substr($string, $j, 1))) { - $chinese++; - $j += 2; - } else { - $word++; - } - $j++; - } - $start = $word + 3 * $chinese; - for ($i = $start, $j = $start; $i < $start + $length; $i++) { - if (0xa0 < ord(substr($string, $j, 1))) { - $substr .= substr($string, $j, 3); - $j += 2; - } else { - $substr .= substr($string, $j, 1); - } - $j++; - } - (strlen($substr) < $strlen) && $dot && $substr .= "..."; - return $substr; - } - - /** - * 以utf8求取字符串长度 - * @param string $str 要计算的字符串编码 - * @return number - */ - public static function utf8_strlen($str) { - $i = $count = 0; - $len = strlen($str); - while ($i < $len) { - $chr = ord($str[$i]); - $count++; - $i++; - if ($i >= $len) - break; - if ($chr & 0x80) { - $chr <<= 1; - while ($chr & 0x80) { - $i++; - $chr <<= 1; - } - } - } - return $count; - } - - /* 以gbk格式截取的字符串编码 - * @param string $string 要截取的字符串编码 - * @param int $start 开始截取 - * @param int $length 截取的长度 - * @param boolean $dot 是否显示省略号 - * @return string - */ - public static function gbk_substr($string, $start, $length = null, $dot = false) { - if (empty($string) || !is_int($start) || ($length && !is_int($length))) { - return ''; - } - $strlen = strlen($string); - $length = $length ? $length : $strlen; - $substr = ''; - $chinese = $word = 0; - for ($i = 0, $j = 0; $i < $start; $i++) { - if (0xa0 < ord(substr($string, $j, 1))) { - $chinese++; - $j++; - } else { - $word++; - } - $j++; - } - $start = $word + 2 * $chinese; - for ($i = $start, $j = $start; $i < $start + $length; $i++) { - if (0xa0 < ord(substr($string, $j, 1))) { - $substr .= substr($string, $j, 2); - $j++; - } else { - $substr .= substr($string, $j, 1); - } - $j++; - } - (strlen($substr) < $strlen) && $dot && $substr .= "..."; - return $substr; - } - - /** - * 以gbk求取字符串长度 - * @param string $str 要计算的字符串编码 - * @return number - */ - public static function gbk_strlen($string) { - $len = strlen($string); - $i = $count = 0; - while ($i < $len) { - ord($string[$i]) > 129 ? $i += 2 : $i++; - $count++; - } - return $count; - } -} \ No newline at end of file diff --git a/wind/component/utility/WindUtility.php b/wind/component/utility/WindUtility.php deleted file mode 100644 index c6edf86c..00000000 --- a/wind/component/utility/WindUtility.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindUtility { - - /** - * 递归合并两个数组 - * - * @param array $array1 - * @param array $array2 - * @return array - */ - public static function mergeArray($array1, $array2) { - foreach ($array2 as $key => $value) { - if (!isset($array1[$key]) || !is_array($array1[$key])) { - $array1[$key] = $value; - continue; - } - $array1[$key] = self::mergeArray($array1[$key], $array2[$key]); - } - return $array1; - } - - /** - * 将字符串首字母小写 - * - * @param string $str - * @return string - */ - public static function lcfirst($str) { - if (function_exists('lcfirst')) - return lcfirst($str); - - $str[0] = strtolower($str[0]); - return $str; - } - - /** - * 获得随机数字符串 - * - * @param int $length - * @return string - */ - public static function generateRandStr($length) { - $randstr = ""; - for ($i = 0; $i < (int) $length; $i++) { - $randnum = rand(0, 61); - if ($randnum < 10) { - $randstr .= chr($randnum + 48); - } else if ($randnum < 36) { - $randstr .= chr($randnum + 55); - } else { - $randstr .= chr($randnum + 61); - } - } - return $randstr; - } - - /** - * 通用组装测试验证规则 - * - * @param string $field | 验证字段名称 - * @param string $validator | 验证方法 - * @param array $args | 参数 - * @param string $default | 默认值 - * @param string $message | 错误信息 - * @return array - */ - public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { - return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, - 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); - } - -} - -?> \ No newline at end of file diff --git a/wind/component/utility/WindValidator.php b/wind/component/utility/WindValidator.php deleted file mode 100644 index 67523f58..00000000 --- a/wind/component/utility/WindValidator.php +++ /dev/null @@ -1,344 +0,0 @@ - 2010-12-22 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindValidator { - - /** - * 验证是否是电话号码 - * 国际区号-地区号-电话号码的格式(在国际区号前可以有前导0和前导+号), - * 国际区号支持0-4位 - * 地区号支持0-6位 - * 电话号码支持4到12位 - * - * @param string $phone 被验证的电话号码 - * @return boolean - */ - public static function isTelPhone($phone) { - return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone); - } - - /** - * 验证是否是手机号码 - * 国际区号-手机号码 - * - * @param string $number - * @return boolean - */ - public static function isTelNumber($number) { - return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number); - } - - /** - * 验证是否是QQ号码 - * - * @param string $qq - * @return boolean - */ - public static function isQQ($qq) { - return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq); - } - - /** - * 验证是否是邮政编码 - * - * @param string $zipcode - * @return boolean - */ - public static function isZipcode($zipcode) { - return 0 < preg_match('/^\d{4,8}$/', $zipcode); - } - - /** - * 验证是否是有合法的email - * @param string $string 被搜索的 字符串 - * @param array $matches 会被搜索的结果 - * @param boolean $ifAll 是否进行全局正则表达式匹配 - * @return boolean - */ - public static function hasEmail($string, &$matches = array(), $ifAll = false) { - return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string, $matches, $ifAll); - } - - /** - * 验证是否是合法的email - * @param string $string - * @return boolean - */ - public static function isEmail($string) { - return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string); - } - - /** - * 验证是否有合法的身份证号 - * @param string $string 被搜索的 字符串 - * @param array $matches 会被搜索的结果 - * @param boolean $ifAll 是否进行全局正则表达式匹配 - * @return boolean - */ - public static function hasIdCard($string, &$matches = array(), $ifAll = false) { - return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll); - } - - /** - * 验证是否是合法的身份证号 - * @param string $string - * @return boolean - */ - public static function isIdCard($string) { - return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string); - } - - /** - * 验证是否有合法的URL - * @param string $string 被搜索的 字符串 - * @param array $matches 会被搜索的结果 - * @param boolean $ifAll 是否进行全局正则表达式匹配 - * @return boolean - */ - public static function hasUrl($string, &$matches = array(), $ifAll = false) { - return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll); - } - - /** - * 验证是否是合法的url - * @param string $string - * @return boolean - */ - public static function isUrl($string) { - return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string); - } - - /** - * 验证是否有中文 - * @param string $string 被搜索的 字符串 - * @param array $matches 会被搜索的结果 - * @param boolean $ifAll 是否进行全局正则表达式匹配 - * @return boolean - */ - public static function hasChinese($string, &$matches = array(), $ifAll = false) { - return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll); - } - - /** - * 验证是否是中文 - * @param string $string - * @return boolean - */ - public static function isChinese($string) { - return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string); - } - - /** - * 验证是否有html标记 - * @param string $string 被搜索的 字符串 - * @param array $matches 会被搜索的结果 - * @param boolean $ifAll 是否进行全局正则表达式匹配 - * @return boolean - */ - public static function hasHtml($string, &$matches = array(), $ifAll = false) { - return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll); - } - - /** - * 验证是否是合法的html标记 - * @param string $string - * @return boolean - */ - public static function isHtml($string) { - return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string); - } - - /** - * 验证是否有合法的ipv4地址 - * @param string $string 被搜索的 字符串 - * @param array $matches 会被搜索的结果 - * @param boolean $ifAll 是否进行全局正则表达式匹配 - * @return boolean - */ - public static function hasIpv4($string, &$matches = array(), $ifAll = false) { - return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll); - } - - /** - * 验证是否是合法的IP - * @param string $string - * @return boolean - */ - public static function isIpv4($string) { - return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string); - } - - /** - * 验证是否有合法的ipV6 - * - * @param string $string - * @param array $matches - * @param boolean $ifAll - * @return boolean - */ - public static function hasIpv6($string, &$matches = array(), $ifAll = false) { - return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}| - ::([a-f0-9]{1,4}:){5}| - ([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}| - (([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}| - (([a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){2}| - (([a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| - (([a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: - )([a-f0-9]{1,4}:[a-f0-9]{1,4}| - (([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} - ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) - )|((([a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| - (([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: - ) - )\Z/ix', $string, $matches, $ifAll); - } - - /** - * 验证是否是合法的ipV6 - * - * @param string $string - * @return boolean - */ - public static function isIpv6($string) { - return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}| - ::(?:[a-f0-9]{1,4}:){5}| - (?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}| - (?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}| - (?:(?:[a-f0-9]{1,4}:){0,2}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){2}| - (?:(?:[a-f0-9]{1,4}:){0,3}[a-f0-9]{1,4})?::[a-f0-9]{1,4}:| - (?:(?:[a-f0-9]{1,4}:){0,4}[a-f0-9]{1,4})?:: - )(?:[a-f0-9]{1,4}:[a-f0-9]{1,4}| - (?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3} - (?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) - )|(?:(?:(?:[a-f0-9]{1,4}:){0,5}[a-f0-9]{1,4})?::[a-f0-9]{1,4}| - (?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?:: - ) - )\Z/ix', $string); - } - - /** - * 验证是否有客户端脚本 - * @param string $string 被搜索的 字符串 - * @param array $matches 会被搜索的结果 - * @param boolean $ifAll 是否进行全局正则表达式匹配 - * @return boolean - */ - public static function hasScript($string, &$matches = array(), $ifAll = false) { - return 0 < self::validateByRegExp('/([^\x00]*?)<\/script>/', $string, $matches, $ifAll); - } - - /** - * 验证是否是合法的客户端脚本 - * @param string $string - * @return boolean - */ - public static function isScript($string) { - return 0 < preg_match('/(?:[^\x00]*?)<\/script>/', $string); - } - - /** - * 判断是否为空 - * @param string $value - * @return boolean - */ - public static function isEmpty($value) { - return empty($value); - } - - /** - * 验证是否是非负整数 - * @param int $number - * @return boolean - */ - public static function isNonNegative($number) { - return 0 <= (int) $number; - } - - /** - * 验证是否是正数 - * @param int $number - * @return boolean - */ - public static function isPositive($number) { - return 0 < (int) $number; - } - - /** - * 验证是否是负数 - * @param int $number - * @return boolean - */ - public static function isNegative($number) { - return 0 > (int) $number; - } - - /** - * 判断一个元素是否是数组 - * @param mixed $array - * @return boolean - */ - public static function isArray($array) { - return is_array($array); - } - - /** - * 验证是否是不能为空 - * - * @param mixed $value - * @return boolean - */ - public static function isRequired($value) { - return !self::isEmpty($value); - } - - /** - * 判断一个值是否在指定数组中 - * - * @param mixed $needle - * @param array $array - * @param boolean $strict - * @return boolean - */ - public static function inArray($needle, array $array, $strict = true) { - return in_array($needle, $array, $strict); - } - - /** - * 验证字符串的长度 - * @param string $string 要验证的字符串 - * @param string $length 指定的合法的长度 - * @param string $charset 字符编码 - * @return boolean - */ - public static function isLegalLength($string, $length, $charset = 'utf8') { - Wind::import('WIND:component.utility.WindString'); - return WindString::strlen($string, $charset) > (int) $length; - } - - /** - * 在 $string 字符串中搜索与 $regExp 给出的正则表达式相匹配的内容。 - * @param string $regExp 搜索的规则(正则) - * @param string $string 被搜索的 字符串 - * @param array $matches 会被搜索的结果 - * @param boolean $ifAll 是否进行全局正则表达式匹配 - * @return number - */ - private static function validateByRegExp($regExp, $string, &$matches = array(), $ifAll = false) { - if (true === $ifAll) { - return preg_match_all($regExp, $string, $matches); - } - return preg_match($regExp, $string, $matches); - } - -} \ No newline at end of file diff --git a/wind/component/utility/date/WindDate.php b/wind/component/utility/date/WindDate.php deleted file mode 100644 index 7c714a28..00000000 --- a/wind/component/utility/date/WindDate.php +++ /dev/null @@ -1,272 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -/** - * 日期的换算与计算 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindDate { - /** - * 获取时区 - * @return string - */ - public static function getTimeZone() { - return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e'); - } - /** - * 设置时区 - * @param string $timezone 时区 - */ - public static function setTimezone($timezone) { - function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}"); - } - /** - * 格式化输出 - * @param string $format 格式化 - * @param int $dateTime unix时间戳 - * @return string - */ - public static function format($format = null, $dateTime = null) { - return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime)); - } - /** - * 获取日期的某部分 - * @param string $interval 字符串表达式 ,时间间隔类型 - * @param mixed $dateTime 表示日期的文字 - * @return string 返回日期的某部分 - */ - public static function datePart($interval, $dateTime = null) { - return date($interval, self::getTimeStamp($dateTime)); - } - /** - * 获取两个日期的差 - * @param string $interval 返回两个日期差的间隔类型 - * @param mixed $startDateTime 开始日期 - * @param mixed $endDateTime 结束日期 - * @return string - */ - public static function dateDiff($interval, $startDateTime, $endDateTime) { - $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime); - $retval = 0; - switch ($interval) { - case "y": - $retval = bcdiv($diff, (60 * 60 * 24 * 365));break; - case "m": - $retval = bcdiv($diff, (60 * 60 * 24 * 30));break; - case "w": - $retval = bcdiv($diff, (60 * 60 * 24 * 7));break; - case "d": - $retval = bcdiv($diff, (60 * 60 * 24));break; - case "h": - $retval = bcdiv($diff, (60 * 60));break; - case "n": - $retval = bcdiv($diff, 60);break; - case "s": - default:$retval = $diff;break; - } - return $retval; - } - /** - * 返回向指定日期追加指定间隔类型的一段时间间隔后的日期 - * @param string $interval 字符串表达式,是所要加上去的时间间隔类型。 - * @param int $value 数值表达式,是要加上的时间间隔的数目。其数值可以为正数(得到未来的日期),也可以为负数(得到过去的日期)。 - * @param string $dateTime 表示日期的文字,这一日期还加上了时间间隔。 - * @param mixed $format 格式化输出 - * @return string 返回追加后的时间 - */ - public static function dateAdd($interval, $value, $dateTime, $format = null) { - $date = getdate(self::getTimeStamp($dateTime)); - switch ($interval) { - case "y": - $date["year"] += $value;break; - case "q": - $date["mon"] += ($value * 3);break; - case "m": - $date["mon"] += $value;break; - case "w": - $date["mday"] += ($value * 7);break; - case "d": - $date["mday"] += $value;break; - case "h": - $date["hours"] += $value;break; - case "n": - $date["minutes"] += $value;break; - case "s": - default:$date["seconds"] += $value;break; - } - return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"])); - } - /** - * 得到一年中每个月真实的天数 - * @param string $year 需要获得的月份天数的年份 - * @return array 每月的天数组成的数组 - */ - public static function getRealDaysInMonthsOfYear($year) { - $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); - if (self::isLeapYear($year)) { - $months[1] = 29; - } - return $months; - } - /** - * 获取该月的天数 - * @param int $month 月份 - * @param int $year 年份 - * @return int - */ - public static function getDaysInMonth($month, $year) { - if (1 > $month || 12 < $month) { - return 0; - } - if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) { - return 0; - } - return $daysInmonths[$month - 1]; - } - /** - * 获取该年的天数 - * @return int - */ - public static function getDaysInYear($year) { - return self::isLeapYear($year) ? 366 : 365; - } - /** - * 取得RFC格式的日期与时间 - * @return string - */ - public static function getRFCDate($date = null) { - $time = $date ? is_int($date) ? $date : strtotime($date) : time(); - $tz = date('Z', $time); - $tzs = ($tz < 0) ? '-' : '+'; - $tz = abs($tz); - $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60; - return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz); - } - /** - * 取得中国日期时间 - * @param int $time - * @return string - */ - public static function getChinaDate($time = null) { - list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i',$time ? $time : time())); - return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i); - } - /** - * 取得中国的星期 - * @param int $week 处国人的星期,是一个数值 - * @return string - */ - public static function getChinaWeek($week = null) { - $week = $week ? $week : (int) date('w', time()); - $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"); - return $weekMap[$week]; - } - /** - * 取得一天中的时段 - * @param int $hour 小时 - * @return string - */ - public static function getPeriodOfTime($hour = null) { - $hour = $hour ? $hour : (int) date('G', time()); - $period = ''; - if (0 <= $hour && 6 > $hour) { - $period = '凌晨'; - } elseif (6 <= $hour && 8 > $hour) { - $period = '早上'; - } elseif (8 <= $hour && 11 > $hour) { - $period = '上午'; - } elseif (11 <= $hour && 13 > $hour) { - $period = '中午'; - } elseif (13 <= $hour && 15 > $hour) { - $period = '响午'; - } elseif (15 <= $hour && 18 > $hour) { - $period = '下午'; - } elseif (18 <= $hour && 20 > $hour) { - $period = '傍晚'; - } elseif (20 <= $hour && 22 > $hour) { - $period = '晚上'; - } elseif (22 <= $hour && 23 >= $hour) { - $period = '深夜'; - } - return $period; - } - /** - * 获取UTC日期格式 - * @param mixed $dateTime - * @return string - */ - public static function getUTCDate($dateTime = null) { - $oldTimezone = self::getTimezone(); - if ('UTC' !== strtoupper($oldTimezone)) { - self::setTimezone('UTC'); - } - $date = date('D, d M y H:i:s e',self::getTimeStamp($dateTime)); - if ('UTC' !== strtoupper($oldTimezone)) { - self::setTimezone($oldTimezone); - } - return $date; - } - /** - * 获取微秒数 - * @return number - */ - public static function getMicroTime($get_as_float = null,$mircrotime = null) { - return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float = null))); - } - /** - * 判断是否是闰年 - * @param int $year - * @return string - */ - public static function isLeapYear($year) { - if (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400) { - return true; - } - return false; - } - public static function getTimeStamp($dateTime = null){ - return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time(); - } - - /** - * @param int $time 当前时间戳 - * @param int $timestamp 比较的时间戳 - * @param string $format 格式化当前时间戳 - * @param array $type 要返回的时间类型 - * @return array - */ - public static function getLastDate($time,$timestamp = null,$format = null,$type = 1) { - $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' =>'前天'); - $timestamp = $timestamp ? $timestamp : time(); - $compareTime = strtotime(self::format('Y-m-d',$timestamp)); - $currentTime = strtotime(self::format('Y-m-d',$time)); - $decrease = $timestamp - $time; - $result = self::format($format,$time); - if (0 >= $decrease) { - return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); - } - if ($currentTime == $compareTime) { - if (1 == $type) { - if (60 >= $decrease) { - return array($decrease . $timelang['second'], $result); - } - return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(ceil($decrease / 3600) . $timelang['hour'], $result); - } - return array(self::format('H:i',$time), $result); - } elseif ($currentTime == $compareTime - 86400) { - return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i', $time), $result); - } elseif ($currentTime == $compareTime - 172800) { - return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i',$time), $result) : array(self::format('m-d H:i',$time), $result); - } elseif (strtotime(self::format('Y',$time)) == strtotime(self::format('Y',$timestamp))) { - return 1 == $type ? array(self::format('m-d',$time), $result) : array(self::format('m-d H:i',$time), $result); - } - return 1 == $type ? array(self::format('Y-m-d',$time), $result) : array(self::format('Y-m-d m-d H:i',$time), $result); - } -} \ No newline at end of file diff --git a/wind/component/utility/date/WindGeneralDate.php b/wind/component/utility/date/WindGeneralDate.php deleted file mode 100644 index 3e52d67a..00000000 --- a/wind/component/utility/date/WindGeneralDate.php +++ /dev/null @@ -1,248 +0,0 @@ - 2010-12-16 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -/** - * 是将日期转化为一个对象去操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - * tags - */ -class WindGeneralDate { - /** - * @var int 填充展示 - */ - const FILL = 0; - /** - * @var int 数字展示 - */ - const DIGIT = 1; - /** - * @var int 文本展示 - */ - const TEXT = 2; - /** - * @var string 默认格式化 - */ - const DEFAULT_FORMAT = 'Y-m-d H:i:s'; - /** - * @var int unix时间戳 - */ - private $time = 0; - - /** - * 根据输入的日期格式转化为时间戳进行属性time初始化 - * - * mktime函数,在只有输入一个年份的时候,就会默认转化为上一年的最后一天,输入一个月份并且缺省输入day的时候, - * 会转化为上个月的最后一天。所以这种情况需要注意。 - * 如果该构造函数没有参数传入的时候,得到的日期不是期望的当前日期,而是上两年的11月的30日 - * - * 如果月份为空:如果年份为空,则取当前月份;否则取1 - * 如果日期为空:如果年份为空,则取当前日期,否则取1 - * 如果小时为空:如果年份为空,则取当前小时 - * 如果分为空:如果年份为空,则取当前分 - * 如果秒为空:如果年份为空,则取当前秒 - * 如果年份为空:取当前年份 - * - * @param int $year 年 - * @param int $month 月 - * @param int $day 日 - * @param int $hours 小时 - * @param int $minutes 分 - * @param int $second 秒 - */ - public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) { - $time = time(); - !$month && ((!$year) ? $month = date('m', $time) : $month = 1); - !$day && ((!$year) ? $day = date('d', $time) : $day = 1); - !$hours && !$year && $hours = date('H', $time); - !$minutes && !$year && $minutes = date('i', $time); - !$second && !$year && $second = date('s', $time); - !$year && $year = date('Y', $time); - $this->time = mktime($hours, $minutes, $second, $month, $day, $year); - } - /** - * 获取当前时间所在月的天数 - * @return string - */ - public function getDaysInMonth() { - return date('t', $this->time); - } - /** - * 获取当前时间所在年的天数 - * @return int 如果是闰年返回366否则返回365 - */ - public function getDaysInYear() { - return $this->isLeapYear() ? 366 : 365; - } - /** - * 所表示当前日期是该年中的第几天。 - * @return int 返回时该年中的第几天 - */ - public function getDayOfYear() { - return date('z', $this->time) + 1; - } - /** - * 表示当前日期为该月中的第几天。 - * @return int - */ - public function getDayOfMonth() { - return date('j', $this->time); - } - /** - * 表示当前日期是该星期中的第几天。 - * @return int - */ - public function getDayOfWeek() { - return date('w', $this->time) + 1; - } - /** - * 判断当前日期所在年的第几周 - * @return int - */ - public function getWeekOfYear() { - return date('W', $this->time); - } - /** - * 获取当前日期的年份 - * @param boolean $format 是否返回四位格式的年份或是两位格式的年份 - * @return string - */ - public function getYear($format = true) { - return date($format ? 'Y' : 'y', $this->time); - } - /** - * 获当前日期的取月份 - * @param int $display 显示类型 - * @return string - */ - public function getMonth($display = self::FILL) { - if(self::FILL == $display){ - return date('m', $this->time); - }elseif(self::DIGIT == $display){ - return date('n', $this->time); - }elseif(self::TEXT == $display){ - return date('M', $this->time); - } - return date('n', $this->time); - } - /** - * 获取当前日期的天数 - * @param string $display 显示类型 - * @return string - */ - public function getDay($display = self::FILL) { - if(self::FILL == $display){ - return date('d', $this->time); - }elseif(self::DIGIT == $display){ - return date('j', $this->time); - }elseif(self::TEXT == $display){ - return date('jS', $this->time); - } - return date('j', $this->time); - } - /** - * 获取当前日期的星期 - * @param string $display 显示类型 - * @return string - */ - public function getWeek($display = self::FILL) { - if(self::FILL == $display || self::DIGIT == $display){ - return date('w', $this->time); - }elseif(self::TEXT == $display){ - return date('D', $this->time); - } - return date('N', $this->time); - } - /** - * 获取当前日期的12小时制时间 - * @param string $display 显示类型 - * @return string - */ - public function get12Hours($display = self::FILL){ - if(self::FILL == $display){ - return date('h', $this->time); - }elseif(self::DIGIT == $display){ - return date('g', $this->time);; - } - return date('h', $this->time); - } - /** - * 获取当前日期的24小时制时间 - * @param string $display 显示类型 - * @return string - */ - public function get24Hours($display = self::FILL){ - if(self::FILL == $display){ - return date('H', $this->time); - }elseif(self::DIGIT == $display){ - return date('G', $this->time);; - } - return date('H', $this->time); - } - /** - * 获取当前日期的分钟 - * @return string - */ - public function getMinutes() { - return date('i', $this->time); - } - /** - * 获取当前日期的秒数 - * @return string - */ - public function getSeconds() { - return date('s', $this->time); - } - /** - * 获取当前日期的本地时区 - * @return string - */ - public function getLocalTimeZone() { - return date('T', $this->time); - } - /** - * 重新设置当前日期与时间 - * @param string | int $time - */ - public function setTime($time) { - if (is_int($time) || (is_string($time)&& ($time = strtotime($time)))) { - $this->time = $time; - } - } - /** - * 取得当前日期时间对象 - * @return WindDate - */ - public function getNow() { - $date = getdate($this->time); - return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]); - } - /** - * 对象转化为字符串,魔术方法 - * @return string - */ - public function __toString() { - return $this->toString(); - } - /** - * 格式化时间输出 - * @param string $format 需要输出的格式 - * @return string - */ - public function toString($format = null) { - return date($format ? $format : self::DEFAULT_FORMAT, $this->time); - } - /** - * 判断是否是闰年 - * @return string 返回1或是0 - */ - public function isLeapYear() { - return date('L', $this->time); - } -} \ No newline at end of file diff --git a/wind/component/utility/json/WindDecoder.php b/wind/component/utility/json/WindDecoder.php deleted file mode 100644 index 17e3342b..00000000 --- a/wind/component/utility/json/WindDecoder.php +++ /dev/null @@ -1,235 +0,0 @@ - -* @author Matt Knapp -* @author Brett Stimmerman -* @copyright 2005 Michal Migurski -* @license http://www.opensource.org/licenses/bsd-license.php -* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 -*/ - -/** - * CJSON converts PHP data to and from JSON format. - * - * @author Michal Migurski - * @author Matt Knapp - * @author Brett Stimmerman - * @version $Id$ - * @package system.web.helpers - * @since 1.0 - */ -class WindDecoder { - const JSON_SLICE = 1; - const JSON_IN_STR = 2; - const JSON_IN_ARR = 4; - const JSON_IN_OBJ = 8; - const JSON_IN_CMT = 16; - public static function decode($str, $useArray = true) { - $str = strtolower(self::reduceString($str)); - if ('true' == $str) { - return true; - } elseif ('false' == $str) { - return false; - } elseif ('null' == $str) { - return null; - } elseif (is_numeric($str)) { - return (float)$str == (integer)$str ? (integer) $str : (float) $str; - }elseif(preg_match('/^("|\').+(\1)$/s', $str, $matche) && $matche[1] == $matche[2]){ - return self::jsonToString($str); - }elseif(preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)){ - return $useArray ? self::jsonToArray($str) : self::jsonToObject($str); - } - return false; - } - protected static function jsonToString($string) { - $delim = substr($string, 0, 1); - $chrs = substr($string, 1, -1); - $decodeStr = ''; - for ($c = 0,$length = strlen($chrs); $c < $length; ++$c) { - $compare = substr($chrs, $c, 2); - $ordCode = ord($chrs{$c}); - if('\b' == $compare){ - $decodeStr .= chr(0x08); - ++$c; - }elseif('\t' == $compare){ - $decodeStr .= chr(0x09); - ++$c; - }elseif('\n' == $compare){ - $decodeStr .= chr(0x0A); - ++$c; - }elseif('\f' == $compare){ - $decodeStr .= chr(0x0C); - ++$c; - }elseif('\r' == $compare){ - $decodeStr .= chr(0x0D); - ++$c; - }elseif(in_array($compare,array('\\"','\\\'','\\\\','\\/'))){ - if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) { - $decodeStr .= $chrs{++$c}; - } - }elseif(preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))){ - $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); - $decodeStr .= self::utf16beToUTF8($utf16); - $c += 5; - }elseif(0x20 <= $ordCode && 0x7F >= $ordCode){ - $decodeStr .= $chrs{$c}; - }elseif(0xC0 == ($ordCode & 0xE0)){ - $decodeStr .= substr($chrs, $c, 2); - ++$c; - }elseif(0xE0 == ($ordCode & 0xF0)){ - $decodeStr .= substr($chrs, $c, 3); - $c += 2; - }elseif(0xF0 == ($ordCode & 0xF8)){ - $decodeStr .= substr($chrs, $c, 4); - $c += 3; - }elseif(0xF8 == ($ordCode & 0xFC)){ - $decodeStr .= substr($chrs, $c, 5); - $c += 4; - }elseif(0xFC == ($ordCode & 0xFE)){ - $decodeStr .= substr($chrs, $c, 6); - $c += 5; - } - } - return $decodeStr; - } - protected static function jsonToArray($str) { - return self::complexConvert($str,true); - } - protected static function jsonToObject($str) { - return self::complexConvert($str,false); - } - protected static function complexConvert($str,$useArray = true){ - if ('[' == $str{0}) { - $stk = array(self::JSON_IN_ARR); - $arr = array(); - } else { - $obj = $useArray ? array() : new stdClass(); - $stk = array(self::JSON_IN_OBJ); - } - array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false)); - $chrs = substr($str, 1, -1); - $chrs = self::reduceString($chrs); - if ('' == $chrs) { - return self::JSON_IN_ARR == reset($stk) ? $arr : $obj; - } - for ($c = 0,$length = strlen($chrs); $c <= $length; ++$c) { - $top = end($stk); - $substr_chrs_c_2 = substr($chrs, $c, 2); - if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) { - $slice = substr($chrs, $top['where'], ($c - $top['where'])); - array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); - if (reset($stk) == self::JSON_IN_ARR) { - array_push($arr, self::decode($slice, $useArray)); - } elseif (reset($stk) == self::JSON_IN_OBJ) { - if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - $key = self::decode($parts[1], $useArray); - $useArray ? $obj[$key] = self::decode($parts[2], $useArray) : $obj->$key = self::decode($parts[2], $useArray); - } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - $useArray ? $obj[$parts[1]] = self::decode($parts[2], $useArray) : $obj->$parts[1] = self::decode($parts[2], $useArray); - } - } - - } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) { - array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); - } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) { - array_pop($stk); - } elseif (($chrs{$c} == '[') && in_array($top['what'], array(self::JSON_SLICE, - self::JSON_IN_ARR, self::JSON_IN_OBJ))) { - array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false)); - } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) { - array_pop($stk); - } elseif (($chrs{$c} == '{') && in_array($top['what'], array(self::JSON_SLICE, - self::JSON_IN_ARR, self::JSON_IN_OBJ))) { - array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false)); - } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) { - array_pop($stk); - } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(self::JSON_SLICE, - self::JSON_IN_ARR, self::JSON_IN_OBJ))) { - array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false)); - } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) { - array_pop($stk); - for ($i = $top['where']; $i <= ++$c; ++$i){ - $chrs = substr_replace($chrs, ' ', $i, 1); - } - } - - } - if (self::JSON_IN_ARR == reset($stk)) { - return $arr; - } elseif (self::JSON_IN_OBJ == reset($stk)) { - return $obj; - } - return false; - } - - protected static function unicodeToUTF8(&$str) { - $utf8 = ''; - foreach ($str as $unicode) { - if ($unicode < 128) { - $utf8 .= chr($unicode); - } elseif ($unicode < 2048) { - $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64)); - $utf8 .= chr(128 + ($unicode % 64)); - } else { - $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096)); - $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64)); - $utf8 .= chr(128 + ($unicode % 64)); - } - } - return $utf8; - } - - protected static function reduceString($str) { - return trim(preg_replace(array( - '#^\s*//(.+)$#m', - '#^\s*/\*(.+)\*/#Us', - '#/\*(.+)\*/\s*$#Us'), - '', $str)); - } - - protected static function utf16beToUTF8(&$str) { - return self::unicodeToUTF8(unpack('n*', $str)); - } - -} \ No newline at end of file diff --git a/wind/component/utility/json/WindEncoder.php b/wind/component/utility/json/WindEncoder.php deleted file mode 100644 index 289a7b63..00000000 --- a/wind/component/utility/json/WindEncoder.php +++ /dev/null @@ -1,202 +0,0 @@ - -* @author Matt Knapp -* @author Brett Stimmerman -* @copyright 2005 Michal Migurski -* @license http://www.opensource.org/licenses/bsd-license.php -* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 -*/ - -/** - * CJSON converts PHP data to and from JSON format. - * - * @author Michal Migurski - * @author Matt Knapp - * @author Brett Stimmerman - * @version $Id$ - * @package system.web.helpers - * @since 1.0 - */ -class WindEncoder { - public static $charset = 'utf-8'; - /** - * @param mixed $var - * @return string - */ - public static function encode($value) { - switch (gettype($value)) { - case 'boolean': - return $value ? 'true' : 'false'; - case 'NULL': - return 'null'; - case 'integer': - return (int) $value; - case 'double': - case 'float': - return (float) $value; - case 'string': - return self::stringToJson($value); - case 'array': - return self::arrayToJson($value); - case 'object': - return self::objectToJson($value); - default: - return ''; - } - return ''; - } - /** - * 将字符串转化成json格式对象 - * @param string $string - * @return string - */ - protected static function stringToJson($string) { - if ('UTF-8' !== ($enc = strtoupper(self::$charset))) { - $string = iconv($enc, 'UTF-8', $string); - } - $ascii = ''; - $strlen = strlen($string); - for ($c = 0; $c < $strlen; ++$c) { - $ordVar = ord($string{$c}); - if (0x08 == $ordVar) { - $ascii .= '\b'; - } elseif (0x09 == $ordVar) { - $ascii .= '\t'; - } elseif (0x0A == $ordVar) { - $ascii .= '\n'; - } elseif (0x0C == $ordVar) { - $ascii .= '\f'; - } elseif (0x0D == $ordVar) { - $ascii .= '\r'; - } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) { - $ascii .= '\\' . $string{$c}; - } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) { - $ascii .= $string{$c}; //ASCII - } elseif (0xC0 == ($ordVar & 0xE0)) { - $char = pack('C*', $ordVar, ord($string{++$c})); - $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); - } elseif (0xE0 == ($ordVar & 0xF0)) { - $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c})); - $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); - } elseif (0xF0 == ($ordVar & 0xF8)) { - $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); - $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); - } elseif (0xF8 == ($ordVar & 0xFC)) { - $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); - $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); - } elseif (0xFC == ($ordVar & 0xFE)) { - $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c}), ord($string{++$c})); - $ascii .= sprintf('\u%04s', bin2hex(self::utf8ToUTF16BE($char))); - } - } - return '"' . $ascii . '"'; - } - /** - * 将数组转化成json格式对象 - * @param array $array - * @return string - */ - protected static function arrayToJson(array $array) { - if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) { - return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($array), array_values($array))) . '}'; - } - return '[' . join(',', array_map(array('WindEncoder', 'encode'), $array)) . ']'; - } - /** - * 将对象转化成json格式对象 - * @param string $object - * @return string - */ - protected static function objectToJson($object) { - if ($object instanceof Traversable) { - $vars = array(); - foreach ($object as $k => $v) { - $vars[$k] = $v; - } - } else { - $vars = get_object_vars($object); - } - return '{' . join(',', array_map(array('WindEncoder', 'nameValue'), array_keys($vars), array_values($vars))) . '}'; - } - - protected static function nameValue($name, $value) { - return self::encode(strval($name)) . ':' . self::encode($value); - } - - protected static function utf8ToUTF16BE(&$string, $bom = false) { - $out = $bom ? "\xFE\xFF" : ''; - if (function_exists('mb_convert_encoding')) { - return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8'); - } - $uni = self::utf8ToUnicode($string); - foreach ($uni as $cp) { - $out .= pack('n', $cp); - } - return $out; - } - - protected static function utf8ToUnicode(&$string) { - $unicode = $values = array(); - $lookingFor = 1; - for ($i = 0, $length = strlen($string); $i < $length; $i++) { - $thisValue = ord($string[$i]); - if ($thisValue < 128) { - $unicode[] = $thisValue; - } else { - if (count($values) == 0) { - $lookingFor = ($thisValue < 224) ? 2 : 3; - } - $values[] = $thisValue; - if (count($values) == $lookingFor) { - $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64; - $values = array(); - $lookingFor = 1; - } - } - } - return $unicode; - } - -} \ No newline at end of file diff --git a/wind/component/viewer/AbstractWindTemplateCompiler.php b/wind/component/viewer/AbstractWindTemplateCompiler.php deleted file mode 100644 index 23e15608..00000000 --- a/wind/component/viewer/AbstractWindTemplateCompiler.php +++ /dev/null @@ -1,128 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class AbstractWindTemplateCompiler extends WindHandlerInterceptor { - - protected $tags = array(); - - /** - * @var WindViewTemplate - */ - protected $windViewTemplate = null; - - /** - * @var WindViewerResolver - */ - protected $windViewerResolver = null; - - protected $request = null; - - protected $response = null; - - /** - * 初始化标签解析器 - * @param string $tagContent - * @param WindViewTemplate $windViewTemplate - * @param WindViewerResolver $windViewerResolver - * @param WindHttpRequest $request - * @param WindHttpResponse $response - */ - public function __construct($tags, $windViewTemplate, $windViewerResolver, $request, $response) { - $this->tags = $tags; - $this->windViewTemplate = $windViewTemplate; - $this->windViewerResolver = $windViewerResolver; - $this->request = $request; - $this->response = $response; - } - - /** - * 模板编译方法 - * @param string $content | 模板内容 - * @param WindViewTemplate $windViewTemplate | 模板编译引擎 - * @return string | 输出编译后结果 - */ - abstract public function compile($key, $content); - - /** - * 编译前预处理 - */ - protected function preCompile() {} - - /** - * 编译后处理结果 - */ - protected function postCompile() {} - - /** - * 返回该标签支持的属性信息 - */ - protected function getProperties() { - return array(); - } - - /** - * 解析属性值 - * - * @param string $content - */ - protected function compileProperty($content) { - foreach ($this->getProperties() as $value) { - if ($value) { - preg_match('/(' . preg_quote($value) . '\s*=\s*([\'\"])?)[^\'\"\s]*(?=(\2)?)/i', - $content, $result); - if ($result) - $this->$value = trim(str_replace($result[1], '', $result[0])); - } - } - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - if ($this->windViewTemplate === null) - return; - $this->preCompile(); - foreach ($this->tags as $key => $value) { - if (!$value[0] || !$value[1]) - continue; - $this->compileProperty($value[1]); - $_output = $this->compile($value[0], $value[1]); - $this->windViewTemplate->setCompiledBlockData($value[0], $_output); - } - $this->postCompile(); - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() {} - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::handle() - */ - public function handle() { - $args = func_get_args(); - call_user_func_array(array($this, 'preHandle'), $args); - if (null !== ($handler = $this->interceptorChain->getHandler())) { - call_user_func_array(array($handler, 'handle'), $args); - } - call_user_func_array(array($this, 'postHandle'), $args); - } - - /** - * @return WindViewTemplate - */ - protected function getWindViewTemplate() { - return $this->windViewTemplate; - } - -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/AbstractWindViewTemplate.php b/wind/component/viewer/AbstractWindViewTemplate.php deleted file mode 100644 index fb8b9915..00000000 --- a/wind/component/viewer/AbstractWindViewTemplate.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -abstract class AbstractWindViewTemplate extends WindModule { - const SUPPORT_TAGS = 'support-tags'; - const TAG = 'tag'; - const REGEX = 'regex'; - const COMPILER = 'compiler'; - const PATTERN = 'pattern'; - - /** - * 对模板内容进行编译 - * @param string $content - * @param WindViewerResolver $windViewerResolver - */ - abstract protected function doCompile($content, $windViewerResolver = null); - - /** - * 进行视图渲染 - * - * - * @param string $templateFile | 模板文件 - * @param WindViewerResolver $windViewerResolver - */ - public function compile($templateFile, $windViewerResolver) { - $_output = $this->getTemplateFileContent($templateFile); - $_output = $this->compileDelimiter($_output); - $_output = $this->doCompile($_output, $windViewerResolver); - return $_output; - } - - /** - * @param string content - * @return string $content - */ - protected function compileDelimiter($content) { - $content = str_replace(array('', '#-->'), '?>', $content); - return $content; - } - - /** - * 获得模板文件内容,目前只支持本地文件获取 - * @param string $templateFile - */ - private function getTemplateFileContent($templateFile) { - $_output = ''; - if ($fp = @fopen($templateFile, 'r')) { - while (!feof($fp)) { - $_output .= fgets($fp, 4096); - } - fclose($fp); - } else - throw new WindViewException('Unable to open the template file \'' . $templateFile . '\'.'); - return $_output; - } - - /** - * 返回模板支持的标签 - * array('tagName'=>array('tag','compiler')) - * @return array - */ - protected function getTags() { - return $this->getConfig(self::SUPPORT_TAGS); - } -} -?> \ No newline at end of file diff --git a/wind/component/viewer/IWindView.php b/wind/component/viewer/IWindView.php deleted file mode 100644 index 8f80ff23..00000000 --- a/wind/component/viewer/IWindView.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindView { - - /** - * 视图渲染 - * - * @param WindForward $forward - * @param WindUrlBasedRouter $router - */ - public function render(); - -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/IWindViewerResolver.php b/wind/component/viewer/IWindViewerResolver.php deleted file mode 100644 index 994a92b6..00000000 --- a/wind/component/viewer/IWindViewerResolver.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -interface IWindViewerResolver { - - /** - * 设置视图变量信息 - * - * @param array $vars - * @param string $key - */ - public function windAssign($vars, $key = ''); - - /** - * 获取模板内容与变量信息 - */ - public function windFetch($template = ''); - -} \ No newline at end of file diff --git a/wind/component/viewer/WindLayout.php b/wind/component/viewer/WindLayout.php deleted file mode 100644 index 543e4ebc..00000000 --- a/wind/component/viewer/WindLayout.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindLayout extends WindModule { - /* 编译结果缓存 */ - protected $blockKey = ""; - /** - * 定义主题包的位置 - * @var string - */ - private $theme; - /** - * javascript集合 - * @var string - */ - private $script; - /** - * css 集合 - * @var string - */ - private $css; - /** - * 布局文件的位置 - * @var string - */ - private $layout; - /** - * @var array - */ - private $segments = array(); - /** - * @var WindViewerResolver - */ - private $viewer = null; - - /** - * @param string $layoutFile - */ - public function __construct($layoutFile = '') { - $this->setLayoutFile($layoutFile); - } - - /** - * 解析布局文件 - * @param WindViewerResolver $viewer - */ - public function parser($viewer) { - $this->viewer = $viewer; - $content = ''; - ob_start(); - if ($this->layout) { - list($tpl) = $this->viewer->compile($this->layout); - if (!@include ($tpl)) { - throw new WindViewException('[component.viewer.WindLayout.parser] layout file ' . $tpl, - WindViewException::VIEW_NOT_EXIST); - } - } else - $this->content(); - $content = ob_get_clean(); - foreach ($this->segments as $key => $value) { - if ($key) - $content = str_replace("", $value[1], $content); - } - $content = preg_replace('/(<\/body>)/i', $this->script . '\\1', $content); - //$content = preg_replace('/<\/head>/i', $this->css . '', $content); - return $content; - } - - /** - * 设置切片内容 - * @param string $template - */ - public function segment($template) { - $this->segments[$template] = $this->viewer->compile($template, '', true); - echo ""; - } - - /** - * 当前模板内容 - * @param string $template - */ - public function content() { - $template = $this->viewer->getWindView()->templateName; - $this->segment($template); - } - - /** - * @param string $theme - */ - public function setTheme($theme) { - $this->theme = $theme; - } - - /** - * @param string $layout - */ - public function setLayout($layout) { - $this->layout = $layout; - } - - /** - * @param string $script - */ - public function setScript($script) { - $this->script .= $script; - } - - /** - * @param string $css - */ - public function setCss($css) { - $this->css .= $css; - } - -} \ No newline at end of file diff --git a/wind/component/viewer/WindView.php b/wind/component/viewer/WindView.php deleted file mode 100644 index bd0dcd89..00000000 --- a/wind/component/viewer/WindView.php +++ /dev/null @@ -1,168 +0,0 @@ - - * - * - * - * - * - * - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindView extends WindModule implements IWindView { - /** - * 模板路径信息 - * - * @var string - */ - public $templateDir; - /** - * 模板文件的扩展名 - * - * @var string - */ - public $templateExt; - /** - * 模板名称 - * - * @var string - */ - public $templateName; - /** - * 是否对模板变量进行html字符过滤 - * @var boolean - */ - public $htmlspecialchars = true; - /** - * 是否开启模板编译 - * 00: 0 关闭,不进行模板编译 - * 01: 1 进行模板编译 - * @var boolean - */ - public $isCompile = 0; - /** - * 编译目录 - * @var string - */ - public $compileDir; - /** - * 编译脚本后缀 - * @var string - */ - public $compileExt = 'tpl'; - /** - * 布局文件 - * @var string - */ - public $layout; - /** - * 主题包目录 - * @var string - */ - public $theme; - - /** - * 视图解析引擎 - * @var WindViewerResolver - */ - protected $viewResolver = null; - - /** - * 视图渲染 - * @param boolean $display - */ - public function render($display = false) { - if (!$this->templateName) - return; - - //TODO 其他输出类型 - $viewResolver = $this->_getViewResolver($this); - $viewResolver->windAssign(Wind::getApp()->getResponse()->getData($this->templateName)); - if ($display === false) { - $this->getResponse()->setBody($viewResolver->windFetch(), $this->templateName); - } else - echo $viewResolver->windFetch(); - } - - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - if ($this->_config) { - $this->templateDir = $this->getConfig('template-dir', '', $this->templateDir); - $this->templateExt = $this->getConfig('template-ext', '', $this->templateExt); - $this->compileDir = $this->getConfig('compile-dir', '', $this->compileDir); - $this->compileExt = $this->getConfig('compile-ext', '', $this->compileExt); - $this->isCompile = $this->getConfig('is-compile', '', $this->isCompile); - $this->htmlspecialchars = $this->getConfig('htmlspecialchars', '', - $this->htmlspecialchars); - } - } - - /** - * 模板路径解析 - * 根据模板的逻辑名称,返回模板的绝对路径信息 - * - * @param string $templateName - * @param string $templateExt - * @return string | false - */ - public function getViewTemplate($template = '', $ext = '') { - if (!$template) { - $template = $this->templateName; - } - !$ext && $ext = $this->templateExt; - return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); - } - - /** - * 模板编译路径解析 - * 根据模板的逻辑名称,返回模板的绝对路径信息 - * - * @param string $templateName - * @param string $templateExt - * @return string | false - */ - public function getCompileFile($template = '') { - if (!$this->compileDir) - return; - if (!$template) { - $template = $this->templateName; - } - $dir = Wind::getRealDir($this->compileDir, true); - if (!is_dir($dir)) - throw new WindViewException( - '[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); - $_tmp = explode('.', $template); - foreach ($_tmp as $_dir) { - !is_dir($dir) && @mkdir($dir); - $dir .= DIRECTORY_SEPARATOR . $_dir; - } - return $this->compileExt ? $dir . '.' . $this->compileExt : $dir; - } - - /** - * @return WindViewerResolver - */ - public function getViewResolver() { - if (null !== $this->viewResolver) - return $this->viewResolver; - $this->_getViewResolver(); - $this->viewResolver->setWindView($this); - if (!$this->getIsCache()) - return $this->viewResolver; - $this->viewResolver = new WindClassProxy($this->viewResolver); - $listener = Wind::import('COM:viewer.listener.WindViewCacheListener'); - $this->viewResolver->registerEventListener('windFetch', new $listener($this)); - return $this->viewResolver; - } -} \ No newline at end of file diff --git a/wind/component/viewer/WindViewerResolver.php b/wind/component/viewer/WindViewerResolver.php deleted file mode 100644 index 8916f304..00000000 --- a/wind/component/viewer/WindViewerResolver.php +++ /dev/null @@ -1,187 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindViewerResolver extends WindModule implements IWindViewerResolver { - /** - * @var array - */ - protected $vars = array(); - /** - * @var WindView - */ - protected $windView = null; - - /** - * @var WindLayout - */ - protected $windLayout = null; - - /** - * @param WindView $windView - */ - public function __construct($windView = null) { - $this->windView = $windView; - } - - /* (non-PHPdoc) - * @see IWindViewerResolver::windFetch() - */ - public function windFetch($template = '') { - ob_start(); - if (!$template) { - $template = $this->windView->templateName; - $_tpl = $this->windView->getCompileFile($template); - if ($this->checkReCompile()) { - $layout = $this->getWindLayout(); - $layout->setLayout($this->windView->layout); - $layout->setTheme($this->windView->theme); - WindFile::write($_tpl, $layout->parser($this)); - } - } else - list($_tpl) = $this->compile($template); - - WindRender::render($_tpl, Wind::getApp()->getResponse()->getData($template), $this); - return ob_get_clean(); - } - - /* (non-PHPdoc) - * @see IWindViewerResolver::windAssign() - */ - public function windAssign($vars, $key = '') { - /*if ($key === '') - $key = $this->windView->templateName; - $this->vars[$key] = $vars;*/ - } - - /** - * 编译模板并返回编译后模板名称, - * $output==true: 直接返回编译结果,不将结果写入编译文件中 - * $output==false:返回编译文件地址 - * - * @param string $template - * @param string $suffix - * @param boolean $output - * @return string - */ - public function compile($template, $suffix = '', $output = false) { - $templateFile = $this->windView->getViewTemplate($template, $suffix); - if (!is_file($templateFile)) - throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, - WindViewException::VIEW_NOT_EXIST); - - $compileFile = $this->windView->getCompileFile($template); - if (!$this->checkReCompile()) - return array($compileFile, ''); - /* @var $_windTemplate WindViewTemplate */ - $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); - $_output = $_windTemplate->compile($templateFile, $this); - if ($output === false) { - $compileFile = $this->windView->getCompileFile($template); - WindFile::write($compileFile, $_output); - } - return array($compileFile, $_output); - } - - /** - * 检查是否需要重新编译,需要编译返回false,不需要编译返回true - * @return boolean - */ - private function checkReCompile() { - return WIND_DEBUG || $this->getWindView()->isCompile; - } - - /** - * 当前模板内容 - * @param string $template - */ - private function getContent($template = '') { - !$template && $template = $this->windView->templateName; - if ($template) - echo $this->windFetch($template); - } - - /** - * @return WindView - */ - public function getWindView() { - return $this->windView; - } - - /** - * @return WindLayout - */ - public function getWindLayout() { - return $this->_getWindLayout('', $this); - } - -} - -/** - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindRender { - - /** - * Convert special characters to HTML entities - * - * @param string $text | - * @return string | string The converted string - */ - public static function encode($text) { - return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); - } - - /** - * Convert special characters to HTML entities - * - * @param array $data - * @return array - */ - public static function encodeArray($data) { - $_tmp = array(); - $_charset = Wind::getApp()->getRequest()->getCharset(); - foreach ($data as $key => $value) { - if (is_string($key)) - $key = htmlspecialchars($key, ENT_QUOTES, $_charset); - if (is_string($value)) - $value = htmlspecialchars($value, ENT_QUOTES, $_charset); - elseif (is_array($value)) - $value = self::encodeArray($value); - $_tmp[$key] = $value; - } - return $_tmp; - } - - /** - * @param string $tpl - * @param array $vars - * @param WindViewerResolver $viewer - * @throws WindViewException - */ - public static function render($tpl, $vars, $viewer) { - @extract($vars, EXTR_REFS); - if (!@include ($tpl)) { - throw new WindViewException( - '[component.viewer.ViewerResolver.render] template name ' . $tpl, - WindViewException::VIEW_NOT_EXIST); - } - } -} \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerAction.php b/wind/component/viewer/compiler/WindTemplateCompilerAction.php deleted file mode 100644 index 801eb5c8..00000000 --- a/wind/component/viewer/compiler/WindTemplateCompilerAction.php +++ /dev/null @@ -1,40 +0,0 @@ - 标签解析脚本 - * 支持属性: action\controller - * - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindTemplateCompilerAction extends AbstractWindTemplateCompiler { - protected $action = ''; - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - return 'getComponent(\'forward\'); - $_tpl_forward->forwardAction(' . $this->action . '); - Wind::getApp()->doDispatch($_tpl_forward, true); ?>'; - } - - /** - * @return string - */ - public function getScript() { - $_tmp = '$_tpl_forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD);' . '$_tpl_forward->setDisplay(true);' . '$_tpl_forward->forwardAnotherAction(\'' . $this->action . '\', \'' . $this->controller . '\');' . '$_tpl_app = $this->getSystemFactory()->getInstance(COMPONENT_WEBAPP);' . '$_tpl_app->doDispatch($_tpl_forward);'; - return $_tmp; - } - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::getProperties() - */ - public function getProperties() { - return array('action'); - } - -} \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php b/wind/component/viewer/compiler/WindTemplateCompilerComponent.php deleted file mode 100644 index 27c9cdc3..00000000 --- a/wind/component/viewer/compiler/WindTemplateCompilerComponent.php +++ /dev/null @@ -1,149 +0,0 @@ - - * - * the last known user to change this file in the repository - * @author xiaoxiao - * @version 2011-7-20 xiaoxiao - */ -class WindTemplateCompilerComponent extends AbstractWindTemplateCompiler { - - protected $name = ''; //组件名字 - - - protected $args = ''; //传递给组件的参数 - - - protected $templateDir = ''; //组件调用的模板路径 - - - protected $appConfig = ''; //组件的配置文件 - - protected $appConfigSuffix = 'php';//配置文件的缺省格式 - - - protected $componentPath = ''; //组件的入口地址 - - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - return $this->getScript($content); - } - - /** - * @return string - */ - private function getScript($content) { - $params = $this->matchConfig($content); - if (!isset($params['name']) || !isset($params['componentPath'])) throw new WindException('组件编译错误!'); - $content = "rebuildConfig($params) . - (isset($params['args']) ? $this->registerUrlParams($params) : '') . - "\$componentPath = Wind::getRealDir('" . $params['componentPath'] . "');\r\n" . - "Wind::register(\$componentPath, '" . $params['name'] . "');\r\n" . - "Wind::run('" . $params['name'] . "', \$config);\r\n?>"; - return $content; - } - - /** - * 编译获得配置文件 - * @param array $params - * @return array - */ - private function rebuildConfig($params) { - $temp = "\$configParser = new WindConfigParser();\r\n" . - "\$configPath = Wind::getRealPath('" . $params['appConfig'] . "', '" . $params['suffix'] . "');\r\n" . - "\$config = \$configParser->parse(\$configPath);\r\n" . - "\$config = \$config['" . $params['name'] . "'];\r\n"; - if (!isset($params['templateDir'])) return $temp; - if (isset($params['args']['m'])) - $temp .= "\$config['modules']['" . $params['args']['m'] . "']['view']['config']['template-dir'] = '" . $params['templateDir'] . "';\r\n"; - else { - $temp .= "foreach(\$config['modules'] as \$key => \$value) {\r\n" . - "\t\$config['modules'][\$key]['view']['config']['template-dir'] = '" . $params['templateDir'] . "';\r\n" . - "}\r\n"; - } - return $temp; - } - - /** - * 注册变量信息 - * - * @param array $params - */ - private function registerUrlParams($params) { - $temp = "\$routerConfig = \$config['router']['config'];\r\n" . - "\$mKey = isset(\$routerConfig['module']['url-param']) ? \$routerConfig['module']['url-param'] : 'm';\r\n" . - "\$cKey = isset(\$routerConfig['controller']['url-param']) ? \$routerConfig['controller']['url-param'] : 'c';\r\n" . - "\$aKey = isset(\$routerConfig['action']['url-param']) ? \$routerConfig['action']['url-param'] : 'a';\r\n" . - "\$_GET[\$mKey] = '" . $params['args']['m'] . "';\r\n" . - "\$_GET[\$cKey] = '" . $params['args']['c'] . "';\r\n" . - "\$_GET[\$aKey] = '" . $params['args']['a'] . "';\r\n"; - unset($params['args']['a'], $params['args']['c'], $params['args']['m']); - foreach ($params['args'] as $key => $value) { - $temp .= "\$_GET['" . $key . "'] = " . (is_array($value) ? $value : "'" . $value . "'" ) . ";\r\n"; - } - return $temp; - } - - /** - * 匹配配置信息 - * - * @param string $content - * @return array - */ - private function matchConfig($content) { - preg_match_all('/(\w+=[\'|"]?[\w|.|:]+[\'|"]?)/', $content, $mathcs); - list($config, $key, $val) = array(array(), '', ''); - foreach ($mathcs[0] as $value) { - list($key, $val) = explode('=', $value); - if (!in_array($key, $this->getProperties()) || !$val) continue; - switch ($key) { - case 'args': - $config['args'] = $this->compileArgs(trim($val, '\'"')); - break; - default: - $config[$key] = trim($val, '\'"'); - break; - } - } - return $config; - } - - /** - * 解析传递给url的参数信息 - * - * @param string $arg - * @return array - */ - private function compileArgs($arg) { - $args = explode(':', $arg); - $urlParams = array(); - list($urlParams['a'], $urlParams['c'], $urlParams['m']) = array('', '', ''); - switch (count($args)) { - case 1: - $urlParams['a'] = $args[0]; - break; - case 2: - list($urlParams['c'], $urlParams['a']) = $args; - break; - case 3: - list($urlParams['m'], $urlParams['c'], $urlParams['a']) = $args; - break; - default: - break; - } - return $urlParams; - } - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::getProperties() - */ - protected function getProperties() { - return array('name', 'templateDir', 'appConfig', 'args', 'componentPath', 'suffix'); - } -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerCss.php b/wind/component/viewer/compiler/WindTemplateCompilerCss.php deleted file mode 100644 index e541f9c9..00000000 --- a/wind/component/viewer/compiler/WindTemplateCompilerCss.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindTemplateCompilerCss extends AbstractWindTemplateCompiler { - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - foreach ($this->windViewTemplate->getCompiledBlockData() as $key => $value) { - $content = str_replace('#' . $key . '#', ($value ? $value : ' '), $content); - } - $this->windViewerResolver->getWindLayout()->setcss($content); - return ''; - } -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php b/wind/component/viewer/compiler/WindTemplateCompilerEcho.php deleted file mode 100644 index d6cfa107..00000000 --- a/wind/component/viewer/compiler/WindTemplateCompilerEcho.php +++ /dev/null @@ -1,34 +0,0 @@ -a|text} //执行编译 - * {@templateName:var|html} - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindTemplateCompilerEcho extends AbstractWindTemplateCompiler { - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - $_output = preg_replace(array('/^[\n\s{\@]+/i', '/[\n\s}\;]+$/i'), array('', ''), $content); - list($_output, $type) = explode('|', $_output . '|'); - if (strpos($_output, '::') === false && strpos($_output, ':') !== false) { - list($_namespace, $_var) = explode(':', $_output); - $_output = 'Wind::getApp()->getResponse()->getData(\'' . $_namespace . '\', \'' . $_var . '\')'; - } - if (!strcasecmp($type, 'html')) - return ''; - else - return ''; - } -} -?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerInternal.php b/wind/component/viewer/compiler/WindTemplateCompilerInternal.php deleted file mode 100644 index 581b42c9..00000000 --- a/wind/component/viewer/compiler/WindTemplateCompilerInternal.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindTemplateCompilerInternal extends AbstractWindTemplateCompiler { - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - //TODO php脚本特别解析 - - - return $content; - } - -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerPage.php b/wind/component/viewer/compiler/WindTemplateCompilerPage.php deleted file mode 100644 index 9b9f7292..00000000 --- a/wind/component/viewer/compiler/WindTemplateCompilerPage.php +++ /dev/null @@ -1,77 +0,0 @@ - - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindTemplateCompilerPage extends AbstractWindTemplateCompiler { - protected $tpl = ''; - - protected $url = ''; - - protected $total = '0'; - - protected $page = '1'; - - protected $count = '0'; - - protected $per = '0'; - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - return $this->getPageCode(); - - } - - private function getPageCode() { - empty($this->total) && $this->total = '0'; - empty($this->page) && $this->page = '1'; - empty($this->count) && $this->count = '0'; - empty($this->per) && $this->per = '0'; - empty($this->url) && $this->url = ''; - $strPageCode = 'count . ';' . '$_tplPagePer=(int)' . $this->per . ';' . - '$_tplPageTotal=(int)' . $this->total . ';' . '$_tplPageCurrent=(int)' . $this->page . ';' . - '$_tplPageUrl=(string)"' . addslashes($this->url) . '";' . 'if ($_tplPageCount > 0 && $_tplPagePer > 0) {' . - '$_tplTmpPageTotal = ceil($_tplPageCount / $_tplPagePer);' . - 'if ($_tplPageTotal > $_tplTmpPageTotal) $_tplPageTotal = $_tplTmpPageTotal;' . '}' . - '$_tplPageCurrent > $_tplPageTotal && $_tplPageCurrent = $_tplPageTotal;' . 'if ($_tplPageTotal > 1) {' . - "?>\r\n" . $this->getTplContent() . "\r\n"; - return $strPageCode; - } - - private function getTplContent() { - if ($this->tpl) { - list($compileFile, $content) = $this->windViewerResolver->compile($this->tpl, '', true); - } else { - $content = $this->getDefaultHtml(); - } - return $this->parsePageTags($content); - } - - private function parsePageTags($content) { - $arrPageTags = array('$total', '$page', '$url', '$count'); - $arrPageVars = array('$_tplPageTotal', '$_tplPageCurrent', '$_tplPageUrl', '$_tplPageCount'); - return str_ireplace($arrPageTags, $arrPageVars, $content); - } - - private function getDefaultHtml() { - return ''; - } - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::getProperties() - */ - public function getProperties() { - return array('tpl', 'total', 'page', 'per', 'count', 'url'); - } -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerScript.php b/wind/component/viewer/compiler/WindTemplateCompilerScript.php deleted file mode 100644 index 3894f182..00000000 --- a/wind/component/viewer/compiler/WindTemplateCompilerScript.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindTemplateCompilerScript extends AbstractWindTemplateCompiler { - protected $compile = 'true'; - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - if ($this->compile === 'false') return $content; - foreach ($this->windViewTemplate->getCompiledBlockData() as $key => $value) { - $content = str_replace('#' . $key . '#', ($value ? $value : ' '), $content); - } - $this->windViewerResolver->getWindLayout()->setScript($content); - return ''; - } - - /** - * 返回该标签支持的属性信息 - */ - protected function getProperties() { - return array('compile'); - } - -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php deleted file mode 100644 index 21657455..00000000 --- a/wind/component/viewer/compiler/WindTemplateCompilerTemplate.php +++ /dev/null @@ -1,55 +0,0 @@ - - * source: 模板文件源地址 - * suffix: 模板文件后缀 - * load: 是否将编译内容加载到本模板中 - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindTemplateCompilerTemplate extends AbstractWindTemplateCompiler { - - protected $source = ''; - - protected $suffix = ''; - - protected $load = 'true'; - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::compile() - */ - public function compile($key, $content) { - if (!$this->source) - return $content; - - preg_match('/^{?\$(\w+)}?$/Ui', $this->source, $_tmp); - if (!empty($_tmp)) { - $_tpl = $this->windViewerResolver->getWindView()->templateName; - $this->source = Wind::getApp()->getResponse()->getData($_tpl, $_tmp[1]); - } - if ($this->load === 'false') { - list($compileFile) = $this->windViewerResolver->compile($this->source, $this->suffix); - if (!empty($_tmp)) - $compileFile = str_replace($this->source, '{$' . $_tmp[1] . '}', $compileFile); - $content = ''; - } else { - list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, - true); - } - return $content; - } - - /* (non-PHPdoc) - * @see AbstractWindTemplateCompiler::getProperties() - */ - public function getProperties() { - return array('source', 'suffix', 'load'); - } - -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/compiler/WindViewTemplate.php b/wind/component/viewer/compiler/WindViewTemplate.php deleted file mode 100644 index 35c5ce06..00000000 --- a/wind/component/viewer/compiler/WindViewTemplate.php +++ /dev/null @@ -1,190 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindViewTemplate extends AbstractWindViewTemplate { - - const COMPILER_ECHO = 'COM:viewer.compiler.WindTemplateCompilerEcho'; - - protected $compiledBlockData = array(); - - /** - * 模板编译器支持的标签信息 - * - * @var array('targName','args info') - */ - protected $_compilerCache = array(); - - protected $windHandlerInterceptorChain = null; - - /* (non-PHPdoc) - * @see AbstractWindViewTemplate::doCompile() - */ - protected function doCompile($content, $windViewerResolver = null) { - try { - $content = $this->registerTags($content, $windViewerResolver); - if ($this->windHandlerInterceptorChain !== null) { - $this->windHandlerInterceptorChain->getHandler()->handle(); - } - foreach (array_reverse($this->compiledBlockData) as $key => $value) { - if (!$key) - continue; - $content = str_replace($this->getBlockTag($key), ($value ? $value : ' '), $content); - } - $content = preg_replace('/\?>(\s|\n)*?<\?php/i', "\r\n", $content); - return $content; - } catch (Exception $e) { - throw new WindViewException('[component.viewer.WindViewTemplate.doCompile] compile fail.' . $e->getMessage(), - WindViewException::ERROR_SYSTEM_ERROR); - } - } - - /** - * 注册支持的标签并返回注册后的模板内容 - * @param string $content - * @param WindViewerResolver $windViewerResolver - * @return string - */ - private function registerTags($content, $windViewerResolver = null) { - foreach ((array) $this->getTags() as $key => $value) { - $compiler = isset($value[self::COMPILER]) ? $value[self::COMPILER] : ''; - $regex = isset($value[self::PATTERN]) ? $value[self::PATTERN] : ''; - $tag = isset($value[self::TAG]) ? $value[self::TAG] : ''; - if (!$compiler || !$tag) - continue; - if ($regex === '') - $regex = '/<(' . preg_quote($tag) . ')[^<>\n]*(\/>|>[^<>]*<\/\1>)/i'; - $content = $this->creatTagCompiler($content, $compiler, $regex, $windViewerResolver); - } - return $content; - } - - /** - * 创建标签解析器类 - * @param string content | 模板内容 - * @param string compiler | 标签编译器 - * @param string regex | 正则表达式 - * @param WindViewerResolver $windViewerResolver - */ - private function creatTagCompiler($content, $compiler, $regex, $windViewerResolver = null) { - $content = preg_replace_callback($regex, array($this, '_creatTagCompiler'), $content); - if ($this->windHandlerInterceptorChain === null) { - $this->windHandlerInterceptorChain = new WindHandlerInterceptorChain(); - } - $_compilerClass = Wind::import($compiler); - $this->windHandlerInterceptorChain->addInterceptors( - new $_compilerClass($this->_compilerCache, $this, $windViewerResolver, $this->getRequest(), - $this->getResponse())); - $this->_compilerCache = array(); - return $content; - } - - /* (non-PHPdoc) - * @see AbstractWindViewTemplate::getTags() - */ - protected function getTags() { - $_tags['internal'] = $this->createTag('internal', 'COM:viewer.compiler.WindTemplateCompilerInternal', - '/<\?php(.|\n)*?\?>/i'); - $_tags['template'] = $this->createTag('template', 'COM:viewer.compiler.WindTemplateCompilerTemplate'); - $_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', - '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); - $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); - /*标签体增加在该位置*/ - $_tags['page'] = $this->createTag('page', 'COM:viewer.compiler.WindTemplateCompilerPage'); - $_tags['action'] = $this->createTag('action', 'COM:viewer.compiler.WindTemplateCompilerAction'); - $_tags['script'] = $this->createTag('script', 'COM:viewer.compiler.WindTemplateCompilerScript', - '/()*/i'); - //$_tags['link'] = $this->createTag('link', 'COM:viewer.compiler.WindTemplateCompilerCss'); - //$_tags['style'] = $this->createTag('style', 'COM:viewer.compiler.WindTemplateCompilerCss'); - $_tags['component'] = $this->createTag('component', 'COM:viewer.compiler.WindTemplateCompilerComponent'); - /*标签解析结束*/ - $_tags += (array) parent::getTags(); - /*$_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', - '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); - $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i');*/ - return $_tags; - } - - /** - * 创建tag配置 - * @param string $tag - * @param string $class - */ - private function createTag($tag, $class, $pattern = '') { - return array(self::TAG => $tag, self::PATTERN => $pattern, self::COMPILER => $class); - } - - /** - * 将标签匹配到的模板内容设置到缓存中,并返回标识位到模板中进行内容站位 - * @param string $content - * @return string|Ambigous --> - */ - private function _creatTagCompiler($content) { - $_content = $content[0]; - if (!$_content) - return ''; - - $key = $this->getCompiledBlockKey(); - $this->_compilerCache[] = array($key, $_content); - return $this->getBlockTag($key); - } - - /** - * 对模板块存储进行标签处理 - * 将Key串 'HhQWFLtU0LSA3nLPLHHXMtTP3EfMtN3FsxLOR1nfYC5OiZTQri' 处理为 - * - * 在模板中进行位置标识 - * - * @param string $key | 索引 - * @return string|mixed | 处理后结果 - */ - private function getBlockTag($key) { - return '#' . $key . '#'; - } - - /** - * 获得切分后块编译缓存Key值,Key值为一个50位的随机字符串,当产生重复串时继续查找 - * @return string - */ - protected function getCompiledBlockKey() { - $key = WindUtility::generateRandStr(50); - if (key_exists($key, $this->compiledBlockData)) { - return $this->getCompiledBlockKey(); - } - return $key; - } - - /** - * 返回编译后结果,根据Key值检索编译后结果,并返回 - * @param string $key - * @return string - */ - public function getCompiledBlockData($key = '') { - if ($key) - return isset($this->compiledBlockData[$key]) ? $this->compiledBlockData[$key] : ''; - else - return $this->compiledBlockData; - } - - /** - * 根据key值保存编译后的模板块 - * @param string $key | 索引 - * @param string $compiledBlockData | 编译结果 - * @param boolean $isTag | 再结果处理时是否添加php脚本定界符 true 添加 ,flase 不添加 - */ - public function setCompiledBlockData($key, $compiledBlockData) { - if ($key) - $this->compiledBlockData[$key] = $compiledBlockData; - } - -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/errorPage/404.htm b/wind/component/viewer/errorPage/404.htm deleted file mode 100644 index b499243e..00000000 --- a/wind/component/viewer/errorPage/404.htm +++ /dev/null @@ -1,10 +0,0 @@ - - - - -Insert title here - - - - - \ No newline at end of file diff --git a/wind/component/viewer/errorPage/default_error.htm b/wind/component/viewer/errorPage/default_error.htm deleted file mode 100644 index 97e2593f..00000000 --- a/wind/component/viewer/errorPage/default_error.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -{@G:title} - - - -
- - - - -
-

{$errorHeader}:

-

- {$key}. {$error}
-

-

You Can Get Help In:

-

{@WindHelper::errorInfo()}

-
-
- - \ No newline at end of file diff --git a/wind/component/viewer/exception/WindViewException.php b/wind/component/viewer/exception/WindViewException.php deleted file mode 100644 index 59bfbd9c..00000000 --- a/wind/component/viewer/exception/WindViewException.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindViewException extends WindException { - - const VIEW_NOT_EXIST = '300'; - const COMPILE_NOT_EXIST = '400'; - - /** - * 自定义异常号的对应异常信息 - * - * @param int $code 异常号 - * @return string 返回异常号对应的异常组装信息原型 - */ - protected function messageMapper($code) { - $messages[self::VIEW_NOT_EXIST] = 'Not exist view template file or Incorrect file path \'$message\''; - $messages[self::COMPILE_NOT_EXIST] = 'Not exist view compile file or Incorrect file path \'$message\''; - return isset($messages[$code]) ? $messages[$code] : '$message'; - } -} - -?> \ No newline at end of file diff --git a/wind/component/viewer/listener/WindViewCacheListener.php b/wind/component/viewer/listener/WindViewCacheListener.php deleted file mode 100644 index 99a1eef6..00000000 --- a/wind/component/viewer/listener/WindViewCacheListener.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindViewCacheListener extends WindHandlerInterceptor { - - private $windView = null; - - /** - * Enter description here ... - * @param WindView $windView - */ - public function __construct($windView) { - $this->windView = $windView; - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::preHandle() - */ - public function preHandle() { - $data = $this->windView->getViewCache()->get($this->getKey()); - $data = !$data ? null : $data; - return $data; - } - - /** - * 获得保存的key值 - */ - private function getKey() { - $host = Wind::getApp()->getRequest()->getHostInfo(); - $uri = Wind::getApp()->getRequest()->getRequestUri(); - return $host.$uri . '/' . $this->windView->templateName . '.' . $this->windView->templateExt; - } - - /* (non-PHPdoc) - * @see WindHandlerInterceptor::postHandle() - */ - public function postHandle() { - $cache = $this->windView->getViewCache(); - $cache->set($this->getKey(), $this->result); - } -} - -?> \ No newline at end of file From 8dd7e57ea1212d1d056a7ec1a0665075d1e4637d Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 08:11:43 +0000 Subject: [PATCH 0430/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2502 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/utility/WindHtmlHelper.php | 43 --------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 wind/utility/WindHtmlHelper.php diff --git a/wind/utility/WindHtmlHelper.php b/wind/utility/WindHtmlHelper.php deleted file mode 100644 index a2850db7..00000000 --- a/wind/utility/WindHtmlHelper.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindHtmlHelper { - - /** - * Convert special characters to HTML entities - * - * @param string $text | - * @return string | string The converted string - */ - public static function encode($text) { - return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); - } - - /** - * Convert special characters to HTML entities - * - * @param array $data - * @return array - */ - public static function encodeArray($data) { - $_tmp = array(); - $_charset = Wind::getApp()->getRequest()->getCharset(); - foreach ($data as $key => $value) { - if (is_string($key)) - $key = htmlspecialchars($key, ENT_QUOTES, $_charset); - if (is_string($value)) - $value = htmlspecialchars($value, ENT_QUOTES, $_charset); - elseif (is_array($value)) - $value = self::encodeArray($value); - $_tmp[$key] = $value; - } - return $_tmp; - } - -} - -?> \ No newline at end of file From 766982f06839b92bd825111f801f80e64422f858 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 09:20:26 +0000 Subject: [PATCH 0431/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2503 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 173 ++++----- wind/base/WindClassProxy.php | 2 +- wind/base/WindEnableValidateModule.php | 2 +- wind/base/WindFactory.php | 5 +- wind/base/WindHelper.php | 2 +- wind/base/WindModule.php | 1 - wind/cache/AbstractWindCache.php | 2 +- .../dependency/WindDbCacheDependency.php | 4 +- .../dependency/WindFileCacheDependency.php | 2 +- wind/cache/strategy/WindApcCache.php | 2 +- wind/cache/strategy/WindDbCache.php | 4 +- wind/cache/strategy/WindEacceleratorCache.php | 2 +- wind/cache/strategy/WindFileCache.php | 4 +- wind/cache/strategy/WindMemCache.php | 2 +- wind/cache/strategy/WindWinCache.php | 2 +- wind/cache/strategy/WindXCache.php | 2 +- wind/cache/strategy/WindZendCache.php | 2 +- wind/components_config.php | 28 +- wind/dao/WindDaoFactory.php | 2 +- wind/dao/exception/WindDaoException.php | 2 +- wind/dao/listener/WindDaoCacheListener.php | 2 +- wind/db/WindConnection.php | 8 +- wind/db/WindConnectionManager.php | 4 +- wind/db/WindSqlStatement.php | 4 +- wind/db/drivers/mssql/WindMsSql.php | 2 +- wind/db/drivers/mssql/WindMsSqlBuilder.php | 2 +- wind/db/exception/WindDbException.php | 1 - wind/filter/WindFilter.php | 2 +- wind/ftp/WindFtp.php | 2 +- wind/ftp/WindSocketFtp.php | 3 +- wind/http/request/WindHttpRequest.php | 2 +- wind/http/response/WindHttpResponse.php | 2 +- wind/http/session/WindDbSession.php | 2 +- wind/http/transfer/WindHttpCurl.php | 2 +- wind/http/transfer/WindHttpSocket.php | 2 +- wind/http/transfer/WindHttpStream.php | 2 +- wind/log/WindLogger.php | 2 +- wind/mail/WindMail.php | 4 +- wind/mail/protocol/WindImap.php | 2 +- wind/mail/protocol/WindPop3.php | 352 +++++++++--------- wind/mail/protocol/WindSmtp.php | 2 +- wind/mail/sender/WindPhpMail.php | 2 +- wind/mail/sender/WindSendMail.php | 2 +- wind/mail/sender/WindSmtpMail.php | 4 +- wind/parser/WindConfigParser.php | 31 +- wind/router/WindRouter.php | 2 +- wind/router/WindUrlRewriteRouter.php | 2 +- wind/router/route/WindRewriteRoute.php | 2 +- wind/upload/AbstractWindUpload.php | 4 +- wind/upload/WindFormUpload.php | 4 +- wind/upload/WindFtpUpload.php | 6 +- wind/utility/WindFile.php | 4 +- wind/utility/WindPack.php | 2 +- wind/utility/WindString.php | 4 +- wind/utility/WindValidator.php | 2 +- wind/viewer/AbstractWindViewTemplate.php | 2 +- wind/viewer/WindView.php | 4 +- wind/viewer/WindViewerResolver.php | 4 +- .../compiler/WindTemplateCompilerAction.php | 2 +- .../WindTemplateCompilerComponent.php | 2 +- .../compiler/WindTemplateCompilerCss.php | 2 +- .../compiler/WindTemplateCompilerEcho.php | 4 +- .../compiler/WindTemplateCompilerInternal.php | 2 +- .../compiler/WindTemplateCompilerPage.php | 2 +- .../compiler/WindTemplateCompilerScript.php | 2 +- .../compiler/WindTemplateCompilerTemplate.php | 2 +- wind/viewer/compiler/WindViewTemplate.php | 30 +- wind/viewer/errorPage/404.htm | 10 - wind/viewer/errorPage/default_error.htm | 45 --- wind/viewer/exception/WindViewException.php | 2 - .../viewer/listener/WindViewCacheListener.php | 2 +- wind/web/WindDispatcher.php | 1 - wind/web/WindErrorHandler.php | 2 +- wind/web/WindSystemConfig.php | 6 +- wind/web/WindWebApplication.php | 8 +- wind/web/listener/WindValidateListener.php | 2 +- 76 files changed, 388 insertions(+), 468 deletions(-) delete mode 100644 wind/viewer/errorPage/404.htm delete mode 100644 wind/viewer/errorPage/default_error.htm diff --git a/wind/Wind.php b/wind/Wind.php index 78406ca0..421173a7 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -17,12 +17,12 @@ * @package */ class Wind { + private static $_imports = array(); + private static $_classes = array(); private static $_components = 'WIND:components_config'; private static $_extensions = 'php'; private static $_isAutoLoad = true; private static $_namespace = array(); - private static $_imports = array(); - private static $_classes = array(); private static $_includePaths = array(); private static $_app = array(); private static $_currentApp = array(); @@ -90,13 +90,13 @@ public static function resetApp() { /** * 加载一个类或者加载一个包 * 如果加载的包中有子文件夹不进行循环加载 - * 参数格式说明:'WIND:core.base.WFrontController' + * 参数格式说明:'WIND:base.WFrontController' * WIND 注册的应用名称,应用名称与路径信息用‘:’号分隔 * core.base.WFrontController 相对的路径信息 * 如果不填写应用名称 ,例如‘core.base.WFrontController’,那么加载路径则相对于默认的应用路径 * - * 加载一个类的参数方式:'WIND:core.base.WFrontController' - * 加载一个包的参数方式:'WIND:core.base.*' + * 加载一个类的参数方式:'WIND:base.WFrontController' + * 加载一个包的参数方式:'WIND:base.*' * * @param string $filePath | 文件路径信息 或者className * @param boolean $autoIncludes | 是否采用自动加载方式 @@ -166,8 +166,7 @@ public static function register($path, $alias = '', $includePath = false, $reset unset(self::$_includePaths[$pos]); } array_unshift(self::$_includePaths, $path); - if (set_include_path( - '.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { + if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { throw new Exception('set include path error.'); } } @@ -193,7 +192,6 @@ public static function autoLoad($className, $path = '') { if (isset(self::$_classes[$className])) $path = self::$_classes[$className]; - //TODO if (WIND_DEBUG & 1) include $path . '.' . self::$_extensions; else @@ -208,6 +206,14 @@ public static function getImports($key = '') { return $key ? self::$_imports[$key] : self::$_imports; } + /** + * 设置imports信息 + * @param array $imports + */ + public static function setImports($imports) { + self::$_imports = array_merge(self::$_imports, $imports); + } + /** * 解析路径信息,并返回路径的详情 * @param string $filePath 路径信息 @@ -254,8 +260,14 @@ public static function getRealDir($dirPath, $absolut = false) { */ public static function init() { function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); - self::_setDefaultSystemNamespace(); - self::_registerAutoloader(); + self::register(WIND_PATH, 'WIND', true); + + if (!self::$_isAutoLoad) + return; + if (function_exists('spl_autoload_register')) + spl_autoload_register('Wind::autoLoad'); + else + self::$_isAutoLoad = false; self::_loadBaseLib(); } @@ -278,28 +290,6 @@ protected static function beforRun($appName, $config, $rootPath) { self::$_currentAppName = $appName; } - /** - * 系统命名空间注册方法 - * @return - */ - private static function _setDefaultSystemNamespace() { - self::register(WIND_PATH, 'WIND', true); - self::register(WIND_PATH . 'component' . '/', 'COM', true); - } - - /** - * 检查框架运行环境 - * @return - */ - private static function _checkEnvironment() { - if (version_compare(PHP_VERSION, PHPVERSION) === -1) { - throw new Exception( - '[wind._checkEnvironment] current php version is lower, php ' . PHPVERSION . ' or later.', - E_WARNING); - } - function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); - } - /** * @param string $className * @param string $classPath @@ -316,80 +306,61 @@ private static function _setImport($className, $classPath) { self::autoLoad($className, $_classPath); } - /** - * 注册自动加载回调方法 - * @return - */ - private static function _registerAutoloader() { - if (!self::$_isAutoLoad) - return; - if (function_exists('spl_autoload_register')) - spl_autoload_register('Wind::autoLoad'); - else - self::$_isAutoLoad = false; - } - /** * 加载核心层库函数 * @return */ private static function _loadBaseLib() { - self::$_classes = array('WindLogger' => 'log/WindLogger', - 'WindActionException' => 'core/exception/WindActionException', - 'WindException' => 'core/exception/WindException', - 'WindFinalException' => 'core/exception/WindFinalException', - 'IWindFactory' => 'core/factory/IWindFactory', - 'WindClassProxy' => 'core/factory/WindClassProxy', - 'WindFactory' => 'core/factory/WindFactory', 'WindFilter' => 'core/filter/WindFilter', - 'WindFilterChain' => 'core/filter/WindFilterChain', - 'WindHandlerInterceptor' => 'core/filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'core/filter/WindHandlerInterceptorChain', - 'IWindApplication' => 'core/IWindApplication', - 'WindUrlFilter' => 'core/web/filter/WindUrlFilter', - 'WindFormListener' => 'core/web/listener/WindFormListener', - 'WindLoggerListener' => 'core/web/listener/WindLoggerListener', - 'WindValidateListener' => 'core/web/listener/WindValidateListener', - 'WindController' => 'core/web/WindController', - 'WindDispatcher' => 'core/web/WindDispatcher', - 'WindErrorHandler' => 'core/web/WindErrorHandler', - 'WindForward' => 'core/web/WindForward', - 'WindSimpleController' => 'core/web/WindSimpleController', - 'WindSystemConfig' => 'core/web/WindSystemConfig', - 'WindUrlHelper' => 'core/web/WindUrlHelper', - 'WindWebApplication' => 'core/web/WindWebApplication', - 'WindEnableValidateModule' => 'core/WindEnableValidateModule', - 'WindErrorMessage' => 'core/WindErrorMessage', 'WindHelper' => 'core/WindHelper', - 'WindModule' => 'core/WindModule', 'IWindConfigParser' => 'parser/IWindConfigParser', - 'WindConfigParser' => 'parser/WindConfigParser', - 'WindIniParser' => 'parser/WindIniParser', - 'WindPropertiesParser' => 'parser/WindPropertiesParser', - 'WindXmlParser' => 'parser/WindXmlParser', - 'AbstractWindRouter' => 'router/AbstractWindRouter', - 'AbstractWindRoute' => 'router/route/AbstractWindRoute', - 'WindRewriteRoute' => 'router/route/WindRewriteRoute', - 'WindRoute' => 'router/route/WindRoute', 'WindRouter' => 'router/WindRouter', - 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter', - 'WindCookie' => 'http/cookie/WindCookie', - 'WindCookieObject' => 'http/cookie/WindCookieObject', - 'IWindRequest' => 'http/request/IWindRequest', - 'WindHttpRequest' => 'http/request/WindHttpRequest', - 'IWindResponse' => 'http/response/IWindResponse', - 'WindHttpResponse' => 'http/response/WindHttpResponse', - 'AbstractWindUserSession' => 'http/session/AbstractWindUserSession', - 'WindDbSession' => 'http/session/WindDbSession', - 'WindSession' => 'http/session/WindSession', - 'AbstractWindHttp' => 'http/transfer/AbstractWindHttp', - 'WindHttpCurl' => 'http/transfer/WindHttpCurl', - 'WindHttpSocket' => 'http/transfer/WindHttpSocket', - 'WindHttpStream' => 'http/transfer/WindHttpStream', - 'WindDate' => 'utility/date/WindDate', - 'WindGeneralDate' => 'utility/date/WindGeneralDate', - 'WindDecoder' => 'utility/json/WindDecoder', 'WindEncoder' => 'utility/json/WindEncoder', - 'WindArray' => 'utility/WindArray', 'WindFile' => 'utility/WindFile', - 'WindHtmlHelper' => 'utility/WindHtmlHelper', 'WindImage' => 'utility/WindImage', - 'WindPack' => 'utility/WindPack', 'WindSecurity' => 'utility/WindSecurity', - 'WindString' => 'utility/WindString', 'WindUtility' => 'utility/WindUtility', - 'WindValidator' => 'utility/WindValidator'); + self::$_classes = array( + 'IWindApplication' => 'base/IWindApplication', + 'IWindFactory' => 'base/IWindFactory', + 'WindActionException' => 'base/WindActionException', + 'WindClassProxy' => 'base/WindClassProxy', + 'WindEnableValidateModule' => 'base/WindEnableValidateModule', + 'WindErrorMessage' => 'base/WindErrorMessage', + 'WindException' => 'base/WindException', + 'WindFactory' => 'base/WindFactory', + 'WindFinalException' => 'base/WindFinalException', + 'WindHelper' => 'base/WindHelper', + 'WindModule' => 'base/WindModule', + 'WindActionFilter' => 'filter/WindActionFilter', + 'WindFilter' => 'filter/WindFilter', + 'WindFilterChain' => 'filter/WindFilterChain', + 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', + 'WindUrlFilter' => 'web/filter/WindUrlFilter', + 'WindFormListener' => 'web/listener/WindFormListener', + 'WindValidateListener' => 'web/listener/WindValidateListener', + 'WindController' => 'web/WindController', + 'WindDispatcher' => 'web/WindDispatcher', + 'WindErrorHandler' => 'web/WindErrorHandler', + 'WindForward' => 'web/WindForward', + 'WindSimpleController' => 'web/WindSimpleController', + 'WindSystemConfig' => 'web/WindSystemConfig', + 'WindUrlHelper' => 'web/WindUrlHelper', + 'WindWebApplication' => 'web/WindWebApplication', + 'AbstractWindRouter' => 'router/AbstractWindRouter', + 'AbstractWindRoute' => 'router/route/AbstractWindRoute', + 'WindRewriteRoute' => 'router/route/WindRewriteRoute', + 'WindRoute' => 'router/route/WindRoute', + 'WindRouter' => 'router/WindRouter', + 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter', + 'IWindRequest' => 'http/request/IWindRequest', + 'WindHttpRequest' => 'http/request/WindHttpRequest', + 'IWindResponse' => 'http/response/IWindResponse', + 'WindHttpResponse' => 'http/response/WindHttpResponse', + 'WindDate' => 'utility/date/WindDate', + 'WindGeneralDate' => 'utility/date/WindGeneralDate', + 'WindDecoder' => 'utility/json/WindDecoder', + 'WindEncoder' => 'utility/json/WindEncoder', + 'WindArray' => 'utility/WindArray', + 'WindFile' => 'utility/WindFile', + 'WindImage' => 'utility/WindImage', + 'WindPack' => 'utility/WindPack', + 'WindSecurity' => 'utility/WindSecurity', + 'WindString' => 'utility/WindString', + 'WindUtility' => 'utility/WindUtility', + 'WindValidator' => 'utility/WindValidator'); } } Wind::init(); diff --git a/wind/base/WindClassProxy.php b/wind/base/WindClassProxy.php index 7c255c14..2326b051 100644 --- a/wind/base/WindClassProxy.php +++ b/wind/base/WindClassProxy.php @@ -13,7 +13,7 @@ class WindClassProxy { const EVENT_TYPE_SETTER = 'setter'; const EVENT_TYPE_GETTER = 'getter'; - private $_interceptorChain = 'WIND:core.filter.WindHandlerInterceptorChain'; + private $_interceptorChain = 'WIND:filter.WindHandlerInterceptorChain'; private $_interceptorChainObj = null; protected $_attributes = array(); protected $_className = ''; diff --git a/wind/base/WindEnableValidateModule.php b/wind/base/WindEnableValidateModule.php index d9086908..247aad09 100644 --- a/wind/base/WindEnableValidateModule.php +++ b/wind/base/WindEnableValidateModule.php @@ -8,7 +8,7 @@ * @package */ class WindEnableValidateModule extends WindModule { - protected $_validatorClass = 'WIND:component.utility.WindValidator'; + protected $_validatorClass = 'WIND:utility.WindValidator'; protected $errorController = ''; protected $errorAction = ''; private $_validator = null; diff --git a/wind/base/WindFactory.php b/wind/base/WindFactory.php index eca4656f..9237e2ec 100644 --- a/wind/base/WindFactory.php +++ b/wind/base/WindFactory.php @@ -1,5 +1,4 @@ diff --git a/wind/cache/dependency/WindDbCacheDependency.php b/wind/cache/dependency/WindDbCacheDependency.php index fd58c835..5d23796a 100644 --- a/wind/cache/dependency/WindDbCacheDependency.php +++ b/wind/cache/dependency/WindDbCacheDependency.php @@ -6,7 +6,7 @@ * @version $Id$ * @package */ -Wind::import('WIND:component.cache.dependency.AbstractWindCacheDependency'); +Wind::import('WIND:cache.dependency.AbstractWindCacheDependency'); class WindDbCacheDependency extends AbstractWindCacheDependency{ private $sql = ''; private $configName = ''; @@ -35,7 +35,7 @@ private function getConnection() { if (!$this->getSystemFactory()->checkAlias($alias)) { $config = $this->getSystemConfig()->getDbConfig($this->configName); $definition = array( - 'path' => $this->getConfig('class', '', 'COM:db.WindConnection', $config), + 'path' => $this->getConfig('class', '', 'WIND:db.WindConnection', $config), 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', diff --git a/wind/cache/dependency/WindFileCacheDependency.php b/wind/cache/dependency/WindFileCacheDependency.php index c72a3719..1ae8244f 100644 --- a/wind/cache/dependency/WindFileCacheDependency.php +++ b/wind/cache/dependency/WindFileCacheDependency.php @@ -6,7 +6,7 @@ * @license * @package */ -Wind::import('WIND:component.cache.AbstractWindCacheDependency'); +Wind::import('WIND:cache.AbstractWindCacheDependency'); class WindFileCacheDependency extends AbstractWindCacheDependency { private $fileName = ''; diff --git a/wind/cache/strategy/WindApcCache.php b/wind/cache/strategy/WindApcCache.php index cbcc786e..6e483c36 100644 --- a/wind/cache/strategy/WindApcCache.php +++ b/wind/cache/strategy/WindApcCache.php @@ -1,6 +1,6 @@ diff --git a/wind/cache/strategy/WindDbCache.php b/wind/cache/strategy/WindDbCache.php index 56d8f5d4..400ce891 100644 --- a/wind/cache/strategy/WindDbCache.php +++ b/wind/cache/strategy/WindDbCache.php @@ -1,6 +1,6 @@ @@ -158,7 +158,7 @@ private function store($key, $value, $expires = 0) { private function getConnection() { if (null == $this->connection) { $config = $this->getSystemConfig()->getDbConfig($this->dbConfigName); - $path = $this->getConfig('class', '', 'COM:db.WindConnection', $config); + $path = $this->getConfig('class', '', 'WIND:db.WindConnection', $config); $alias = $this->dbConfigName ? $path . $this->dbConfigName : $path . get_class($this); if (!$this->getSystemFactory()->checkAlias($alias)) { $definition = array('path' => $path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', 'scope' => 'application'); diff --git a/wind/cache/strategy/WindEacceleratorCache.php b/wind/cache/strategy/WindEacceleratorCache.php index 35a466a2..1cada601 100644 --- a/wind/cache/strategy/WindEacceleratorCache.php +++ b/wind/cache/strategy/WindEacceleratorCache.php @@ -1,6 +1,6 @@ diff --git a/wind/cache/strategy/WindMemCache.php b/wind/cache/strategy/WindMemCache.php index 5b672af2..17b3e2d3 100644 --- a/wind/cache/strategy/WindMemCache.php +++ b/wind/cache/strategy/WindMemCache.php @@ -1,5 +1,5 @@ diff --git a/wind/cache/strategy/WindXCache.php b/wind/cache/strategy/WindXCache.php index d07fa7ba..8ec5def0 100644 --- a/wind/cache/strategy/WindXCache.php +++ b/wind/cache/strategy/WindXCache.php @@ -1,5 +1,5 @@ diff --git a/wind/cache/strategy/WindZendCache.php b/wind/cache/strategy/WindZendCache.php index dd36c252..696c25af 100644 --- a/wind/cache/strategy/WindZendCache.php +++ b/wind/cache/strategy/WindZendCache.php @@ -1,5 +1,5 @@ diff --git a/wind/components_config.php b/wind/components_config.php index 9778e06b..cb7f980d 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -1,6 +1,6 @@ array( - 'path' => 'WIND:core.web.WindWebApplication', + 'path' => 'WIND:web.WindWebApplication', 'scope' => 'singleton', 'properties' => array( 'dispatcher' => array( @@ -12,7 +12,7 @@ ), ), 'windLogger' => array( - 'path' => 'COM:log.WindLogger', + 'path' => 'WIND:log.WindLogger', 'scope' => 'singleton', 'constructor-arg' => array( '0' => array( @@ -24,11 +24,11 @@ ), ), 'dispatcher' => array( - 'path' => 'WIND:core.web.WindDispatcher', + 'path' => 'WIND:web.WindDispatcher', 'scope' => 'application', ), 'forward' => array( - 'path' => 'WIND:core.web.WindForward', + 'path' => 'WIND:web.WindForward', 'scope' => 'prototype', 'properties' => array( 'windView' => array( @@ -37,15 +37,15 @@ ), ), 'router' => array( - 'path' => 'COM:router.WindRouter', + 'path' => 'WIND:router.WindRouter', 'scope' => 'application', ), 'urlHelper' => array( - 'path' => 'WIND:core.web.WindUrlHelper', + 'path' => 'WIND:web.WindUrlHelper', 'scope' => 'application', ), 'windView' => array( - 'path' => 'COM:viewer.WindView', + 'path' => 'WIND:viewer.WindView', 'scope' => 'prototype', 'config' => array( 'template-dir' => 'template', @@ -64,7 +64,7 @@ ), ), 'viewResolver' => array( - 'path' => 'COM:viewer.WindViewerResolver', + 'path' => 'WIND:viewer.WindViewerResolver', 'scope' => 'prototype', 'properties' => array( 'windLayout' => array( @@ -73,15 +73,15 @@ ), ), 'layout' => array( - 'path' => 'COM:viewer.WindLayout', + 'path' => 'WIND:viewer.WindLayout', 'scope' => 'prototype', ), 'template' => array( - 'path' => 'COM:viewer.compiler.WindViewTemplate', + 'path' => 'WIND:viewer.compiler.WindViewTemplate', 'scope' => 'prototype', ), 'db' => array( - 'path' => 'COM:db.WindConnection', + 'path' => 'WIND:db.WindConnection', 'scope' => 'singleton', 'config' => array( 'resource' => 'db_config.xml', @@ -92,11 +92,11 @@ 'scope' => 'prototype', ), 'configParser' => array( - 'path' => 'COM:parser.WindConfigParser', + 'path' => 'WIND:parser.WindConfigParser', 'scope' => 'singleton', ), 'windCache' => array( - 'path' => 'COM:cache.strategy.WindFileCache', + 'path' => 'WIND:cache.strategy.WindFileCache', 'config' => array( 'dir' => 'data.config', 'suffix' => 'php', @@ -104,7 +104,7 @@ ), ), 'viewCache' => array( - 'path' => 'COM:cache.strategy.WindFileCache', + 'path' => 'WIND:cache.strategy.WindFileCache', 'config' => array( 'dir' => 'data.view', 'suffix' => 'php', diff --git a/wind/dao/WindDaoFactory.php b/wind/dao/WindDaoFactory.php index 009e610d..bd6d607b 100644 --- a/wind/dao/WindDaoFactory.php +++ b/wind/dao/WindDaoFactory.php @@ -1,5 +1,5 @@ @@ -215,7 +215,7 @@ public function close() { public function init() { try { $driverName = $this->getDriverName(); - $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; + $dbHandleClass = "WIND:db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; $dbHandleClass = Wind::import($dbHandleClass); $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); diff --git a/wind/db/WindConnectionManager.php b/wind/db/WindConnectionManager.php index 7f79e1d5..03e00bca 100644 --- a/wind/db/WindConnectionManager.php +++ b/wind/db/WindConnectionManager.php @@ -1,5 +1,5 @@ @@ -36,7 +36,7 @@ class WindConnectionManager extends WindConnection { public function init() { try { $driverName = $this->getDriverName(); - $dbHandleClass = "WIND:component.db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; + $dbHandleClass = "WIND:db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; $dbHandleClass = Wind::import($dbHandleClass); $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); diff --git a/wind/db/WindSqlStatement.php b/wind/db/WindSqlStatement.php index e3cfa7a2..83acdb11 100644 --- a/wind/db/WindSqlStatement.php +++ b/wind/db/WindSqlStatement.php @@ -1,6 +1,6 @@ * @author Qiong Wu diff --git a/wind/db/drivers/mssql/WindMsSql.php b/wind/db/drivers/mssql/WindMsSql.php index af1e8674..4e7a22e5 100644 --- a/wind/db/drivers/mssql/WindMsSql.php +++ b/wind/db/drivers/mssql/WindMsSql.php @@ -5,7 +5,7 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ -Wind::import('WIND:component.drivers.AbstractWindDbAdapter'); +Wind::import('WIND:drivers.AbstractWindDbAdapter'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qian Su diff --git a/wind/db/drivers/mssql/WindMsSqlBuilder.php b/wind/db/drivers/mssql/WindMsSqlBuilder.php index 096d0bb4..acc4d616 100644 --- a/wind/db/drivers/mssql/WindMsSqlBuilder.php +++ b/wind/db/drivers/mssql/WindMsSqlBuilder.php @@ -5,7 +5,7 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ -Wind::import('WIND:component.db.drivers.AbstractWindSqlBuilder'); +Wind::import('WIND:db.drivers.AbstractWindSqlBuilder'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qian Su diff --git a/wind/db/exception/WindDbException.php b/wind/db/exception/WindDbException.php index 17a5813e..fe8d17f8 100644 --- a/wind/db/exception/WindDbException.php +++ b/wind/db/exception/WindDbException.php @@ -1,5 +1,4 @@ * @version $Id$ diff --git a/wind/filter/WindFilter.php b/wind/filter/WindFilter.php index 827cc218..ea0ab864 100644 --- a/wind/filter/WindFilter.php +++ b/wind/filter/WindFilter.php @@ -1,5 +1,5 @@ * @author xiaoxia xu diff --git a/wind/ftp/WindFtp.php b/wind/ftp/WindFtp.php index 76959bc0..d91eb63b 100644 --- a/wind/ftp/WindFtp.php +++ b/wind/ftp/WindFtp.php @@ -1,5 +1,5 @@ diff --git a/wind/ftp/WindSocketFtp.php b/wind/ftp/WindSocketFtp.php index 1719a0a9..50dcd24d 100644 --- a/wind/ftp/WindSocketFtp.php +++ b/wind/ftp/WindSocketFtp.php @@ -1,6 +1,5 @@ diff --git a/wind/http/request/WindHttpRequest.php b/wind/http/request/WindHttpRequest.php index 29608259..37eafd71 100644 --- a/wind/http/request/WindHttpRequest.php +++ b/wind/http/request/WindHttpRequest.php @@ -1,5 +1,5 @@ * @author Qiong Wu diff --git a/wind/http/response/WindHttpResponse.php b/wind/http/response/WindHttpResponse.php index a7016946..75520776 100644 --- a/wind/http/response/WindHttpResponse.php +++ b/wind/http/response/WindHttpResponse.php @@ -1,5 +1,5 @@ diff --git a/wind/http/transfer/WindHttpCurl.php b/wind/http/transfer/WindHttpCurl.php index fe0b5ffd..bded731d 100644 --- a/wind/http/transfer/WindHttpCurl.php +++ b/wind/http/transfer/WindHttpCurl.php @@ -5,7 +5,7 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ -Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +Wind::import('WIND:http.transfer.AbstractWindHttp'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qian Su diff --git a/wind/http/transfer/WindHttpSocket.php b/wind/http/transfer/WindHttpSocket.php index 06c6d5f8..b82479a3 100644 --- a/wind/http/transfer/WindHttpSocket.php +++ b/wind/http/transfer/WindHttpSocket.php @@ -5,7 +5,7 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ -Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +Wind::import('WIND:http.transfer.AbstractWindHttp'); /** * socket操作 * the last known user to change this file in the repository <$LastChangedBy$> diff --git a/wind/http/transfer/WindHttpStream.php b/wind/http/transfer/WindHttpStream.php index abee1faa..00b8abb5 100644 --- a/wind/http/transfer/WindHttpStream.php +++ b/wind/http/transfer/WindHttpStream.php @@ -5,7 +5,7 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ -Wind::import('WIND:component.http.transfer.AbstractWindHttp'); +Wind::import('WIND:http.transfer.AbstractWindHttp'); /** * the last known user to change this file in the repository <$LastChangedBy$> * @author Qian Su diff --git a/wind/log/WindLogger.php b/wind/log/WindLogger.php index 60dac919..b45775bb 100644 --- a/wind/log/WindLogger.php +++ b/wind/log/WindLogger.php @@ -128,7 +128,7 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flu public function flush() { if (empty($this->_logs)) return false; - Wind::import('WIND:component.utility.WindFile'); + Wind::import('WIND:utility.WindFile'); $_l = $_logTypes = $_logLevels = array(); $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', diff --git a/wind/mail/WindMail.php b/wind/mail/WindMail.php index b4efd04b..4e624068 100644 --- a/wind/mail/WindMail.php +++ b/wind/mail/WindMail.php @@ -120,7 +120,7 @@ public function send($type = self::SEND_SMTP,$config = array()){ if(!in_array($type,array(self::SEND_SMTP,self::SEND_PHP,self::SEND_SEND))){ throw new WindException('There is no way that you want to send e-mail'); } - $class = Wind::import('Wind:component.mail.sender.Wind'.ucfirst($type).'Mail'); + $class = Wind::import('Wind:mail.sender.Wind'.ucfirst($type).'Mail'); /* @var $sender IWindSendMail */ $sender = new $class($config); $sender->send($this); @@ -252,7 +252,7 @@ public function setSubject($subject) { */ public function setDate($date = null,$ifchinese = true){ if(!$date){ - Wind::import ( 'WIND:component.utility.date.WindDate' ); + Wind::import ( 'WIND:utility.date.WindDate' ); $date = $ifchinese ? WindDate::getChinaDate() : WindDate::getRFCDate(); } $this->setMailHeader(self::DATE,$date ); diff --git a/wind/mail/protocol/WindImap.php b/wind/mail/protocol/WindImap.php index 2e0dd161..57ecfe71 100644 --- a/wind/mail/protocol/WindImap.php +++ b/wind/mail/protocol/WindImap.php @@ -6,7 +6,7 @@ * @package * tags */ -Wind::import('WIND:component.mail.protocol.WindSocket'); +Wind::import('WIND:mail.protocol.WindSocket'); /** * imap协议封装 * the last known user to change this file in the repository <$LastChangedBy$> diff --git a/wind/mail/protocol/WindPop3.php b/wind/mail/protocol/WindPop3.php index 6a807a87..a77ff46f 100644 --- a/wind/mail/protocol/WindPop3.php +++ b/wind/mail/protocol/WindPop3.php @@ -1,260 +1,264 @@ - * @author Qian Su * @version $Id$ * @package * tags - */ -Wind::import ( 'WIND:component.mail.protocol.WindSocket' ); + */ +Wind::import('WIND:mail.protocol.WindSocket'); /** * pop3协议 * the last known user to change this file in the repository <$LastChangedBy$> * @author Qian Su * @version $Id$ * @package - */ -class WindPop3 { - const CRLF = "\r\n"; + */ +class WindPop3 { + const CRLF = "\r\n"; /** * @var WindSocket pop3邮件服务器 - */ - protected $pop3 = null; - protected $seperate = ' '; - protected $request = array(); - protected $resonse = array(); - - public function __construct($host, $port) { - $this->pop3 = new WindSocket($host, $port); - } - + */ + protected $pop3 = null; + protected $seperate = ' '; + protected $request = array(); + protected $resonse = array(); + + public function __construct($host, $port) { + $this->pop3 = new WindSocket($host, $port); + } + /** * 打开pop3服务器,建立连接 * @return string - */ - public function open() { - $this->pop3->open(); - return $this->response(); - } - + */ + public function open() { + $this->pop3->open(); + return $this->response(); + } + /** * 登陆pop3 * @param string $username 用户名 * @param string $password 密码 * @return string - */ - public function login($username, $password) { - $this->communicate("USER $username"); - return $this->communicate("PASS $password"); - } - + */ + public function login($username, $password) { + $this->communicate("USER $username"); + return $this->communicate("PASS $password"); + } + /** * 处理请求 server 回送邮箱统计资料,如邮件数、 邮件总字节数 * @return string - */ - public function stat() { - return $this->communicate('STAT', false, true); - } - + */ + public function stat() { + return $this->communicate('STAT', false, true); + } + /** * 处理 server 返回用于该指定邮件的唯一标识, 如果没有指定,返回所有的。 * @param int $n 指定邮件 * @return string - */ - public function uidl($n = null) { - $request = $n ? "UIDL $n" : 'UIDL'; - $ifmulti = $n ? false : true; - return $this->communicate($request, $ifmulti, true); - } - + */ + public function uidl($n = null) { + $request = $n ? "UIDL $n" : 'UIDL'; + $ifmulti = $n ? false : true; + return $this->communicate($request, $ifmulti, true); + } + /** * 处理 server 返回指定邮件的大小等 * @param int $n 指定邮件 * @return string - */ - public function getList($n = null) { - $request = $n ? "LIST $n" : 'LIST'; - $ifmulti = $n ? false : true; - return $this->communicate($request, $ifmulti, true); - } - + */ + public function getList($n = null) { + $request = $n ? "LIST $n" : 'LIST'; + $ifmulti = $n ? false : true; + return $this->communicate($request, $ifmulti, true); + } + /** * 处处理 server 返回邮件的全部文本 * @param int $n 指定邮件 * @return string - */ - public function retr($n) { - return $this->communicate("RETR $n", true); - } + */ + public function retr($n) { + return $this->communicate("RETR $n", true); + } + /** * 处理 server 标记删除,QUIT 命令执行时才真正删除 * @param int $n 指定邮件 * @return string - */ - public function dele($n) { - return $this->communicate("DELE $n"); - } + */ + public function dele($n) { + return $this->communicate("DELE $n"); + } + /** * 处理撤消所有的 DELE 命令 * @return string - */ - public function rset() { - return $this->communicate("RSET"); - } - + */ + public function rset() { + return $this->communicate("RSET"); + } + /** * 处理 返回 n 号邮件的前 m 行内容,m 必须是自然数 * @param int $n 指定邮件 * @param int $m 指定邮件前多少行 * @return string - */ - public function top($n, $m = null) { - $request = $m ? 'TOP ' . (int) $n . ' ' . (int) $m : 'TOP ' . (int) $n; - return $this->communicate($request, true); - } - + */ + public function top($n, $m = null) { + $request = $m ? 'TOP ' . (int) $n . ' ' . (int) $m : 'TOP ' . (int) $n; + return $this->communicate($request, true); + } + /** * 处理 server 返回一个肯定的响应 * @return string - */ - public function noop() { - return $this->communicate("NOOP"); - } - + */ + public function noop() { + return $this->communicate("NOOP"); + } + /** * 希望结束会话。如果 server 处于"处理" 状态, * 则现在进入"更新"状态,删除那些标记成删除的邮件。 * 如果 server 处于"认可"状态,则结束会话时 server * 不进入"更新"状态 。 * @return string - */ - public function quit() { - return $this->communicate("QUIT"); - } - + */ + public function quit() { + return $this->communicate("QUIT"); + } + /** * 结否会话,关闭pop3服务器 - */ - public function close() { - $this->quit(); - $this->pop3->close(); - $this->pop3 = null; - } + */ + public function close() { + $this->quit(); + $this->pop3->close(); + $this->pop3 = null; + } + /** * pop3响应请求 * @param int $timeout - */ - public function responseLine($timeout = null) { - if (null !== $timeout) { - $this->pop3->setSocketTimeOut((int) $timeout); - } - return $this->pop3->responseLine(); - } - + */ + public function responseLine($timeout = null) { + if (null !== $timeout) { + $this->pop3->setSocketTimeOut((int) $timeout); + } + return $this->pop3->responseLine(); + } + /** * 外理响应内容 * @param string $response * @return Array - */ - public function buildResponse($response) { - if (empty($response)) { - return array(); - } - $response = explode("\n", $response); - $_response = array(); - foreach ($response as $line) { - if (empty($line)) { - continue; - } - list($key, $value) = explode($this->seperate, trim($line), 2); - $key ? $_response[(int) $key] = $value : $_response[] = $value; - } - return $_response; - } - + */ + public function buildResponse($response) { + if (empty($response)) { + return array(); + } + $response = explode("\n", $response); + $_response = array(); + foreach ($response as $line) { + if (empty($line)) { + continue; + } + list($key, $value) = explode($this->seperate, trim($line), 2); + $key ? $_response[(int) $key] = $value : $_response[] = $value; + } + return $_response; + } + /** * 进行一次网络传输通信 * @param string $request 发竤的请求命令 * @param boolean $ifmulti 是否返回多行响应文本,否则为一行 * @param baoolean $ifbuild 是否对响应进行处理 * @return array - */ - public function communicate($request, $ifmulti = false, $ifbuild = false) { - $this->request($request); - return $ifbuild ? $this->buildResponse($this->response($ifmulti)) : $this->response($ifmulti); - } - + */ + public function communicate($request, $ifmulti = false, $ifbuild = false) { + $this->request($request); + return $ifbuild ? $this->buildResponse($this->response($ifmulti)) : $this->response($ifmulti); + } + /** * 发送pop3命令 * @param string $request - */ - public function request($request) { - $this->request[] = $request; - return $this->pop3->request($request . self::CRLF); - } - + */ + public function request($request) { + $this->request[] = $request; + return $this->pop3->request($request . self::CRLF); + } + /** * 验证请求 * @param boolean $multi * @param int $timeout * @return string - */ - public function response($multi = false, $timeout = null) { - $ok = $this->responseLine($timeout); - if (empty($ok) || !is_string($ok)) { - throw new WindException('Read Failed'); - } - if ('+OK' !== substr($ok, 0, 3)) { - throw new WindException('Request Failed!Pleae See Failed Info:' . $ok); - } - if (true === $multi) { - $response = ''; - while ('' != ($_response = $this->responseLine($timeout))) { - if ('.' === trim($_response)) { - break; - } - $response .= $_response; - $this->resonse[] = $_response; - } - } else { - $this->resonse[] = $ok; - if (strpos($ok, $this->seperate)) { - list(, $response) = explode($this->seperate, $ok, 2); - } else { - $response = $ok; - } - } - if(empty($response)) throw new WindException('No response'); - return $response; - } - + */ + public function response($multi = false, $timeout = null) { + $ok = $this->responseLine($timeout); + if (empty($ok) || !is_string($ok)) { + throw new WindException('Read Failed'); + } + if ('+OK' !== substr($ok, 0, 3)) { + throw new WindException('Request Failed!Pleae See Failed Info:' . $ok); + } + if (true === $multi) { + $response = ''; + while ('' != ($_response = $this->responseLine($timeout))) { + if ('.' === trim($_response)) { + break; + } + $response .= $_response; + $this->resonse[] = $_response; + } + } else { + $this->resonse[] = $ok; + if (strpos($ok, $this->seperate)) { + list(, $response) = explode($this->seperate, $ok, 2); + } else { + $response = $ok; + } + } + if (empty($response)) + throw new WindException('No response'); + return $response; + } + /** * 获取解析后的内容 * @param $content * @param $sep - */ - public function getMailContent($content,$sep = "\n\n"){ - $content = explode($sep,$content); - $content[0] = explode("\n",$content[0]); - $headers = array(); - foreach($content[0] as $value){ - $_value = explode(':',$value); - $headers[$_value[0]] = trim($_value[1]); - } - $encode = $headers['Content-Transfer-Encoding']; - if('base64' == $encode){ - $content = base64_decode($content[1]); - }else{ - $content = $content[1]; - } - return array($headers,$content); - } - - public function __destruct() { - if ($this->pop3) { - $this->close(); - } - } - -} + */ + public function getMailContent($content, $sep = "\n\n") { + $content = explode($sep, $content); + $content[0] = explode("\n", $content[0]); + $headers = array(); + foreach ($content[0] as $value) { + $_value = explode(':', $value); + $headers[$_value[0]] = trim($_value[1]); + } + $encode = $headers['Content-Transfer-Encoding']; + if ('base64' == $encode) { + $content = base64_decode($content[1]); + } else { + $content = $content[1]; + } + return array($headers, $content); + } + + public function __destruct() { + if ($this->pop3) { + $this->close(); + } + } + +} ?> \ No newline at end of file diff --git a/wind/mail/protocol/WindSmtp.php b/wind/mail/protocol/WindSmtp.php index 895387b8..17d20714 100644 --- a/wind/mail/protocol/WindSmtp.php +++ b/wind/mail/protocol/WindSmtp.php @@ -6,7 +6,7 @@ * @package * tags */ -Wind::import ( 'WIND:component.mail.protocol.WindSocket' ); +Wind::import ( 'WIND:mail.protocol.WindSocket' ); /** * 邮件传输协议操作 * the last known user to change this file in the repository <$LastChangedBy$> diff --git a/wind/mail/sender/WindPhpMail.php b/wind/mail/sender/WindPhpMail.php index 04f69ade..b32c9bc6 100644 --- a/wind/mail/sender/WindPhpMail.php +++ b/wind/mail/sender/WindPhpMail.php @@ -6,7 +6,7 @@ * @package * tags */ -Wind::import('WIND:component.mail.sender.IWindSendMail'); +Wind::import('WIND:mail.sender.IWindSendMail'); /** * 使用php内部函数发送邮件 * the last known user to change this file in the repository <$LastChangedBy$> diff --git a/wind/mail/sender/WindSendMail.php b/wind/mail/sender/WindSendMail.php index e6f98882..b5b1cec8 100644 --- a/wind/mail/sender/WindSendMail.php +++ b/wind/mail/sender/WindSendMail.php @@ -6,7 +6,7 @@ * @package * tags */ -Wind::import('WIND:component.mail.sender.IWindSendMail'); +Wind::import('WIND:mail.sender.IWindSendMail'); /** * 使用sendmail发送邮件 * the last known user to change this file in the repository <$LastChangedBy$> diff --git a/wind/mail/sender/WindSmtpMail.php b/wind/mail/sender/WindSmtpMail.php index d645702d..882063d9 100644 --- a/wind/mail/sender/WindSmtpMail.php +++ b/wind/mail/sender/WindSmtpMail.php @@ -6,8 +6,8 @@ * @package * tags */ -Wind::import('WIND:component.mail.sender.IWindSendMail'); -Wind::import ( 'WIND:component.mail.protocol.WindSmtp' ); +Wind::import('WIND:mail.sender.IWindSendMail'); +Wind::import ( 'WIND:mail.protocol.WindSmtp' ); /** * 邮件发送 * the last known user to change this file in the repository <$LastChangedBy$> diff --git a/wind/parser/WindConfigParser.php b/wind/parser/WindConfigParser.php index 624dae50..e4e97613 100644 --- a/wind/parser/WindConfigParser.php +++ b/wind/parser/WindConfigParser.php @@ -1,5 +1,5 @@ getCache($alias, $append, $cache)) return $config; + if ($config = $this->getCache($alias, $append, $cache)) + return $config; $config = $this->doParser($configPath); $this->setCache($alias, $append, $cache, $config); return $config; @@ -60,7 +61,8 @@ public function parse($configPath, $alias = '', $append = '', AbstractWindCache * @param AbstractWindCache $cache */ private function setCache($alias, $append, $cache, $data) { - if (!$alias || !$cache) return; + if (!$alias || !$cache) + return; if ($append) { $_config = (array) $cache->get($append); $_config[$alias] = $data; @@ -78,8 +80,10 @@ private function setCache($alias, $append, $cache, $data) { * @return array */ private function getCache($alias, $append, $cache) { - if (!$alias || !$cache) return array(); - if (!$append) return $cache->get($alias); + if (!$alias || !$cache) + return array(); + if (!$append) + return $cache->get($alias); $config = $cache->get($append); return isset($config[$alias]) ? $config[$alias] : array(); @@ -93,15 +97,15 @@ private function getCache($alias, $append, $cache) { private function createParser($type) { switch ($type) { case self::CONFIG_XML: - Wind::import("WIND:component.parser.WindXmlParser"); + Wind::import("WIND:parser.WindXmlParser"); return new WindXmlParser(); break; case self::CONFIG_INI: - Wind::import("WIND:component.parser.WindIniParser"); + Wind::import("WIND:parser.WindIniParser"); return new WindIniParser(); break; case self::CONFIG_PROPERTIES: - Wind::import("WIND:component.parser.WindPropertiesParser"); + Wind::import("WIND:parser.WindPropertiesParser"); return new WindPropertiesParser(); break; default: @@ -119,11 +123,14 @@ private function createParser($type) { * @return array 返回解析结果 */ private function doParser($configFile) { - if (!is_file($configFile)) throw new WindException( - '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); + if (!is_file($configFile)) + throw new WindException( + '[component.parser.WindConfigParser.doParser] The file \'' . $configFile . '\' is not exists'); $ext = strtoupper(strrchr($configFile, '.')); - if ($ext == self::CONFIG_PHP) return @include ($configFile); - if (!isset($this->configParsers[$ext])) $this->configParsers[$ext] = $this->createParser($ext); + if ($ext == self::CONFIG_PHP) + return @include ($configFile); + if (!isset($this->configParsers[$ext])) + $this->configParsers[$ext] = $this->createParser($ext); return $this->configParsers[$ext]->parse($configFile); } } \ No newline at end of file diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index 11c5dfa7..89e519a7 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -1,5 +1,5 @@ * @author Qiong Wu diff --git a/wind/router/WindUrlRewriteRouter.php b/wind/router/WindUrlRewriteRouter.php index 6481a873..00813caa 100644 --- a/wind/router/WindUrlRewriteRouter.php +++ b/wind/router/WindUrlRewriteRouter.php @@ -1,6 +1,6 @@ diff --git a/wind/router/route/WindRewriteRoute.php b/wind/router/route/WindRewriteRoute.php index 3a9eeb86..78b47b25 100644 --- a/wind/router/route/WindRewriteRoute.php +++ b/wind/router/route/WindRewriteRoute.php @@ -1,5 +1,5 @@ * @author Qiong Wu diff --git a/wind/upload/AbstractWindUpload.php b/wind/upload/AbstractWindUpload.php index baf5a346..608c951a 100644 --- a/wind/upload/AbstractWindUpload.php +++ b/wind/upload/AbstractWindUpload.php @@ -5,8 +5,8 @@ * @copyright Copyright © 2003-2110 phpwind.com * @license */ -Wind::import('WIND:component.utility.Security'); -Wind::import('WIND:component.utility.WindFile'); +Wind::import('WIND:utility.Security'); +Wind::import('WIND:utility.WindFile'); /** * the last known user to change this file in the repository <$LastChangedBy: yishuo $> * @author Qian Su diff --git a/wind/upload/WindFormUpload.php b/wind/upload/WindFormUpload.php index 1d7d1445..1262ba12 100644 --- a/wind/upload/WindFormUpload.php +++ b/wind/upload/WindFormUpload.php @@ -1,5 +1,5 @@ 2011-7-18 * @link http://www.phpwind.com @@ -31,7 +31,7 @@ protected function postUpload($tmp_name, $filename) { @chmod($filename, 0777); return filesize($filename); } elseif (is_readable($tmp_name)) { - Wind::import('WIND:component.utility.WindFile'); + Wind::import('WIND:utility.WindFile'); WindFile::write($filename, WindFile::read($tmp_name)); @unlink($tmp_name); if (file_exists($filename)) { diff --git a/wind/upload/WindFtpUpload.php b/wind/upload/WindFtpUpload.php index a44f712c..3e24beab 100644 --- a/wind/upload/WindFtpUpload.php +++ b/wind/upload/WindFtpUpload.php @@ -1,6 +1,6 @@ @@ -45,11 +45,11 @@ public function setConfig($config) { private function getFtpConnection() { if (is_object($this->ftp)) return $this->ftp; if (function_exists('ftp_connect')) { - Wind::import("COM:ftp.WindFtp"); + Wind::import("WIND:ftp.WindFtp"); $this->ftp = new WindFtp($this->config); return $this->ftp; } - Wind::import("COM:ftp.WindSocketFtp"); + Wind::import("WIND:ftp.WindSocketFtp"); $this->ftp = new WindSocketFtp($this->config); return $this->ftp; } diff --git a/wind/utility/WindFile.php b/wind/utility/WindFile.php index 80e8b9c3..88bfd37a 100644 --- a/wind/utility/WindFile.php +++ b/wind/utility/WindFile.php @@ -1,6 +1,6 @@ diff --git a/wind/utility/WindPack.php b/wind/utility/WindPack.php index e0b7aa6a..5bdf7547 100644 --- a/wind/utility/WindPack.php +++ b/wind/utility/WindPack.php @@ -1,5 +1,5 @@ diff --git a/wind/utility/WindString.php b/wind/utility/WindString.php index eb41cd5e..5c9a369b 100644 --- a/wind/utility/WindString.php +++ b/wind/utility/WindString.php @@ -80,7 +80,7 @@ public static function varToString($input, $indent = '') { public static function jsonEncode($value) { if (!function_exists('json_encode')) { - Wind::import('Wind:component.utility.json.WindEncoder'); + Wind::import('Wind:utility.json.WindEncoder'); return WindDecoder::decode($value); } return json_encode($value); @@ -88,7 +88,7 @@ public static function jsonEncode($value) { public static function jsonDecode($value) { if (!function_exists('json_decode')) { - Wind::import('Wind:component.utility.json.WindEncoder'); + Wind::import('Wind:utility.json.WindEncoder'); return WindEncoder::encode($value); } return json_decode($value); diff --git a/wind/utility/WindValidator.php b/wind/utility/WindValidator.php index 67523f58..cf65adcb 100644 --- a/wind/utility/WindValidator.php +++ b/wind/utility/WindValidator.php @@ -322,7 +322,7 @@ public static function inArray($needle, array $array, $strict = true) { * @return boolean */ public static function isLegalLength($string, $length, $charset = 'utf8') { - Wind::import('WIND:component.utility.WindString'); + Wind::import('WIND:utility.WindString'); return WindString::strlen($string, $charset) > (int) $length; } diff --git a/wind/viewer/AbstractWindViewTemplate.php b/wind/viewer/AbstractWindViewTemplate.php index fb8b9915..0c12071d 100644 --- a/wind/viewer/AbstractWindViewTemplate.php +++ b/wind/viewer/AbstractWindViewTemplate.php @@ -1,5 +1,5 @@ * @author Qiong Wu diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index bd0dcd89..b60a0f5e 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -1,5 +1,5 @@ getIsCache()) return $this->viewResolver; $this->viewResolver = new WindClassProxy($this->viewResolver); - $listener = Wind::import('COM:viewer.listener.WindViewCacheListener'); + $listener = Wind::import('WIND:viewer.listener.WindViewCacheListener'); $this->viewResolver->registerEventListener('windFetch', new $listener($this)); return $this->viewResolver; } diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 8916f304..a867471e 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -1,6 +1,6 @@ 标签解析脚本 * 支持属性: action\controller diff --git a/wind/viewer/compiler/WindTemplateCompilerComponent.php b/wind/viewer/compiler/WindTemplateCompilerComponent.php index 27c9cdc3..835c34f9 100644 --- a/wind/viewer/compiler/WindTemplateCompilerComponent.php +++ b/wind/viewer/compiler/WindTemplateCompilerComponent.php @@ -1,5 +1,5 @@ * diff --git a/wind/viewer/compiler/WindTemplateCompilerCss.php b/wind/viewer/compiler/WindTemplateCompilerCss.php index e541f9c9..862a5159 100644 --- a/wind/viewer/compiler/WindTemplateCompilerCss.php +++ b/wind/viewer/compiler/WindTemplateCompilerCss.php @@ -1,5 +1,5 @@ * @author Qiong Wu diff --git a/wind/viewer/compiler/WindTemplateCompilerEcho.php b/wind/viewer/compiler/WindTemplateCompilerEcho.php index d6cfa107..fa967734 100644 --- a/wind/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/viewer/compiler/WindTemplateCompilerEcho.php @@ -1,6 +1,6 @@ * @author Qiong Wu diff --git a/wind/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/viewer/compiler/WindTemplateCompilerTemplate.php index 21657455..4bf9584b 100644 --- a/wind/viewer/compiler/WindTemplateCompilerTemplate.php +++ b/wind/viewer/compiler/WindTemplateCompilerTemplate.php @@ -1,5 +1,5 @@ * source: 模板文件源地址 diff --git a/wind/viewer/compiler/WindViewTemplate.php b/wind/viewer/compiler/WindViewTemplate.php index 35c5ce06..19b38f06 100644 --- a/wind/viewer/compiler/WindViewTemplate.php +++ b/wind/viewer/compiler/WindViewTemplate.php @@ -1,6 +1,6 @@ createTag('internal', 'COM:viewer.compiler.WindTemplateCompilerInternal', + $_tags['internal'] = $this->createTag('internal', 'WIND:viewer.compiler.WindTemplateCompilerInternal', '/<\?php(.|\n)*?\?>/i'); - $_tags['template'] = $this->createTag('template', 'COM:viewer.compiler.WindTemplateCompilerTemplate'); - $_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', + $_tags['template'] = $this->createTag('template', 'WIND:viewer.compiler.WindTemplateCompilerTemplate'); + $_tags['expression'] = $this->createTag('expression', 'WIND:viewer.compiler.WindTemplateCompilerEcho', '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); - $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); + $_tags['echo'] = $this->createTag('echo', 'WIND:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); /*标签体增加在该位置*/ - $_tags['page'] = $this->createTag('page', 'COM:viewer.compiler.WindTemplateCompilerPage'); - $_tags['action'] = $this->createTag('action', 'COM:viewer.compiler.WindTemplateCompilerAction'); - $_tags['script'] = $this->createTag('script', 'COM:viewer.compiler.WindTemplateCompilerScript', + $_tags['page'] = $this->createTag('page', 'WIND:viewer.compiler.WindTemplateCompilerPage'); + $_tags['action'] = $this->createTag('action', 'WIND:viewer.compiler.WindTemplateCompilerAction'); + $_tags['script'] = $this->createTag('script', 'WIND:viewer.compiler.WindTemplateCompilerScript', '/()*/i'); - //$_tags['link'] = $this->createTag('link', 'COM:viewer.compiler.WindTemplateCompilerCss'); - //$_tags['style'] = $this->createTag('style', 'COM:viewer.compiler.WindTemplateCompilerCss'); - $_tags['component'] = $this->createTag('component', 'COM:viewer.compiler.WindTemplateCompilerComponent'); + //$_tags['link'] = $this->createTag('link', 'WIND:viewer.compiler.WindTemplateCompilerCss'); + //$_tags['style'] = $this->createTag('style', 'WIND:viewer.compiler.WindTemplateCompilerCss'); + $_tags['component'] = $this->createTag('component', 'WIND:viewer.compiler.WindTemplateCompilerComponent'); /*标签解析结束*/ $_tags += (array) parent::getTags(); - /*$_tags['expression'] = $this->createTag('expression', 'COM:viewer.compiler.WindTemplateCompilerEcho', + /*$_tags['expression'] = $this->createTag('expression', 'WIND:viewer.compiler.WindTemplateCompilerEcho', '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); - $_tags['echo'] = $this->createTag('echo', 'COM:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i');*/ + $_tags['echo'] = $this->createTag('echo', 'WIND:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i');*/ return $_tags; } diff --git a/wind/viewer/errorPage/404.htm b/wind/viewer/errorPage/404.htm deleted file mode 100644 index b499243e..00000000 --- a/wind/viewer/errorPage/404.htm +++ /dev/null @@ -1,10 +0,0 @@ - - - - -Insert title here - - - - - \ No newline at end of file diff --git a/wind/viewer/errorPage/default_error.htm b/wind/viewer/errorPage/default_error.htm deleted file mode 100644 index 97e2593f..00000000 --- a/wind/viewer/errorPage/default_error.htm +++ /dev/null @@ -1,45 +0,0 @@ - - - - -{@G:title} - - - -
- - - - -
-

{$errorHeader}:

-

- {$key}. {$error}
-

-

You Can Get Help In:

-

{@WindHelper::errorInfo()}

-
-
- - \ No newline at end of file diff --git a/wind/viewer/exception/WindViewException.php b/wind/viewer/exception/WindViewException.php index 59bfbd9c..525a2586 100644 --- a/wind/viewer/exception/WindViewException.php +++ b/wind/viewer/exception/WindViewException.php @@ -1,6 +1,4 @@ * * - * + * * * * @@ -126,7 +126,7 @@ public function getModules($name = '') { * * Controller * - * WIND:core.web.WindErrorHandler + * WIND:web.WindErrorHandler * * * @@ -237,7 +237,7 @@ public function getDefaultConfigStruct($configName) { $_tmp['modules']['controller-suffix'] = $this->getConfig('controller-suffix', '', 'Controller'); $_tmp['modules']['error-handler'] = $this->getConfig('error-handler', '', - 'WIND:core.web.WindErrorHandler'); + 'WIND:web.WindErrorHandler'); return $configName ? (isset($_tmp[$configName]) ? $_tmp[$configName] : array()) : array(); } } \ No newline at end of file diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 1f43ce92..0cdb891a 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -1,6 +1,6 @@ * @author Qiong Wu @@ -29,7 +29,7 @@ class WindWebApplication extends WindModule implements IWindApplication { */ protected $handlerAdapter = null; protected $defaultModule = array('controller-path' => 'controller', 'controller-suffix' => 'Controller', - 'error-handler' => 'WIND:core.web.WindErrorHandler'); + 'error-handler' => 'WIND:web.WindErrorHandler'); /** * 应用初始化操作 @@ -147,7 +147,7 @@ protected function sendErrorMessage($exception) { * * Controller * - * WIND:core.web.WindErrorHandler + * WIND:web.WindErrorHandler * * * diff --git a/wind/web/listener/WindValidateListener.php b/wind/web/listener/WindValidateListener.php index 71be225a..a5c32543 100644 --- a/wind/web/listener/WindValidateListener.php +++ b/wind/web/listener/WindValidateListener.php @@ -1,5 +1,5 @@ From 79247748e9649d24ca3ee2cb44c2d04b1846e38f Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 09:21:01 +0000 Subject: [PATCH 0432/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2504 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/compile.php | 32 ++++++++++++++++----------- _compile/config/components_config.xml | 30 ++++++++++++------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/_compile/compile.php b/_compile/compile.php index 482871d1..dd466b81 100644 --- a/_compile/compile.php +++ b/_compile/compile.php @@ -8,19 +8,20 @@ include '../wind/Wind.php'; define('_COMPILE_PATH', dirname(__FILE__) . '/'); Wind::clear(); -Wind::import('COM:log.WindLogger'); -Wind::import('WIND:core.*', true); -Wind::import('COM:parser.*', true); -Wind::import('COM:router.*', true); -Wind::import('COM:http.*', true); -Wind::import('COM:utility.*', true); +Wind::import('WIND:base.*', true); +Wind::import('WIND:filter.*', true); +Wind::import('WIND:web.*', true); +Wind::import('WIND:router.*', true); +Wind::import('WIND:http.request.*', true); +Wind::import('WIND:http.response.*', true); +Wind::import('WIND:utility.*', true); $imports = Wind::getImports(); /* 载入需要的文件信息 */ -Wind::import('COM:utility.WindPack'); -Wind::import('COM:utility.WindFile'); -Wind::import('COM:utility.WindString'); -Wind::import('COM:parser.WindConfigParser'); +Wind::import('WIND:utility.WindPack'); +Wind::import('WIND:utility.WindFile'); +Wind::import('WIND:utility.WindString'); +Wind::import('WIND:parser.WindConfigParser'); /* 打包 */ $pack = new WindPack(); @@ -31,8 +32,8 @@ $fileList[$_key] = array($key, $value); $content[$value] = parseFilePath($key); } +$pack->setContentInjectionCallBack('addImports'); $pack->packFromFileList($fileList, _COMPILE_PATH . 'wind_basic.php', WindPack::STRIP_PHP, true); -/* import信息写入编译文件 */ WindFile::write(_COMPILE_PATH . 'wind_imports.php', 'parse(_COMPILE_PATH . 'config/' . $file); $file = preg_replace('/\.(\w)*$/i', '', $file); WindFile::write(_COMPILE_PATH . $file . '.php', ' --> - - + - - + - + - - + template htm @@ -46,28 +46,28 @@ - - + - - + - - + data.config php @@ -75,7 +75,7 @@ - + data.view php From 5581b6c1ed8764504ca5785779643be06310ab93 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 29 Aug 2011 09:36:45 +0000 Subject: [PATCH 0433/1065] =?UTF-8?q?=E7=9B=AE=E5=BD=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2505 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/dao/WindDaoFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/dao/WindDaoFactory.php b/wind/dao/WindDaoFactory.php index bd6d607b..41958dcf 100644 --- a/wind/dao/WindDaoFactory.php +++ b/wind/dao/WindDaoFactory.php @@ -40,7 +40,7 @@ public function getDao($className) { return $daoInstance; } catch (Exception $exception) { throw new WindDaoException( - '[component.dao.WindDaoFactory] create dao ' . $className . ' fail.' . $exception->getMessage()); + '[dao.WindDaoFactory] create dao ' . $className . ' fail.' . $exception->getMessage()); } } From be1ee749b8e053287c99f0628ef4563c5e9ca725 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Mon, 29 Aug 2011 10:29:36 +0000 Subject: [PATCH 0434/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= =?UTF-8?q?=EF=BC=8Caction=E6=A0=87=E7=AD=BE=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2506 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/compiler/WindTemplateCompilerAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/viewer/compiler/WindTemplateCompilerAction.php b/wind/viewer/compiler/WindTemplateCompilerAction.php index 89e4db5f..1e9b5b49 100644 --- a/wind/viewer/compiler/WindTemplateCompilerAction.php +++ b/wind/viewer/compiler/WindTemplateCompilerAction.php @@ -18,7 +18,7 @@ class WindTemplateCompilerAction extends AbstractWindTemplateCompiler { */ public function compile($key, $content) { return 'getComponent(\'forward\'); - $_tpl_forward->forwardAction(' . $this->action . '); + $_tpl_forward->forwardAction(\'' . $this->action . '\'); Wind::getApp()->doDispatch($_tpl_forward, true); ?>'; } From 8e41a9c4a41aef10446f8757c8362d7b852f5094 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 03:00:49 +0000 Subject: [PATCH 0435/1065] bug fixted: $viewResolver = $this->_getViewResolver(); $viewResolver->setWindView($this); git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2507 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindView.php | 9 +++---- wind/viewer/WindViewerResolver.php | 41 ++++++------------------------ 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index b60a0f5e..b16c19ce 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -84,7 +84,8 @@ public function render($display = false) { return; //TODO 其他输出类型 - $viewResolver = $this->_getViewResolver($this); + $viewResolver = $this->_getViewResolver(); + $viewResolver->setWindView($this); $viewResolver->windAssign(Wind::getApp()->getResponse()->getData($this->templateName)); if ($display === false) { $this->getResponse()->setBody($viewResolver->windFetch(), $this->templateName); @@ -103,8 +104,7 @@ public function setConfig($config) { $this->compileDir = $this->getConfig('compile-dir', '', $this->compileDir); $this->compileExt = $this->getConfig('compile-ext', '', $this->compileExt); $this->isCompile = $this->getConfig('is-compile', '', $this->isCompile); - $this->htmlspecialchars = $this->getConfig('htmlspecialchars', '', - $this->htmlspecialchars); + $this->htmlspecialchars = $this->getConfig('htmlspecialchars', '', $this->htmlspecialchars); } } @@ -140,8 +140,7 @@ public function getCompileFile($template = '') { } $dir = Wind::getRealDir($this->compileDir, true); if (!is_dir($dir)) - throw new WindViewException( - '[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); + throw new WindViewException('[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); $_tmp = explode('.', $template); foreach ($_tmp as $_dir) { !is_dir($dir) && @mkdir($dir); diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index a867471e..970a3d7d 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -122,6 +122,13 @@ public function getWindView() { return $this->windView; } + /** + * @param WindView $windView + */ + public function setWindView($windView) { + $this->windView = $windView; + } + /** * @return WindLayout */ @@ -139,37 +146,6 @@ public function getWindLayout() { */ class WindRender { - /** - * Convert special characters to HTML entities - * - * @param string $text | - * @return string | string The converted string - */ - public static function encode($text) { - return htmlspecialchars($text, ENT_QUOTES, Wind::getApp()->getResponse()->getCharset()); - } - - /** - * Convert special characters to HTML entities - * - * @param array $data - * @return array - */ - public static function encodeArray($data) { - $_tmp = array(); - $_charset = Wind::getApp()->getRequest()->getCharset(); - foreach ($data as $key => $value) { - if (is_string($key)) - $key = htmlspecialchars($key, ENT_QUOTES, $_charset); - if (is_string($value)) - $value = htmlspecialchars($value, ENT_QUOTES, $_charset); - elseif (is_array($value)) - $value = self::encodeArray($value); - $_tmp[$key] = $value; - } - return $_tmp; - } - /** * @param string $tpl * @param array $vars @@ -179,8 +155,7 @@ public static function encodeArray($data) { public static function render($tpl, $vars, $viewer) { @extract($vars, EXTR_REFS); if (!@include ($tpl)) { - throw new WindViewException( - '[component.viewer.ViewerResolver.render] template name ' . $tpl, + throw new WindViewException('[component.viewer.ViewerResolver.render] template name ' . $tpl, WindViewException::VIEW_NOT_EXIST); } } From 3810d44002fb947f577f5d04cc45280b75184793 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 03:11:08 +0000 Subject: [PATCH 0436/1065] =?UTF-8?q?bug=20fixted:=20=E6=A8=A1=E6=9D=BFtem?= =?UTF-8?q?plate=E6=A0=87=E7=AD=BE=E6=94=AF=E6=8C=81=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2508 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindView.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index b16c19ce..647d1c17 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -121,6 +121,7 @@ public function getViewTemplate($template = '', $ext = '') { $template = $this->templateName; } !$ext && $ext = $this->templateExt; + //TODO return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); } @@ -138,6 +139,7 @@ public function getCompileFile($template = '') { if (!$template) { $template = $this->templateName; } + //TODO $dir = Wind::getRealDir($this->compileDir, true); if (!is_dir($dir)) throw new WindViewException('[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); From 505ec903347a4915ee09cdd2ac695e451be099e0 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 30 Aug 2011 05:29:39 +0000 Subject: [PATCH 0437/1065] =?UTF-8?q?template=E6=94=AF=E6=8C=81=E4=BC=A0?= =?UTF-8?q?=E5=85=A5=E5=91=BD=E5=90=8D=E6=A0=BC=E5=BC=8F=E7=9A=84=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2509 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindView.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index 647d1c17..9b5d87e9 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -112,6 +112,8 @@ public function setConfig($config) { * 模板路径解析 * 根据模板的逻辑名称,返回模板的绝对路径信息 * + * 【支持命名空间的方式】如果用户输入了命名空间的方式:APP:module.common.template.head 或是module.common.template.head + * * @param string $templateName * @param string $templateExt * @return string | false @@ -121,14 +123,21 @@ public function getViewTemplate($template = '', $ext = '') { $template = $this->templateName; } !$ext && $ext = $this->templateExt; - //TODO - return Wind::getRealPath($this->templateDir . '.' . $template, ($ext ? $ext : false)); + + //#命名空间的方式表示含有.号 + if (false === strpos($template, '.')) { + $template = $this->templateDir . '.' . $template; + } + return Wind::getRealPath($template, ($ext ? $ext : false)); } /** * 模板编译路径解析 * 根据模板的逻辑名称,返回模板的绝对路径信息 * + * 【支持命名空间的方式】如果用户输入了命名空间的方式:APP:module.common.template.head 或是module.common.template.head + * 如果含有命名空间的格式,则将该模板编译文件设置为"template_"前缀保存 + * * @param string $templateName * @param string $templateExt * @return string | false @@ -138,8 +147,10 @@ public function getCompileFile($template = '') { return; if (!$template) { $template = $this->templateName; + } elseif (false !== ($pos = strrpos($template, '.'))) {//#支持命名空间的方式 + $template = 'include.' . substr($template, $pos + 1); } - //TODO + $dir = Wind::getRealDir($this->compileDir, true); if (!is_dir($dir)) throw new WindViewException('[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); From 88879e8e22cd6ee5afe7d05775ae79140e11b227 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 30 Aug 2011 05:44:12 +0000 Subject: [PATCH 0438/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=AE=8C=E5=96=84.?= =?UTF-8?q?registerComponent=E7=9A=84=E6=97=B6=E5=80=99=E4=BC=A0=E5=85=A5?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E7=9A=84=E6=96=B9=E5=BC=8Fscope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2510 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 0cdb891a..4b698f08 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -203,7 +203,7 @@ public function setConfig($config) { * @param string $componentName */ public function registeComponent($componentName, $componentInstance, $scope) { - return $this->windFactory->registInstance($componentInstance, $componentName); + return $this->windFactory->registInstance($componentInstance, $componentName, $scope); } /** From 4e95fb86a98b3eed9291129030c9eb64303e3a33 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 30 Aug 2011 06:35:32 +0000 Subject: [PATCH 0439/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2511 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 970a3d7d..d8a3b51c 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -91,7 +91,6 @@ public function compile($template, $suffix = '', $output = false) { $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); $_output = $_windTemplate->compile($templateFile, $this); if ($output === false) { - $compileFile = $this->windView->getCompileFile($template); WindFile::write($compileFile, $_output); } return array($compileFile, $_output); From e05813f9cddeaf4322316ec154b0b0cefaf08af8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 07:43:36 +0000 Subject: [PATCH 0440/1065] =?UTF-8?q?bug=20fixted:=20=E5=9D=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2512 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/compiler/WindViewTemplate.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/wind/viewer/compiler/WindViewTemplate.php b/wind/viewer/compiler/WindViewTemplate.php index 19b38f06..20be4f7f 100644 --- a/wind/viewer/compiler/WindViewTemplate.php +++ b/wind/viewer/compiler/WindViewTemplate.php @@ -93,23 +93,21 @@ private function creatTagCompiler($content, $compiler, $regex, $windViewerResolv protected function getTags() { $_tags['internal'] = $this->createTag('internal', 'WIND:viewer.compiler.WindTemplateCompilerInternal', '/<\?php(.|\n)*?\?>/i'); + /*标签体增加在该位置*/ $_tags['template'] = $this->createTag('template', 'WIND:viewer.compiler.WindTemplateCompilerTemplate'); + $_tags['page'] = $this->createTag('page', 'WIND:viewer.compiler.WindTemplateCompilerPage'); + $_tags['action'] = $this->createTag('action', 'WIND:viewer.compiler.WindTemplateCompilerAction'); + $_tags['component'] = $this->createTag('component', 'WIND:viewer.compiler.WindTemplateCompilerComponent'); + /*标签解析结束*/ + $_tags += (array) parent::getTags(); $_tags['expression'] = $this->createTag('expression', 'WIND:viewer.compiler.WindTemplateCompilerEcho', '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); $_tags['echo'] = $this->createTag('echo', 'WIND:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); - /*标签体增加在该位置*/ - $_tags['page'] = $this->createTag('page', 'WIND:viewer.compiler.WindTemplateCompilerPage'); - $_tags['action'] = $this->createTag('action', 'WIND:viewer.compiler.WindTemplateCompilerAction'); + /* 块编译标签,嵌套变量处理 */ $_tags['script'] = $this->createTag('script', 'WIND:viewer.compiler.WindTemplateCompilerScript', '/()*/i'); //$_tags['link'] = $this->createTag('link', 'WIND:viewer.compiler.WindTemplateCompilerCss'); //$_tags['style'] = $this->createTag('style', 'WIND:viewer.compiler.WindTemplateCompilerCss'); - $_tags['component'] = $this->createTag('component', 'WIND:viewer.compiler.WindTemplateCompilerComponent'); - /*标签解析结束*/ - $_tags += (array) parent::getTags(); - /*$_tags['expression'] = $this->createTag('expression', 'WIND:viewer.compiler.WindTemplateCompilerEcho', - '/({@|{\$[\w$]{1})[^}{@=\n]*}/i'); - $_tags['echo'] = $this->createTag('echo', 'WIND:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i');*/ return $_tags; } From e15c7ea6a8710ce61821a48d72be16f6a864e1e0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 08:19:02 +0000 Subject: [PATCH 0441/1065] =?UTF-8?q?bug=20fixted:=20=E5=9D=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2513 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindView.php | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index 9b5d87e9..3d1595fd 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -111,23 +111,18 @@ public function setConfig($config) { /** * 模板路径解析 * 根据模板的逻辑名称,返回模板的绝对路径信息 - * - * 【支持命名空间的方式】如果用户输入了命名空间的方式:APP:module.common.template.head 或是module.common.template.head + * 【支持命名空间的方式】如果用户输入了命名空间的方式:APP:module.common.template.head * * @param string $templateName * @param string $templateExt * @return string | false */ public function getViewTemplate($template = '', $ext = '') { - if (!$template) { + if (!$template) $template = $this->templateName; - } !$ext && $ext = $this->templateExt; - - //#命名空间的方式表示含有.号 - if (false === strpos($template, '.')) { + if (false === strpos($template, ':')) $template = $this->templateDir . '.' . $template; - } return Wind::getRealPath($template, ($ext ? $ext : false)); } @@ -135,7 +130,7 @@ public function getViewTemplate($template = '', $ext = '') { * 模板编译路径解析 * 根据模板的逻辑名称,返回模板的绝对路径信息 * - * 【支持命名空间的方式】如果用户输入了命名空间的方式:APP:module.common.template.head 或是module.common.template.head + * 【支持命名空间的方式】如果用户输入了命名空间的方式:APP:module.common.template.head * 如果含有命名空间的格式,则将该模板编译文件设置为"template_"前缀保存 * * @param string $templateName @@ -145,20 +140,23 @@ public function getViewTemplate($template = '', $ext = '') { public function getCompileFile($template = '') { if (!$this->compileDir) return; - if (!$template) { + if (!$template) $template = $this->templateName; - } elseif (false !== ($pos = strrpos($template, '.'))) {//#支持命名空间的方式 - $template = 'include.' . substr($template, $pos + 1); - } - + elseif (false !== ($pos = strpos($template, ':'))) + $template = 'external.' . substr($template, $pos + 1); + else + $template = $template; $dir = Wind::getRealDir($this->compileDir, true); - if (!is_dir($dir)) - throw new WindViewException('[component.viewer.WindView.getCompileFile] Template compile dir is not exist.'); - $_tmp = explode('.', $template); + if (!is_dir($dir)) { + throw new WindViewException( + '[viewer.WindView.getCompileFile] Template compile dir ' . $this->compileDir . ' is not exist.'); + } + $dir .= '/' . str_replace('.', '_', $template); + /*$_tmp = explode('.', $template); foreach ($_tmp as $_dir) { !is_dir($dir) && @mkdir($dir); $dir .= DIRECTORY_SEPARATOR . $_dir; - } + }*/ return $this->compileExt ? $dir . '.' . $this->compileExt : $dir; } From 8776b6a0e373e564b6b7e8cef746624e424797f4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 08:19:30 +0000 Subject: [PATCH 0442/1065] =?UTF-8?q?bug=20fixted:=20=E5=9D=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2514 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindView.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index 3d1595fd..0cbfb8ba 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -147,10 +147,9 @@ public function getCompileFile($template = '') { else $template = $template; $dir = Wind::getRealDir($this->compileDir, true); - if (!is_dir($dir)) { + if (!is_dir($dir)) throw new WindViewException( '[viewer.WindView.getCompileFile] Template compile dir ' . $this->compileDir . ' is not exist.'); - } $dir .= '/' . str_replace('.', '_', $template); /*$_tmp = explode('.', $template); foreach ($_tmp as $_dir) { From 1032fab296193198648af603201af5060367e389 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 08:19:42 +0000 Subject: [PATCH 0443/1065] =?UTF-8?q?bug=20fixted:=20=E5=9D=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2515 18ba2127-5a84-46d4-baec-3457e417f034 From e3292cbaa11eecfb601c007eb155bd50ad8d4240 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 08:23:30 +0000 Subject: [PATCH 0444/1065] =?UTF-8?q?bug=20fixted:=20=E5=9D=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2516 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 4b698f08..458f2bec 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -83,6 +83,7 @@ public function processRequest() { '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', 404); $module = WindUtility::mergeArray($this->defaultModule, $module); + $this->setModules($this->handlerAdapter->getModule(), $module, true); $handlerPath = @$module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . @$module['controller-suffix']; if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( @@ -159,21 +160,9 @@ protected function sendErrorMessage($exception) { * @param array $config * @return array */ - public function setModules($name, $config = array()) { - if (!isset($this->_config['modules'][$name])) { + public function setModules($name, $config = array(), $replace = false) { + if ($replace || !isset($this->_config['modules'][$name])) $this->_config['modules'][$name] = (array) $config; - } - - /*if (isset($this->_config['modules']['default'])) - $_default = $this->_config['modules']['default']; - else { - $this->_config['modules']['default'] = $_default; - } - if (!$config) - $this->_config['modules'][$name] = $_default; - else - $this->_config['modules'][$name] = WindUtility::mergeArray($_default, $config); - return $this->_config['modules'][$name];*/ } /** From 63b157e2dd956e8c1a42935ec2ece0c68ecf2a48 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 08:27:47 +0000 Subject: [PATCH 0445/1065] =?UTF-8?q?bug=20fixted:=20=E5=9D=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2517 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 78 ++++++++++++++++++--------------------------------- 1 file changed, 27 insertions(+), 51 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 421173a7..0a07186e 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -40,7 +40,7 @@ public static function application($appName = 'default', $config = array(), $roo $factory = new WindFactory(@include (Wind::getRealPath(self::$_components))); if ($config && !is_array($config)) $config = $factory->getInstance('configParser')->parse($config); - $appClass = @$config['class'] ? $config['class'] : 'windWebApp'; + $appClass = isset($config['class']) ? $config['class'] : 'windWebApp'; $application = $factory->getInstance($appClass, array($config, $factory)); if (!$application instanceof IWindApplication) throw new WindException('[Wind.application] ' . get_class($application), @@ -311,56 +311,32 @@ private static function _setImport($className, $classPath) { * @return */ private static function _loadBaseLib() { - self::$_classes = array( - 'IWindApplication' => 'base/IWindApplication', - 'IWindFactory' => 'base/IWindFactory', - 'WindActionException' => 'base/WindActionException', - 'WindClassProxy' => 'base/WindClassProxy', - 'WindEnableValidateModule' => 'base/WindEnableValidateModule', - 'WindErrorMessage' => 'base/WindErrorMessage', - 'WindException' => 'base/WindException', - 'WindFactory' => 'base/WindFactory', - 'WindFinalException' => 'base/WindFinalException', - 'WindHelper' => 'base/WindHelper', - 'WindModule' => 'base/WindModule', - 'WindActionFilter' => 'filter/WindActionFilter', - 'WindFilter' => 'filter/WindFilter', - 'WindFilterChain' => 'filter/WindFilterChain', - 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', - 'WindUrlFilter' => 'web/filter/WindUrlFilter', - 'WindFormListener' => 'web/listener/WindFormListener', - 'WindValidateListener' => 'web/listener/WindValidateListener', - 'WindController' => 'web/WindController', - 'WindDispatcher' => 'web/WindDispatcher', - 'WindErrorHandler' => 'web/WindErrorHandler', - 'WindForward' => 'web/WindForward', - 'WindSimpleController' => 'web/WindSimpleController', - 'WindSystemConfig' => 'web/WindSystemConfig', - 'WindUrlHelper' => 'web/WindUrlHelper', - 'WindWebApplication' => 'web/WindWebApplication', - 'AbstractWindRouter' => 'router/AbstractWindRouter', - 'AbstractWindRoute' => 'router/route/AbstractWindRoute', - 'WindRewriteRoute' => 'router/route/WindRewriteRoute', - 'WindRoute' => 'router/route/WindRoute', - 'WindRouter' => 'router/WindRouter', - 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter', - 'IWindRequest' => 'http/request/IWindRequest', - 'WindHttpRequest' => 'http/request/WindHttpRequest', - 'IWindResponse' => 'http/response/IWindResponse', - 'WindHttpResponse' => 'http/response/WindHttpResponse', - 'WindDate' => 'utility/date/WindDate', - 'WindGeneralDate' => 'utility/date/WindGeneralDate', - 'WindDecoder' => 'utility/json/WindDecoder', - 'WindEncoder' => 'utility/json/WindEncoder', - 'WindArray' => 'utility/WindArray', - 'WindFile' => 'utility/WindFile', - 'WindImage' => 'utility/WindImage', - 'WindPack' => 'utility/WindPack', - 'WindSecurity' => 'utility/WindSecurity', - 'WindString' => 'utility/WindString', - 'WindUtility' => 'utility/WindUtility', - 'WindValidator' => 'utility/WindValidator'); + self::$_classes = array('IWindApplication' => 'base/IWindApplication', 'IWindFactory' => 'base/IWindFactory', + 'WindActionException' => 'base/WindActionException', 'WindClassProxy' => 'base/WindClassProxy', + 'WindEnableValidateModule' => 'base/WindEnableValidateModule', 'WindErrorMessage' => 'base/WindErrorMessage', + 'WindException' => 'base/WindException', 'WindFactory' => 'base/WindFactory', + 'WindFinalException' => 'base/WindFinalException', 'WindHelper' => 'base/WindHelper', + 'WindModule' => 'base/WindModule', 'WindActionFilter' => 'filter/WindActionFilter', + 'WindFilter' => 'filter/WindFilter', 'WindFilterChain' => 'filter/WindFilterChain', + 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', + 'WindUrlFilter' => 'web/filter/WindUrlFilter', 'WindFormListener' => 'web/listener/WindFormListener', + 'WindValidateListener' => 'web/listener/WindValidateListener', 'WindController' => 'web/WindController', + 'WindDispatcher' => 'web/WindDispatcher', 'WindErrorHandler' => 'web/WindErrorHandler', + 'WindForward' => 'web/WindForward', 'WindSimpleController' => 'web/WindSimpleController', + 'WindSystemConfig' => 'web/WindSystemConfig', 'WindUrlHelper' => 'web/WindUrlHelper', + 'WindWebApplication' => 'web/WindWebApplication', 'AbstractWindRouter' => 'router/AbstractWindRouter', + 'AbstractWindRoute' => 'router/route/AbstractWindRoute', + 'WindRewriteRoute' => 'router/route/WindRewriteRoute', 'WindRoute' => 'router/route/WindRoute', + 'WindRouter' => 'router/WindRouter', 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter', + 'IWindRequest' => 'http/request/IWindRequest', 'WindHttpRequest' => 'http/request/WindHttpRequest', + 'IWindResponse' => 'http/response/IWindResponse', 'WindHttpResponse' => 'http/response/WindHttpResponse', + 'WindDate' => 'utility/date/WindDate', 'WindGeneralDate' => 'utility/date/WindGeneralDate', + 'WindDecoder' => 'utility/json/WindDecoder', 'WindEncoder' => 'utility/json/WindEncoder', + 'WindArray' => 'utility/WindArray', 'WindFile' => 'utility/WindFile', 'WindImage' => 'utility/WindImage', + 'WindPack' => 'utility/WindPack', 'WindSecurity' => 'utility/WindSecurity', + 'WindString' => 'utility/WindString', 'WindUtility' => 'utility/WindUtility', + 'WindValidator' => 'utility/WindValidator'); } } Wind::init(); From 5175f62beec698c1acfe8c0456a14eb43912ee2b Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 08:28:50 +0000 Subject: [PATCH 0446/1065] =?UTF-8?q?bug=20fixted:=20=E5=9D=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2518 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index d8a3b51c..8bf29578 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -62,11 +62,7 @@ public function windFetch($template = '') { /* (non-PHPdoc) * @see IWindViewerResolver::windAssign() */ - public function windAssign($vars, $key = '') { - /*if ($key === '') - $key = $this->windView->templateName; - $this->vars[$key] = $vars;*/ - } + public function windAssign($vars, $key = '') {} /** * 编译模板并返回编译后模板名称, @@ -104,16 +100,6 @@ private function checkReCompile() { return WIND_DEBUG || $this->getWindView()->isCompile; } - /** - * 当前模板内容 - * @param string $template - */ - private function getContent($template = '') { - !$template && $template = $this->windView->templateName; - if ($template) - echo $this->windFetch($template); - } - /** * @return WindView */ @@ -134,7 +120,6 @@ public function setWindView($windView) { public function getWindLayout() { return $this->_getWindLayout('', $this); } - } /** From 9a7acdc3fa18a95f3acf03e6f15c7986cafe7e67 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 09:42:04 +0000 Subject: [PATCH 0447/1065] =?UTF-8?q?bug=20fixted:=20=E5=9D=97=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2519 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindView.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index 0cbfb8ba..75b9b6bd 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -143,7 +143,7 @@ public function getCompileFile($template = '') { if (!$template) $template = $this->templateName; elseif (false !== ($pos = strpos($template, ':'))) - $template = 'external.' . substr($template, $pos + 1); + $template = '__external.' . substr($template, $pos + 1); else $template = $template; $dir = Wind::getRealDir($this->compileDir, true); From 397324c0439ff373b7a009332935362b2236ff22 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 09:43:11 +0000 Subject: [PATCH 0448/1065] =?UTF-8?q?bug=20fixted:=20=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2520 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 8bf29578..58ccbd3d 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -136,11 +136,10 @@ class WindRender { * @param WindViewerResolver $viewer * @throws WindViewException */ - public static function render($tpl, $vars, $viewer) { - @extract($vars, EXTR_REFS); - if (!@include ($tpl)) { - throw new WindViewException('[component.viewer.ViewerResolver.render] template name ' . $tpl, + public static function render($__tpl, $__vars, $__viewer) { + @extract($__vars, EXTR_REFS); + if (!@include ($__tpl)) + throw new WindViewException('[component.viewer.ViewerResolver.render] template name ' . $__tpl, WindViewException::VIEW_NOT_EXIST); - } } } \ No newline at end of file From 8b16782d766ab774758f4132d4e6740ed7621bbd Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 09:44:12 +0000 Subject: [PATCH 0449/1065] =?UTF-8?q?bug=20fixted:=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E4=B8=AA=E6=95=B0=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2521 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindDispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/web/WindDispatcher.php b/wind/web/WindDispatcher.php index 7cecb848..7e06ca13 100644 --- a/wind/web/WindDispatcher.php +++ b/wind/web/WindDispatcher.php @@ -39,7 +39,7 @@ public function dispatch($forward, $router, $display) { $vars = $forward->getVars(); Wind::getApp()->getResponse()->setData($vars, $view->templateName); Wind::getApp()->getResponse()->setData($vars['G'], true); - $view->render($forward, $router, $this->display); + $view->render($this->display); } $this->display = false; } From 62e7cc6f8a29cea40a362778c21ef4e7fbec1ad0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 09:45:03 +0000 Subject: [PATCH 0450/1065] =?UTF-8?q?bug=20fixted:=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E4=B8=AA=E6=95=B0=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2522 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindDispatcher.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/web/WindDispatcher.php b/wind/web/WindDispatcher.php index 7e06ca13..8da5831d 100644 --- a/wind/web/WindDispatcher.php +++ b/wind/web/WindDispatcher.php @@ -38,7 +38,7 @@ public function dispatch($forward, $router, $display) { if ($view->templateName) { $vars = $forward->getVars(); Wind::getApp()->getResponse()->setData($vars, $view->templateName); - Wind::getApp()->getResponse()->setData($vars['G'], true); + Wind::getApp()->getResponse()->setData($vars['G'], '', true); $view->render($this->display); } $this->display = false; @@ -54,8 +54,8 @@ public function dispatch($forward, $router, $display) { protected function dispatchWithRedirect($forward, $router) { $_url = $forward->getUrl(); if (!$_url && $forward->getIsReAction()) { - $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), - $forward->getController(), $forward->getArgs()); + $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), + $forward->getArgs()); if ($this->checkToken($router)) throw new WindFinalException( '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, From 4a7201bece545ba6930978920d26506a8ea567f1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 09:46:07 +0000 Subject: [PATCH 0451/1065] =?UTF-8?q?bug=20fixted:=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E4=B8=AA=E6=95=B0=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2523 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 458f2bec..0539ba8f 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -89,7 +89,7 @@ public function processRequest() { Wind::getApp()->getComponent('windLogger')->info( '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); - $this->getSystemFactory()->addClassDefinitions($handlerPath, + $this->windFactory->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'prototype', 'proxy' => true, 'config' => $this->getConfig('actionmap'), 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), From 019278cb325504510e02171efda08e6d4c524850 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 30 Aug 2011 11:04:18 +0000 Subject: [PATCH 0452/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2524 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindView.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index 75b9b6bd..50d78504 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -144,8 +144,7 @@ public function getCompileFile($template = '') { $template = $this->templateName; elseif (false !== ($pos = strpos($template, ':'))) $template = '__external.' . substr($template, $pos + 1); - else - $template = $template; + $dir = Wind::getRealDir($this->compileDir, true); if (!is_dir($dir)) throw new WindViewException( From e94894830c646fff7d19cda695a31dffd8864b44 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 30 Aug 2011 11:19:03 +0000 Subject: [PATCH 0453/1065] =?UTF-8?q?bug=20fixted:=20=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2525 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 0539ba8f..2c72d53e 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -82,7 +82,7 @@ public function processRequest() { throw new WindActionException( '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', 404); - $module = WindUtility::mergeArray($this->defaultModule, $module); + $module = WindUtility::mergeArray($this->getModules('default'), $module); $this->setModules($this->handlerAdapter->getModule(), $module, true); $handlerPath = @$module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . @$module['controller-suffix']; if (WIND_DEBUG & 2) From 3085bb49619836e3ffab206da72ad10f8b3810e7 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 30 Aug 2011 11:22:29 +0000 Subject: [PATCH 0454/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2526 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 2c72d53e..e89aa2e5 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -128,9 +128,9 @@ protected function sendErrorMessage($exception) { if (!$_errorAction = $errorMessage->getErrorAction()) { $module = $this->getModules($moduleName); if (empty($module)) - $module = $this->setModules('default'); + $module = $this->getModules('default'); preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); - $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0])))); + $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0]) + 1))); $_errorAction = 'error/' . @$matchs[0] . '/run/'; $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); From c4e6b574be5838a0a9fb542da71f26c507114cea Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Tue, 30 Aug 2011 11:30:49 +0000 Subject: [PATCH 0455/1065] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B9=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2527 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/db/WindConnection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/db/WindConnection.php b/wind/db/WindConnection.php index 3d592b20..4e3aad3c 100644 --- a/wind/db/WindConnection.php +++ b/wind/db/WindConnection.php @@ -243,7 +243,7 @@ public function setConfig($config) { $this->_pwd = $this->getConfig('pwd', '', $this->_pwd); $this->_enableLog = $this->getConfig('enablelog', '', $this->_enableLog); $this->_charset = $this->getConfig('charset', '', $this->_charset); - $this->_tablePrefix = $this->getConfig('tableprefix', '', $this->_tablePrefix); + $this->_tablePrefix = $this->getConfig('prefix', '', ''); } /** From 47d341a8d95b19c3c3cf9a01111b53f0890102cb Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 31 Aug 2011 04:12:09 +0000 Subject: [PATCH 0456/1065] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2528 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 4 ++-- wind/base/WindClassProxy.php | 4 ++-- wind/base/WindFactory.php | 6 +++--- wind/filter/WindHandlerInterceptorChain.php | 2 +- wind/web/WindController.php | 4 ++-- wind/web/WindDispatcher.php | 6 +++--- wind/web/WindWebApplication.php | 6 +++--- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 0a07186e..0418ecdf 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -92,8 +92,8 @@ public static function resetApp() { * 如果加载的包中有子文件夹不进行循环加载 * 参数格式说明:'WIND:base.WFrontController' * WIND 注册的应用名称,应用名称与路径信息用‘:’号分隔 - * core.base.WFrontController 相对的路径信息 - * 如果不填写应用名称 ,例如‘core.base.WFrontController’,那么加载路径则相对于默认的应用路径 + * base.WFrontController 相对的路径信息 + * 如果不填写应用名称 ,例如‘base.WFrontController’,那么加载路径则相对于默认的应用路径 * * 加载一个类的参数方式:'WIND:base.WFrontController' * 加载一个包的参数方式:'WIND:base.*' diff --git a/wind/base/WindClassProxy.php b/wind/base/WindClassProxy.php index 2326b051..2b1a3c2d 100644 --- a/wind/base/WindClassProxy.php +++ b/wind/base/WindClassProxy.php @@ -36,7 +36,7 @@ public function registerEventListener($event, $listener, $type = self::EVENT_TYP if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) { throw new WindException( - '[core.factory.proxy.WindClassProxy.registerEventListener] Unsupport event type:' . $type, + '[base.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR); } !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array(); @@ -123,7 +123,7 @@ private function _getInterceptorChain($event = '') { $this->_interceptorChainObj = $interceptorChain; } else throw new WindException( - '[core.factory.proxy.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); + '[base.WindClassProxy._getInterceptorChain] Unable to create interceptorChain.'); } $this->_interceptorChainObj->reset(); return $this->_interceptorChainObj; diff --git a/wind/base/WindFactory.php b/wind/base/WindFactory.php index 9237e2ec..61e6c1f6 100644 --- a/wind/base/WindFactory.php +++ b/wind/base/WindFactory.php @@ -96,7 +96,7 @@ static public function createInstance($className, $args = array()) { } } catch (Exception $e) { throw new WindException( - '[core.factory.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), + '[base.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } @@ -120,7 +120,7 @@ public function addClassDefinitions($alias, $classDefinition) { $this->classDefinitions[$alias] = $classDefinition; } else throw new WindException( - '[core.factory.WindFactory.addClassDefinitions] class alias is empty.', + '[base.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } @@ -207,7 +207,7 @@ protected function executeInitMethod($initMethod, $instance) { return call_user_func_array(array($instance, $initMethod), array()); } catch (Exception $e) { throw new WindException( - '[core.factory.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', + '[base.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } } diff --git a/wind/filter/WindHandlerInterceptorChain.php b/wind/filter/WindHandlerInterceptorChain.php index b7b53fb5..b9c8d718 100644 --- a/wind/filter/WindHandlerInterceptorChain.php +++ b/wind/filter/WindHandlerInterceptorChain.php @@ -34,7 +34,7 @@ public function handle() { return null; if (is_string($this->_callBack) && !function_exists($this->_callBack)) { throw new WindException( - '[core.filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, + '[filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, WindException::ERROR_FUNCTION_NOT_EXIST); } return call_user_func_array($this->_callBack, (array) $this->_args); diff --git a/wind/web/WindController.php b/wind/web/WindController.php index 8c70fea6..7e13684a 100644 --- a/wind/web/WindController.php +++ b/wind/web/WindController.php @@ -15,11 +15,11 @@ protected function resolvedActionMethod($handlerAdapter) { if ($action !== 'run') $action = $this->resolvedActionName($action); if ($action == 'doAction') - throw new WindException('[core.web.WindController.resolvedActionMethod]', + throw new WindException('[web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); $method = new ReflectionMethod($this, $action); if ($method->isAbstract() || !$method->isPublic()) { - throw new WindException('[core.web.WindController.resolvedActionMethod]', + throw new WindException('[web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); } return $action; diff --git a/wind/web/WindDispatcher.php b/wind/web/WindDispatcher.php index 8da5831d..d2f2e279 100644 --- a/wind/web/WindDispatcher.php +++ b/wind/web/WindDispatcher.php @@ -58,7 +58,7 @@ protected function dispatchWithRedirect($forward, $router) { $forward->getArgs()); if ($this->checkToken($router)) throw new WindFinalException( - '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, + '[web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); } else @@ -76,7 +76,7 @@ protected function dispatchWithRedirect($forward, $router) { */ protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) - throw new WindException('[core.web.WindDispatcher.dispatchWithAction] forward fail.', + throw new WindException('[web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $args = $forward->getArgs(); @@ -93,7 +93,7 @@ protected function dispatchWithAction($forward, $router, $display) { $router->setModule($_tmp); if ($this->checkToken($router)) throw new WindFinalException( - '[core.web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, + '[web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); Wind::getApp()->processRequest(); diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index e89aa2e5..5b11f0c0 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -80,14 +80,14 @@ public function processRequest() { $this->handlerAdapter->setModule('default'); if (!($module = $this->getModules())) throw new WindActionException( - '[core.web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', + '[web.WindWebApplication.processRequest] Your requested \'' . $this->handlerAdapter->getModule() . '\' was not found on this server.', 404); $module = WindUtility::mergeArray($this->getModules('default'), $module); $this->setModules($this->handlerAdapter->getModule(), $module, true); $handlerPath = @$module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . @$module['controller-suffix']; if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( - '[core.web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); + '[web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); $this->windFactory->addClassDefinitions($handlerPath, array('path' => $handlerPath, 'scope' => 'prototype', 'proxy' => true, @@ -98,7 +98,7 @@ public function processRequest() { if (!$handler) throw new WindActionException( - '[core.web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', + '[web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { From c98100ab521c6aab86f54a477b7d80b87cccc608 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 31 Aug 2011 10:17:46 +0000 Subject: [PATCH 0457/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9Adbmanager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2529 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/db/WindConnection.php | 90 +++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 50 deletions(-) diff --git a/wind/db/WindConnection.php b/wind/db/WindConnection.php index 4e3aad3c..c7c190dd 100644 --- a/wind/db/WindConnection.php +++ b/wind/db/WindConnection.php @@ -13,21 +13,20 @@ class WindConnection extends WindModule { * PDO 链接字符串 * @var string */ - private $_dsn; - private $_driverName; - private $_user; - private $_pwd; - private $_tablePrefix; - private $_charset; - private $_enableLog = false; + protected $_dsn; + protected $_driverName; + protected $_user; + protected $_pwd; + protected $_tablePrefix; + protected $_charset; /** * @var array */ - private $_attributes = array(); + protected $_attributes = array(); /** * @var PDO */ - private $_dbHandle = null; + protected $_dbHandle = null; /** * @param string $dsn @@ -46,7 +45,7 @@ public function __construct($dsn = '', $username = '', $password = '') { * @return WindSqlStatement */ public function createStatement($sql = null) { - return new WindSqlStatement($this, $sql); + return new WindSqlStatement($this, $this->parseQueryString($sql)); } /** @@ -54,8 +53,7 @@ public function createStatement($sql = null) { * @return WindMysqlPdoAdapter */ public function getDbHandle() { - if ($this->_dbHandle === null) - $this->init(); + $this->init(); return $this->_dbHandle; } @@ -64,9 +62,7 @@ public function getDbHandle() { * @param string $attribute * @return string * */ - public function getAttribute($attribute = '') { - if (!$attribute) - return; + public function getAttribute($attribute) { if ($this->_dbHandle !== null) { return $this->_dbHandle->getAttribute($attribute); } else @@ -82,7 +78,7 @@ public function getAttribute($attribute = '') { public function setAttribute($attribute, $value = null) { if (!$attribute) return; - if ($this->_dbHandle !== null && $this->_dbHandle instanceof PDO) { + if ($this->_dbHandle !== null) { $this->_dbHandle->setAttribute($attribute, $value); } else $this->_attributes[$attribute] = $value; @@ -110,11 +106,10 @@ public function getDriverName() { */ public function execute($sql) { try { - $result = $this->getDbHandle()->exec($sql); + $result = $this->getDbHandle()->exec($this->parseQueryString($sql)); if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindConnection.execute] \r\n\tSQL: " . $sql . - " \r\n\tResult:" . WindString::varToString( + "[db.WindConnection.execute] \r\n\tSQL: " . $sql . " \r\n\tResult:" . WindString::varToString( $result)); return $result; } catch (PDOException $e) { @@ -130,8 +125,8 @@ public function execute($sql) { */ public function query($sql) { try { - $statement = $this->getDbHandle()->query($sql); - return new WindResultSet($statement); + $sql = $this->parseQueryString($sql); + return new WindResultSet($this->getDbHandle()->query($sql)); } catch (PDOException $e) { throw new WindDbException(); } @@ -139,7 +134,6 @@ public function query($sql) { /** * 过滤SQL元数据,数据库对象(如表名字,字段等) - * * @param string $data * @throws WindDbException */ @@ -150,7 +144,6 @@ public function sqlMetadata($data) { /** * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组 - * * @param array $array */ public function quoteArray($array) { @@ -159,7 +152,6 @@ public function quoteArray($array) { /** * sql元数据安全过滤 - * * @param string $string */ public function quote($string) { @@ -168,7 +160,6 @@ public function quote($string) { /** * 组装单条 key=value 形式的SQL查询语句值 insert/update并进行安全过滤 - * * @param array $array */ public function sqlSingle($array) { @@ -177,18 +168,15 @@ public function sqlSingle($array) { /** * 创建表 - * * @param string $tableName * @param array $fileds */ public function createTable($tableName, $values, $engine = '', $autoIncrement = '') { - return $this->getDbHandle()->createTable($tableName, $values, $engine, $this->_charset, - $autoIncrement); + return $this->getDbHandle()->createTable($tableName, $values, $engine, $this->_charset, $autoIncrement); } /** * 返回最后一条插入数据ID - * * @param string $name * @return int */ @@ -208,24 +196,23 @@ public function close() { /** * 初始化DB句柄 - * * @throws Exception * @return */ public function init() { try { + if ($this->_dbHandle !== null) + return; $driverName = $this->getDriverName(); $dbHandleClass = "WIND:db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; $dbHandleClass = Wind::import($dbHandleClass); - $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, - (array) $this->_attributes); + $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->_dbHandle->setCharset($this->_charset); - if (WIND_DEBUG & 2) { + if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindConnection.init] Initialize db connection success. \r\n\tDSN:" . $this->_dsn . "\r\n\tUser:" . $this->_user . "\r\n\tCharset:" . $this->_charset . "\r\n\tTablePrefix:" . $this->_tablePrefix . "\r\n\tDriverName:" . $this->_driverName, - 'component.db'); - } + "[db.WindConnection.init] Initialize db connection success. \r\n\tDSN:" . $this->_dsn . "\r\n\tUser:" . $this->_user . "\r\n\tCharset:" . $this->_charset . "\r\n\tTablePrefix:" . $this->_tablePrefix . "\r\n\tDriverName:" . $this->_driverName, + 'db'); } catch (PDOException $e) { $this->close(); throw new WindDbException($e->getMessage()); @@ -238,28 +225,31 @@ public function init() { */ public function setConfig($config) { parent::setConfig($config); - $this->_dsn = $this->getConfig('dsn', '', $this->_dsn); - $this->_user = $this->getConfig('user', '', $this->_user); - $this->_pwd = $this->getConfig('pwd', '', $this->_pwd); - $this->_enableLog = $this->getConfig('enablelog', '', $this->_enableLog); - $this->_charset = $this->getConfig('charset', '', $this->_charset); - $this->_tablePrefix = $this->getConfig('prefix', '', ''); + $this->_attributes = array(); + $this->_initConfig(); } /** - * 获得是否启用日志记录功能 - * @return boolean $enableLog + * 根据配置信息,初始化当前连接对象 + * @param array $config */ - public function getEnableLog() { - return $this->_enableLog; + protected function _initConfig($config = array()) { + $this->_dsn = $this->getConfig('dsn', '', '', $config); + $this->_user = $this->getConfig('user', '', '', $config); + $this->_pwd = $this->getConfig('pwd', '', '', $config); + $this->_charset = $this->getConfig('charset', '', '', $config); + $this->_tablePrefix = $this->getConfig('tableprefix', '', '', $config); } /** - * 设置是否启用日志记录功能 - * @param boolean $enableLog + * @param string $sql */ - public function setEnableLog($enableLog) { - $this->_enableLog = (boolean) $enableLog; + protected function parseQueryString($sql) { + if ($_prefix = $this->getTablePrefix()) { + list($new, $old) = explode('|', $_prefix . '|'); + $sql = preg_replace('/{(' . $old . ')?(.*?)}/', $new . '\2', $sql); + } + return $sql; } /** From 7c7510f914c73e428cba0422f10142ce2deffb46 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 31 Aug 2011 10:17:58 +0000 Subject: [PATCH 0458/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9Adbmanager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2530 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/db/WindConnectionManager.php | 165 +++++++++++++++++++++++++----- wind/db/WindSqlStatement.php | 56 +++------- 2 files changed, 152 insertions(+), 69 deletions(-) diff --git a/wind/db/WindConnectionManager.php b/wind/db/WindConnectionManager.php index 03e00bca..f754194c 100644 --- a/wind/db/WindConnectionManager.php +++ b/wind/db/WindConnectionManager.php @@ -1,54 +1,82 @@ - * + * 配置说明: + * 1. 当没有任何策略部署时 ,默认返回当前配置中的第一个链接句柄 + * 2. 当没有任何策略部署时,如果在sql语句中有链接句柄指定时则返回指定的链接句柄 + * 例如:'{db1:tableName}'返回db1指定的链接句柄 + * 3. 如果当前有策略部署时,则按照策略部署规则返回 + * 配置格式如下: + * + * * mysql:host=localhost;dbname=test * root * root * utf8 * pw_ * - * + * * mysql:host=localhost;dbname=test * root * root * utf8 * pw_ * - * + * * the last known user to change this file in the repository <$LastChangedBy$> * @author Qiong Wu * @version $Id$ * @package */ class WindConnectionManager extends WindConnection { + /** + * 数据库连接池策略部署配置信息 + * @var array + */ + private $except = array('_current' => '', '_default' => ''); /** * 链接池 * @var array */ - private $connPool = array(); + private $pool = array(); + /** + * 当前sql语句表名称 + * @var string + */ + private $tableName; + /** + * 当前的sql语句查询类型 + * @var string + */ + private $sqlType; + private $dbNames = array(); + + /* (non-PHPdoc) + * @see WindConnection::getDbHandle() + */ + public function getDbHandle() { + $this->init(); + return $this->_dbHandle; + } /* (non-PHPdoc) * @see WindConnection::init() */ public function init() { try { - $driverName = $this->getDriverName(); - $dbHandleClass = "WIND:db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; - $dbHandleClass = Wind::import($dbHandleClass); - $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, - (array) $this->_attributes); - $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->_dbHandle->setCharset($this->_charset); - if (WIND_DEBUG & 2) { - $reflection = new ReflectionClass(get_class($this)); - $properties = $reflection->getProperties(); - Wind::getApp()->getComponent('windLogger')->info( - "component.db.WindConnection.init() Initialize db connection success." . WindString::varToString( - $properties), 'component.db'); + if (!isset($this->pool[$this->except['_current']])) { + $driverName = $this->getDriverName(); + $dbHandleClass = "WIND:db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter"; + $dbHandleClass = Wind::import($dbHandleClass); + $_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes); + $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $_dbHandle->setCharset($this->_charset); + $this->pool[$this->except['_current']] = $_dbHandle; } + $this->_dbHandle = $this->pool[$this->except['_current']]; + if (WIND_DEBUG & 2) + Wind::getApp()->getComponent('windLogger')->info( + "db.WindConnection.init() Initialize db connection success.", 'db'); } catch (PDOException $e) { $this->close(); throw new WindDbException($e->getMessage()); @@ -56,16 +84,97 @@ public function init() { } /* (non-PHPdoc) - * @see WindModule::setConfig() + * @see WindConnection::parseQueryString() */ - public function setConfig($config) { - if ($config) { - if (is_string($config)) - $config = Wind::getApp()->getComponent('configParser')->parse($config); - if (!empty($this->_config)) { - $this->_config = array_merge($this->_config, (array) $config); - } else - $this->_config = $config; + protected function parseQueryString($sql) { + $sql = preg_replace_callback('/^([a-zA-Z]*)\s[\w\*\s]+(\{([\w]+\:)?([\w]+\.)?([\w]+)\})?[\w\s\<\=\:]*/i', + array($this, '_pregQueryString'), $sql); + if (!$this->except['_current']) { + //TODO 通配符支持 + $_c = isset($this->except[$this->tableName]) ? $this->except[$this->tableName] : $this->except['_default']; + $this->_resolveCurrentDb($_c); + !$this->except['_current'] && $this->except['_current'] = $this->dbNames[0]; + } + $_config = $this->getConfig($this->except['_current']); + if (!$_config) + throw new WindDbException( + '[db.WindConnectionManager.init] db connection ' . $this->except['_current'] . ' is not exist.'); + parent::_initConfig($_config); + return parent::parseQueryString($sql); + } + + /** + * @param array $_c + */ + private function _resolveCurrentDb($_c) { + if ($_c) + switch ($this->sqlType) { + case 'SELECT': + if (is_array($_c['_s']) && !empty($_c['_s'])) { + $_count = count((array) $_c['_s']); + if ($_count > 1) + $this->except['_current'] = $_c['_s'][rand(0, $_count - 1)]; + else + $this->except['_current'] = $_c['_s'][0]; + break; + } + default: + $this->except['_current'] = $_c['_m']; + break; + } + } + + /** + * Array( + * [0] => SELECT * FROM {db1:database.members} WHERE uid<=:uid | 匹配到的完整str + * [1] => SELECT | 当前的sql类型 + * [2] => {db1:database.members} | 当前table + * [3] => db1: | 当前table自定义链接 + * [4] => database. | 当前database + * [5] => members | 当前表名 + * ) + * @param array $matchs + */ + private function _pregQueryString($matchs) { + $this->sqlType = $matchs[1]; + if (isset($matchs[2])) { + $this->tableName = $matchs[5]; + $this->except['_current'] = trim($matchs[3], ':'); + $_return = str_replace($matchs[3] . $matchs[4], '', $matchs[0]); + } else + $_return = $matchs[0]; + return $_return; + } + + /* (non-PHPdoc) + * @see WindConnection::_initConfig() + */ + protected function _initConfig() { + if ($_except = $this->getConfig('connections', 'except')) { + preg_replace_callback('/([\w\*\,]+):([\w]+)\|*([\w\,]+)*/i', array($this, '_pregExcept'), $_except); + unset($this->_config['connections']['except']); + } + $this->_config = $this->getConfig('connections'); + $this->dbNames = array_keys($this->_config); + if (empty($this->dbNames)) + throw new WindDbException('[db.WindConnectionManager._initConfig] db config is required.'); + } + + /** + * 处理链接管理策略 + * @param array $matchs + * @throws WindDbException + */ + private function _pregExcept($matchs) { + $_keys = explode(',', $matchs[1]); + foreach ($_keys as $_v) { + if ($_v === '*') { + $this->except['_default']['_m'] = $matchs[2]; + $this->except['_default']['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array(); + break; + } + $this->except[$_v]['_m'] = $matchs[2]; + $this->except[$_v]['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array(); } } } \ No newline at end of file diff --git a/wind/db/WindSqlStatement.php b/wind/db/WindSqlStatement.php index 83acdb11..73806fe4 100644 --- a/wind/db/WindSqlStatement.php +++ b/wind/db/WindSqlStatement.php @@ -18,17 +18,18 @@ class WindSqlStatement { private $_statement = null; /** * sql语句字符串 - * * @var string */ private $_queryString; /** * PDO类型映射 - * * @var array */ - private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, - 'string' => PDO::PARAM_STR, 'NULL' => PDO::PARAM_NULL); + private $_typeMap = array('boolean' => PDO::PARAM_BOOL, 'integer' => PDO::PARAM_INT, 'string' => PDO::PARAM_STR, + 'NULL' => PDO::PARAM_NULL); + /** + * @var array + */ private $_columns = array(); /** @@ -39,7 +40,7 @@ class WindSqlStatement { */ public function __construct($connection, $query) { $this->_connection = $connection; - $this->setQueryString($query); + $this->_queryString = $query; } /** @@ -62,8 +63,7 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu if ($length === null) $this->getStatement()->bindParam($parameter, $variable, $dataType); else - $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, - $driverOptions); + $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, $driverOptions); return $this; } catch (PDOException $e) { throw new WindDbException($e->getMessage()); @@ -83,8 +83,7 @@ public function bindParam($parameter, &$variable, $dataType = null, $length = nu public function bindParams(&$parameters) { if (!is_array($parameters)) throw new WindDbException( - '[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype( - $parameters)); + '[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters)); $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1)); foreach ($parameters as $key => $value) { @@ -131,8 +130,7 @@ public function bindValue($parameter, $value, $data_type = null) { public function bindValues($values) { if (!is_array($values)) throw new WindDbException( - '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type \'' . gettype( - $values) . '\''); + '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type \'' . gettype($values) . '\''); $keied = (array_keys($values) !== range(0, sizeof($values) - 1)); foreach ($values as $key => $value) { @@ -270,18 +268,15 @@ public function lastInsertId($name = '') { public function execute($params = array(), $rowCount = true) { try { if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->profileBegin( - 'SQL:execute sql statement.', 'component.db'); + Wind::getApp()->getComponent('windLogger')->profileBegin('SQL:execute sql statement.', 'component.db'); $this->init(); $this->bindValues($params); $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; if (WIND_DEBUG & 2) { - Wind::getApp()->getComponent('windLogger')->profileEnd( - 'SQL:execute sql statement.', 'component.db'); + Wind::getApp()->getComponent('windLogger')->profileEnd('SQL:execute sql statement.', 'component.db'); Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindSqlStatement.execute] \r\n\tSQL:" . $this->getQueryString(), - 'component.db'); + "[component.db.WindSqlStatement.execute] \r\n\tSQL:" . $this->getQueryString(), 'component.db'); } return $_result; } catch (PDOException $e) { @@ -289,24 +284,6 @@ public function execute($params = array(), $rowCount = true) { } } - /** - * 设置查询预定义语句 - * - * @param string $queryString - * @return WindSqlStatement - */ - public function setQueryString($queryString) { - if (!$queryString) - return $this; - if ($_prefix = $this->getConnection()->getTablePrefix()) { - list($new, $old) = strpos($_prefix, '|') !== false ? explode('|', $_prefix) : array( - $_prefix, ''); - $queryString = preg_replace('/{(' . $old . ')?(.*?)}/', $new . '\2', $queryString); - } - $this->_queryString = $queryString; - return $this; - } - /** * 获得查询的预定义语句 * @@ -349,15 +326,12 @@ public function getColumns() { public function init() { if ($this->_statement === null) { try { - $this->_statement = $this->getConnection()->getDbHandle()->prepare( - $this->getQueryString()); + $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString()); if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindSqlStatement.init] Initialize statement success.", - 'component.db'); + "[component.db.WindSqlStatement.init] Initialize statement success.", 'component.db'); } catch (PDOException $e) { - throw new WindDbException( - "Initialization WindSqlStatement failed." . $e->getMessage()); + throw new WindDbException("Initialization WindSqlStatement failed." . $e->getMessage()); } } } From a37b8bf383f7d2e99f2a5451c4af945fed908d7e Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 31 Aug 2011 10:19:04 +0000 Subject: [PATCH 0459/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9Adbmanager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2531 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 0418ecdf..4bf1be69 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -339,22 +339,4 @@ private static function _loadBaseLib() { 'WindValidator' => 'utility/WindValidator'); } } -Wind::init(); - -/* 组件定义 */ -/*define('COMPONENT_WEBAPP', 'windWebApp'); -define('COMPONENT_ERRORHANDLER', 'errorHandler'); -define('COMPONENT_LOGGER', 'windLogger'); -define('COMPONENT_FORWARD', 'forward'); -define('COMPONENT_ROUTER', 'urlBasedRouter'); -define('COMPONENT_URLHELPER', 'urlHelper'); -define('COMPONENT_VIEW', 'windView'); -define('COMPONENT_VIEWRESOLVER', 'viewResolver'); -define('COMPONENT_TEMPLATE', 'template'); -define('COMPONENT_ERRORMESSAGE', 'errorMessage'); -define('COMPONENT_DB', 'db'); -define('COMPONENT_DISPATCHER', 'dispatcher'); -define('COMPONENT_CONFIGPARSER', 'configParser'); -define('COMPONENT_CACHE', 'windCache');*/ -//TODO 迁移更新框架内部的常量定义到这里 配置/异常类型等 注意区分异常命名空间和类型 -//********************约定变量*********************************** +Wind::init(); \ No newline at end of file From 9361de3a6500ee83699f91222bad4080cd06f2d4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 31 Aug 2011 10:19:26 +0000 Subject: [PATCH 0460/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9Adbmanager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2532 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/dao/WindDao.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/wind/dao/WindDao.php b/wind/dao/WindDao.php index 567e87ab..9dfab12c 100644 --- a/wind/dao/WindDao.php +++ b/wind/dao/WindDao.php @@ -17,12 +17,8 @@ class WindDao extends WindModule { * 根据用户配置决定配置是采用配置链接管理 * @return WindConnection */ - public function getConnection($name = '') { - $this->_getConnection(); - if ($this->connection instanceof WindConnectionManager) { - return $this->connection->getConnection($name); - } - return $this->connection; + public function getConnection() { + return $this->_getConnection(); } /** From 8341c480f593a9fd0dd5137d5db2031ceed7d514 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 1 Sep 2011 03:10:17 +0000 Subject: [PATCH 0461/1065] =?UTF-8?q?bug=20fixted:=20script=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E5=8C=B9=E9=85=8D=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2533 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/compiler/WindViewTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/viewer/compiler/WindViewTemplate.php b/wind/viewer/compiler/WindViewTemplate.php index 20be4f7f..61a2532f 100644 --- a/wind/viewer/compiler/WindViewTemplate.php +++ b/wind/viewer/compiler/WindViewTemplate.php @@ -105,7 +105,7 @@ protected function getTags() { $_tags['echo'] = $this->createTag('echo', 'WIND:viewer.compiler.WindTemplateCompilerEcho', '/\$[\w_]+/i'); /* 块编译标签,嵌套变量处理 */ $_tags['script'] = $this->createTag('script', 'WIND:viewer.compiler.WindTemplateCompilerScript', - '/()*/i'); + '/()*/i'); //$_tags['link'] = $this->createTag('link', 'WIND:viewer.compiler.WindTemplateCompilerCss'); //$_tags['style'] = $this->createTag('style', 'WIND:viewer.compiler.WindTemplateCompilerCss'); return $_tags; From d8e712c8df69684c4adcc30674016500cbd99137 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 1 Sep 2011 06:28:26 +0000 Subject: [PATCH 0462/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9Adbmanager=E9=80=9A=E9=85=8D=E7=AC=A6=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2534 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/db/WindConnectionManager.php | 49 ++++++++++++++++++------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/wind/db/WindConnectionManager.php b/wind/db/WindConnectionManager.php index f754194c..576fd7c5 100644 --- a/wind/db/WindConnectionManager.php +++ b/wind/db/WindConnectionManager.php @@ -33,7 +33,7 @@ class WindConnectionManager extends WindConnection { * 数据库连接池策略部署配置信息 * @var array */ - private $except = array('_current' => '', '_default' => ''); + private $except = array('_current' => '', '_default' => array(), '_except' => array(), '_db' => array()); /** * 链接池 * @var array @@ -49,7 +49,6 @@ class WindConnectionManager extends WindConnection { * @var string */ private $sqlType; - private $dbNames = array(); /* (non-PHPdoc) * @see WindConnection::getDbHandle() @@ -90,15 +89,23 @@ protected function parseQueryString($sql) { $sql = preg_replace_callback('/^([a-zA-Z]*)\s[\w\*\s]+(\{([\w]+\:)?([\w]+\.)?([\w]+)\})?[\w\s\<\=\:]*/i', array($this, '_pregQueryString'), $sql); if (!$this->except['_current']) { - //TODO 通配符支持 - $_c = isset($this->except[$this->tableName]) ? $this->except[$this->tableName] : $this->except['_default']; + if (!isset($this->except['_db'][$this->tableName])) { + $_c = $this->except['_default']; + foreach ((array) $this->except['_except'] as $value) { + preg_match('/' . str_replace('*', '\w*', $value) . '/i', $this->tableName, $matchs); + if (!empty($matchs)) { + $_c = $this->except['_db'][$value]; + break; + } + } + } else + $_c = $this->except['_db'][$this->tableName]; $this->_resolveCurrentDb($_c); - !$this->except['_current'] && $this->except['_current'] = $this->dbNames[0]; } $_config = $this->getConfig($this->except['_current']); if (!$_config) throw new WindDbException( - '[db.WindConnectionManager.init] db connection ' . $this->except['_current'] . ' is not exist.'); + '[db.WindConnectionManager.parseQueryString] db connection ' . $this->except['_current'] . ' is not exist.'); parent::_initConfig($_config); return parent::parseQueryString($sql); } @@ -110,7 +117,7 @@ private function _resolveCurrentDb($_c) { if ($_c) switch ($this->sqlType) { case 'SELECT': - if (is_array($_c['_s']) && !empty($_c['_s'])) { + if (isset($_c['_s']) && is_array($_c['_s']) && !empty($_c['_s'])) { $_count = count((array) $_c['_s']); if ($_count > 1) $this->except['_current'] = $_c['_s'][rand(0, $_count - 1)]; @@ -140,24 +147,24 @@ private function _pregQueryString($matchs) { if (isset($matchs[2])) { $this->tableName = $matchs[5]; $this->except['_current'] = trim($matchs[3], ':'); - $_return = str_replace($matchs[3] . $matchs[4], '', $matchs[0]); - } else - $_return = $matchs[0]; - return $_return; + $matchs[0] = str_replace($matchs[3] . $matchs[4], '', $matchs[0]); + } + return $matchs[0]; } /* (non-PHPdoc) * @see WindConnection::_initConfig() */ protected function _initConfig() { - if ($_except = $this->getConfig('connections', 'except')) { - preg_replace_callback('/([\w\*\,]+):([\w]+)\|*([\w\,]+)*/i', array($this, '_pregExcept'), $_except); - unset($this->_config['connections']['except']); - } - $this->_config = $this->getConfig('connections'); - $this->dbNames = array_keys($this->_config); - if (empty($this->dbNames)) + $_except = $this->getConfig('connections', 'except'); + unset($this->_config['connections']['except']); + $this->_config = $this->_config['connections']; + $_dbNames = array_keys($this->_config); + if (empty($_dbNames)) throw new WindDbException('[db.WindConnectionManager._initConfig] db config is required.'); + $this->except['_default']['_m'] = $_dbNames[0]; + if ($_except) + preg_replace_callback('/([\w\*\,]+):([\w]+)\|*([\w\,]+)*/i', array($this, '_pregExcept'), $_except); } /** @@ -173,8 +180,10 @@ private function _pregExcept($matchs) { $this->except['_default']['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array(); break; } - $this->except[$_v]['_m'] = $matchs[2]; - $this->except[$_v]['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array(); + if (strpos($_v, '*') !== false) + $this->except['_except'][] = $_v; + $this->except['_db'][$_v]['_m'] = $matchs[2]; + $this->except['_db'][$_v]['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array(); } } } \ No newline at end of file From fc55f101f3aa9eb44edcc3b35034f183fee04420 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 1 Sep 2011 06:31:09 +0000 Subject: [PATCH 0463/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9Adbmanager=E9=80=9A=E9=85=8D=E7=AC=A6=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2535 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/db/WindConnectionManager.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wind/db/WindConnectionManager.php b/wind/db/WindConnectionManager.php index 576fd7c5..049732eb 100644 --- a/wind/db/WindConnectionManager.php +++ b/wind/db/WindConnectionManager.php @@ -29,6 +29,7 @@ * @package */ class WindConnectionManager extends WindConnection { + private $wildcard = '*'; /** * 数据库连接池策略部署配置信息 * @var array @@ -92,7 +93,7 @@ protected function parseQueryString($sql) { if (!isset($this->except['_db'][$this->tableName])) { $_c = $this->except['_default']; foreach ((array) $this->except['_except'] as $value) { - preg_match('/' . str_replace('*', '\w*', $value) . '/i', $this->tableName, $matchs); + preg_match('/' . str_replace($this->wildcard, '\w*', $value) . '/i', $this->tableName, $matchs); if (!empty($matchs)) { $_c = $this->except['_db'][$value]; break; @@ -175,12 +176,12 @@ protected function _initConfig() { private function _pregExcept($matchs) { $_keys = explode(',', $matchs[1]); foreach ($_keys as $_v) { - if ($_v === '*') { + if ($_v === $this->wildcard) { $this->except['_default']['_m'] = $matchs[2]; $this->except['_default']['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array(); break; } - if (strpos($_v, '*') !== false) + if (strpos($_v, $this->wildcard) !== false) $this->except['_except'][] = $_v; $this->except['_db'][$_v]['_m'] = $matchs[2]; $this->except['_db'][$_v]['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array(); From 9fa285fe7932cb6b5e2a0059b7b83e28bf2be90f Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 1 Sep 2011 06:41:32 +0000 Subject: [PATCH 0464/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2536 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/config/components_config.xml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index 1cc3abf3..e792d7b4 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -67,19 +67,14 @@ scope='singleton'> - + + + data.config php 0 - - - - data.view - php - 10 - - From 9062f640ba415c6b02d7bb194c213172327a2905 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 1 Sep 2011 06:42:12 +0000 Subject: [PATCH 0465/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20db=E9=93=BE=E6=8E=A5=E8=8E=B7=E5=8F=96=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2537 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/cache/strategy/WindDbCache.php | 227 ++++++++++++++-------------- 1 file changed, 110 insertions(+), 117 deletions(-) diff --git a/wind/cache/strategy/WindDbCache.php b/wind/cache/strategy/WindDbCache.php index 400ce891..2c4485a8 100644 --- a/wind/cache/strategy/WindDbCache.php +++ b/wind/cache/strategy/WindDbCache.php @@ -1,141 +1,144 @@ - * @author xiaoxiao * @version 2011-7-26 xiaoxiao - */ -class WindDbCache extends AbstractWindCache { - + */ +class WindDbCache extends AbstractWindCache { + /** * 链接句柄 * @var AbstractWindDbAdapter - */ - private $connection; - + */ + protected $connection; + /** * 缓存表 * @var string - */ - private $table = 'pw_cache'; - + */ + private $table = 'pw_cache'; + /** * 缓存表的键字段 * @var string - */ - private $keyField = 'key'; - + */ + private $keyField = 'key'; + /** * 缓存表的值字段 * @var string - */ - private $valueField = 'value'; - + */ + private $valueField = 'value'; + /** * 缓存表过期时间字段 * @var string - */ - private $expireField = 'expire'; - + */ + private $expireField = 'expire'; + /** * 配置文件 * @var string - */ - private $dbConfigName = ''; - - public function __construct(WindConnection $connection = null, $config = array()) { - $connection && $this->setConnection($connection); - $config && $this->setConfig($config); - } - + */ + private $dbConfigName = ''; + + public function __construct(WindConnection $connection = null, $config = array()) { + $connection && $this->setConnection($connection); + $config && $this->setConfig($config); + } + /* * @see AbstractWindCache#setValue() - */ - protected function setValue($key, $value, $expire = 0) { - return $this->store($key, $value, $expire); - } - + */ + protected function setValue($key, $value, $expire = 0) { + return $this->store($key, $value, $expire); + } + /* * @see AbstractWindCache#getValue() - */ - protected function getValue($key) { - $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; - $data = $this->getConnection()->createStatement($sql)->getOne(array($key, time())); - return $data[$this->valueField]; - } - + */ + protected function getValue($key) { + $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; + $data = $this->getConnection()->createStatement($sql)->getOne(array($key, time())); + return $data[$this->valueField]; + } + /* * @see AbstractWindCache#batchFetch() - */ - public function batchGet(array $keys) { - foreach ($keys as $key => $value) { - $keys[$key] = $this->buildSecurityKey($value); - } - list($sql, $result) = array('', array()); - $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys) . ' AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; - $data = $this->getConnection()->createStatement($sql)->queryAll(array(time())); - foreach ($data as $tmp) { - $result[] = $this->formatData(array_search($tmp[$this->keyField], $keys), $tmp[$this->valueField]); - } - return $result; - } - + */ + public function batchGet(array $keys) { + foreach ($keys as $key => $value) { + $keys[$key] = $this->buildSecurityKey($value); + } + list($sql, $result) = array('', array()); + $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray( + $keys) . ' AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; + $data = $this->getConnection()->createStatement($sql)->queryAll(array(time())); + foreach ($data as $tmp) { + $result[] = $this->formatData(array_search($tmp[$this->keyField], $keys), $tmp[$this->valueField]); + } + return $result; + } + /* * @see AbstractWindCache#deleteValue() - */ - protected function deleteValue($key) { - $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` = ? '; - return $this->getConnection()->createStatement($sql)->update(array($key)); - } - + */ + protected function deleteValue($key) { + $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` = ? '; + return $this->getConnection()->createStatement($sql)->update(array($key)); + } + /* * @see AbstractWindCache#batchDelete() - */ - public function batchDelete(array $keys) { - foreach ($keys as $key => $value) { - $keys[$key] = $this->buildSecurityKey($value); - } - $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray($keys); - return $this->getConnection()->execute($sql); - } - + */ + public function batchDelete(array $keys) { + foreach ($keys as $key => $value) { + $keys[$key] = $this->buildSecurityKey($value); + } + $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray( + $keys); + return $this->getConnection()->execute($sql); + } + /* * @see AbstractWindCache#clear() - */ - public function clear() { - return $this->getConnection()->execute('DELETE FROM ' . $this->getTableName()); - } - + */ + public function clear() { + return $this->getConnection()->execute('DELETE FROM ' . $this->getTableName()); + } + /* (non-PHPdoc) * @see WindModule::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->table = $this->getConfig('table-name', '', 'pw_cache', $config); - $this->keyField = $this->getConfig('field-key', '', 'key', $config); - $this->valueField = $this->getConfig('field-value', '', 'value', $config); - $this->expireField = $this->getConfig('field-expire', '', 'expire', $config); - $this->dbConfigName = $this->getConfig('dbconfig-name', '', '', $config); - } - + */ + public function setConfig($config) { + parent::setConfig($config); + $this->table = $this->getConfig('table-name', '', 'pw_cache', $config); + $this->keyField = $this->getConfig('field-key', '', 'key', $config); + $this->valueField = $this->getConfig('field-value', '', 'value', $config); + $this->expireField = $this->getConfig('field-expire', '', 'expire', $config); + $this->dbConfigName = $this->getConfig('dbconfig-name', '', '', $config); + } + /** * 设置链接对象 * @param WindConnection $connection - */ - public function setConnection($connection) { - if ($connection instanceof WindConnection) $this->connection = $connection; - } - + */ + public function setConnection($connection) { + if ($connection instanceof WindConnection) + $this->connection = $connection; + } + /** * 返回表名 * @return string - */ - private function getTableName() { - return $this->table; - } - + */ + private function getTableName() { + return $this->table; + } + /** * 存储数据 * @param string $key @@ -143,29 +146,19 @@ private function getTableName() { * @param int $expires * @param IWindCacheDependency $denpendency * @return boolean - */ - private function store($key, $value, $expires = 0) { - ($expires > 0) ? $expires += time() : $expire=0; - $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires); - $sql = 'REPLACE INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db); - return $this->getConnection()->createStatement($sql)->update(); - } - + */ + private function store($key, $value, $expires = 0) { + ($expires > 0) ? $expires += time() : $expire = 0; + $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires); + $sql = 'REPLACE INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db); + return $this->getConnection()->createStatement($sql)->update(); + } + /** * 获得链接对象 * @return WindConnection - */ - private function getConnection() { - if (null == $this->connection) { - $config = $this->getSystemConfig()->getDbConfig($this->dbConfigName); - $path = $this->getConfig('class', '', 'WIND:db.WindConnection', $config); - $alias = $this->dbConfigName ? $path . $this->dbConfigName : $path . get_class($this); - if (!$this->getSystemFactory()->checkAlias($alias)) { - $definition = array('path' => $path, 'alias' => $alias, 'config' => $config, 'initMethod' => 'init', 'scope' => 'application'); - $this->getSystemFactory()->addClassDefinitions($alias, $definition); - } - $this->connection = $this->getSystemFactory()->getInstance($alias); - } - return $this->connection; - } + */ + private function getConnection() { + return $this->_getConnection(); + } } \ No newline at end of file From a4f6f4c9d01c0fdc12e76cea3665477be7d9a030 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 1 Sep 2011 06:42:42 +0000 Subject: [PATCH 0466/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=BB=B6=E8=BF=9F=E5=8A=A0=E8=BD=BD=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2538 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/base/WindModule.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/base/WindModule.php b/wind/base/WindModule.php index ca04bfd4..06478178 100644 --- a/wind/base/WindModule.php +++ b/wind/base/WindModule.php @@ -61,7 +61,7 @@ public function __call($methodName, $args) { $_propertyName = substr($methodName, 4); $_propertyName = WindUtility::lcfirst($_propertyName); if ($_prefix == '_get') { - if (isset($this->delayAttributes[$_propertyName])) { + if (!$this->$_propertyName && isset($this->delayAttributes[$_propertyName])) { $_property = $this->delayAttributes[$_propertyName]; $_value = null; if (isset($_property['value'])) { @@ -73,7 +73,7 @@ public function __call($methodName, $args) { $_value = $this->getSystemFactory()->createInstance($_className, $args); } $this->$_propertyName = $_value; - unset($this->delayAttributes[$_propertyName]); + //unset($this->delayAttributes[$_propertyName]); } return $this->$_propertyName; } elseif ($_prefix == '_set') { From b8acad8a30b57b2e0a9440c7a3427da1f5d69765 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 2 Sep 2011 02:59:43 +0000 Subject: [PATCH 0467/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9ArootPath=E6=94=AF=E6=8C=81=E5=91=BD=E5=90=8D=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E7=9A=84=E6=96=B9=E5=BC=8F=E8=BF=9B=E8=A1=8C=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2539 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wind/Wind.php b/wind/Wind.php index 4bf1be69..cc15a110 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -40,12 +40,14 @@ public static function application($appName = 'default', $config = array(), $roo $factory = new WindFactory(@include (Wind::getRealPath(self::$_components))); if ($config && !is_array($config)) $config = $factory->getInstance('configParser')->parse($config); + $config = isset($config[$appName]) ? $config[$appName] : $config; $appClass = isset($config['class']) ? $config['class'] : 'windWebApp'; $application = $factory->getInstance($appClass, array($config, $factory)); if (!$application instanceof IWindApplication) throw new WindException('[Wind.application] ' . get_class($application), WindException::ERROR_CLASS_TYPE_ERROR); - $rootPath = $rootPath ? $rootPath : (@$config['root-path'] ? $config['root-path'] : dirname( + $rootPath = $rootPath ? self::getRealPath($rootPath, true) : (isset($config['root-path']) && !empty( + $config['root-path']) ? self::getRealPath($config['root-path'], true) : dirname( $_SERVER['SCRIPT_FILENAME'])); Wind::register($rootPath, $appName, true); self::$_app[$appName] = $application; From e41e97562e7a5b5ab6512507fbefd1612ccfe534 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 2 Sep 2011 03:00:45 +0000 Subject: [PATCH 0468/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2540 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/base/WindHelper.php | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/wind/base/WindHelper.php b/wind/base/WindHelper.php index 29ce8f0f..f0bd9a66 100644 --- a/wind/base/WindHelper.php +++ b/wind/base/WindHelper.php @@ -89,14 +89,14 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { $padLen = strlen($count); foreach ($fileLines as $line => &$fileLine) $fileLine = " " . htmlspecialchars( - str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace( - "\t", " ", rtrim($fileLine)), null, "UTF-8"); + str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace("\t", " ", + rtrim($fileLine)), null, "UTF-8"); } } $msg .= "$file\n" . implode("\n", $fileLines) . "\n" . implode("\n", $trace); } else $_errorPage = '404.htm'; - + if ($status >= 400 && $status <= 505) { $_statusMsg = ucwords(Wind::getApp()->getResponse()->codeMap($status)); $topic = "$status - " . $_statusMsg . "\n"; @@ -106,8 +106,7 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { $msg = "$topic\n$errmessage\n" . $msg . "\n\n" . self::errorInfo(); if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', - true); + Wind::getApp()->getComponent('windLogger')->error($msg, 'wind.error', 'core.error', true); if ($_errhtml) { ob_start(); @@ -118,8 +117,7 @@ protected static function crash($message, $file, $line, $trace, $status = 0) { header('Status: ' . $status . ' ' . $_statusMsg); is_file(Wind::getRealPath($errDir) . '.' . $status . '.htm') && $_errorPage = $status . '.htm'; } - require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, - true); + require Wind::getRealPath(($errDir ? $errDir : self::$errorDir) . '.' . $_errorPage, true); $msg = ob_get_clean(); } $msg = str_replace(Wind::getRootPath(Wind::getAppName()), '~/', $msg); @@ -165,12 +163,11 @@ private static function getCallLine($call) { * @return string */ protected static function getErrorName($errorNumber) { - $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", - E_NOTICE => "E_NOTICE ", E_CORE_ERROR => "E_CORE_ERROR", - E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", - E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", - E_USER_WARNING => "E_USER_WARNING", E_USER_NOTICE => "E_USER_NOTICE", - E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", E_ALL => "E_ALL"); + $errorMap = array(E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", E_PARSE => "E_PARSE", E_NOTICE => "E_NOTICE ", + E_CORE_ERROR => "E_CORE_ERROR", E_CORE_WARNING => "E_CORE_WARNING", E_COMPILE_ERROR => "E_COMPILE_ERROR", + E_COMPILE_WARNING => "E_COMPILE_WARNING", E_USER_ERROR => "E_USER_ERROR", E_USER_WARNING => "E_USER_WARNING", + E_USER_NOTICE => "E_USER_NOTICE", E_STRICT => "E_STRICT", E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", + E_ALL => "E_ALL"); return isset($errorMap[$errorNumber]) ? $errorMap[$errorNumber] : 'E_UNKNOWN'; } @@ -187,17 +184,11 @@ public static function errorInfo() { * @param string $controllerPath * @return array */ - public static function resolveController($controllerPath) { - $_m = $_c = ''; - if (!$controllerPath) - return array($_c, $_m); - if (false !== ($pos = strrpos($controllerPath, '.'))) { - $_m = substr($controllerPath, 0, $pos); - $_c = substr($controllerPath, $pos + 1); - } else { - $_c = $controllerPath; - } - return array($_c, $_m); + public static function resolveAction($action, $args = array()) { + list($action, $_args) = explode('?', $action . '?'); + $action = explode('/', trim($action, '/') . '/'); + end($action); + return array(prev($action), prev($action), prev($action), $args); } } ?> \ No newline at end of file From 0a40e1bbdf07305e88201f05a7b844a627b1a9cf Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 2 Sep 2011 03:01:16 +0000 Subject: [PATCH 0469/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2541 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/filter/WindHandlerInterceptorChain.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/filter/WindHandlerInterceptorChain.php b/wind/filter/WindHandlerInterceptorChain.php index b9c8d718..852ad3d9 100644 --- a/wind/filter/WindHandlerInterceptorChain.php +++ b/wind/filter/WindHandlerInterceptorChain.php @@ -58,7 +58,7 @@ public function getHandler() { } return $this->getHandler(); } - + /** * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 * From 98c12125dceb42fbeca28687caec4f8fca169af8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 2 Sep 2011 03:01:44 +0000 Subject: [PATCH 0470/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2542 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/response/WindHttpResponse.php | 31 +++++++++++-------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/wind/http/response/WindHttpResponse.php b/wind/http/response/WindHttpResponse.php index 75520776..57d9d482 100644 --- a/wind/http/response/WindHttpResponse.php +++ b/wind/http/response/WindHttpResponse.php @@ -26,7 +26,7 @@ class WindHttpResponse implements IWindResponse { private $_status = ''; - private $_data = array('G' => array()); + private $_data = array('G' => array(), 'F' => array()); /* * Server status codes; see RFC 2068. @@ -297,19 +297,16 @@ class WindHttpResponse implements IWindResponse { const W_HTTP_VERSION_NOT_SUPPORTED = 505; public function codeMap($code) { - $map = array(505 => 'http version not supported', 504 => 'gateway timeout', - 503 => 'service unavailable', 503 => 'bad gateway', 502 => 'bad gateway', - 501 => 'not implemented', 500 => 'internal server error', 417 => 'expectation failed', - 416 => 'requested range not satisfiable', 415 => 'unsupported media type', - 414 => 'request uri too long', 413 => 'request entity too large', - 412 => 'precondition failed', 411 => 'length required', 410 => 'gone', 409 => 'conflict', - 408 => 'request timeout', 407 => 'proxy authentication required', - 406 => 'not acceptable', 405 => 'method not allowed', 404 => 'not found', - 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', - 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', - 302 => 'moved temporarily', 302 => 'found', 303 => 'see other', 304 => 'not modified', - 305 => 'use proxy', 307 => 'temporary redirect', 100 => 'continue', - 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', + $map = array(505 => 'http version not supported', 504 => 'gateway timeout', 503 => 'service unavailable', + 503 => 'bad gateway', 502 => 'bad gateway', 501 => 'not implemented', 500 => 'internal server error', + 417 => 'expectation failed', 416 => 'requested range not satisfiable', 415 => 'unsupported media type', + 414 => 'request uri too long', 413 => 'request entity too large', 412 => 'precondition failed', + 411 => 'length required', 410 => 'gone', 409 => 'conflict', 408 => 'request timeout', + 407 => 'proxy authentication required', 406 => 'not acceptable', 405 => 'method not allowed', + 404 => 'not found', 403 => 'forbidden', 402 => 'payment required', 401 => 'unauthorized', + 400 => 'bad request', 300 => 'multiple choices', 301 => 'moved permanently', 302 => 'moved temporarily', + 302 => 'found', 303 => 'see other', 304 => 'not modified', 305 => 'use proxy', 307 => 'temporary redirect', + 100 => 'continue', 101 => 'witching protocols', 200 => 'ok', 201 => 'created', 202 => 'accepted', 203 => 'non authoritative information', 204 => 'no content', 205 => 'reset content', 206 => 'partial content'); return isset($map[$code]) ? $map[$code] : ''; @@ -328,8 +325,7 @@ public function setHeader($name, $value, $replace = false) { $setted = false; foreach ($this->_headers as $key => $one) { if ($one['name'] == $name) { - $this->_headers[$key] = array('name' => $name, 'value' => $value, - 'replace' => $replace); + $this->_headers[$key] = array('name' => $name, 'value' => $value, 'replace' => $replace); $setted = true; break; } @@ -490,8 +486,7 @@ public function getBody($name = false) { public function isSendedHeader($throw = false) { $sended = headers_sent($file, $line); if ($throw && $sended) - throw new WindException( - __CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); + throw new WindException(__CLASS__ . ' the headers are sent in file ' . $file . ' on line ' . $line); return $sended; } From 485978e1b36201adabef38aceb692805e9bb513b Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 2 Sep 2011 03:02:27 +0000 Subject: [PATCH 0471/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2543 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/utility/WindUtility.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/utility/WindUtility.php b/wind/utility/WindUtility.php index c6edf86c..921e7ce1 100644 --- a/wind/utility/WindUtility.php +++ b/wind/utility/WindUtility.php @@ -8,7 +8,7 @@ * @package */ class WindUtility { - + /** * 递归合并两个数组 * From 07168b9165e8277ffa5610f5fa1eb5d6d8b78031 Mon Sep 17 00:00:00 2001 From: yishuo Date: Fri, 2 Sep 2011 03:03:02 +0000 Subject: [PATCH 0472/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2544 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindController.php | 3 +-- wind/web/WindDispatcher.php | 22 +++++++------------- wind/web/WindErrorHandler.php | 4 ++-- wind/web/WindForward.php | 34 +------------------------------ wind/web/WindSimpleController.php | 3 ++- wind/web/WindWebApplication.php | 18 ++++------------ 6 files changed, 17 insertions(+), 67 deletions(-) diff --git a/wind/web/WindController.php b/wind/web/WindController.php index 7e13684a..f4f471ee 100644 --- a/wind/web/WindController.php +++ b/wind/web/WindController.php @@ -18,10 +18,9 @@ protected function resolvedActionMethod($handlerAdapter) { throw new WindException('[web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); $method = new ReflectionMethod($this, $action); - if ($method->isAbstract() || !$method->isPublic()) { + if ($method->isAbstract() || !$method->isPublic()) throw new WindException('[web.WindController.resolvedActionMethod]', WindException::ERROR_CLASS_METHOD_NOT_EXIST); - } return $action; } diff --git a/wind/web/WindDispatcher.php b/wind/web/WindDispatcher.php index d2f2e279..4f79a957 100644 --- a/wind/web/WindDispatcher.php +++ b/wind/web/WindDispatcher.php @@ -78,24 +78,16 @@ protected function dispatchWithAction($forward, $router, $display) { if (!$action = $forward->getAction()) throw new WindException('[web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); - - $args = $forward->getArgs(); $this->display = $display; - list($action, $_args) = explode('?', $action . '?'); - $action = trim($action, '/') . '/'; - $action = explode('/', $action); - end($action); - if ($_tmp = prev($action)) - $router->setAction($_tmp); - if ($_tmp = prev($action)) - $router->setController($_tmp); - if ($_tmp = prev($action)) - $router->setModule($_tmp); + list($_a, $_c, $_m, $args) = WindHelper::resolveAction($action); + if ($_var = $forward->getVars()) + $this->getResponse()->setData($_var, 'F'); + $_a && $router->setAction($_a); + $_c && $router->setController($_c); + $_m && $router->setModule($_m); if ($this->checkToken($router)) - throw new WindFinalException( - '[web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, + throw new WindFinalException('[web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, WindException::ERROR_SYSTEM_ERROR); - Wind::getApp()->processRequest(); } diff --git a/wind/web/WindErrorHandler.php b/wind/web/WindErrorHandler.php index 6461ebfc..8abb563c 100644 --- a/wind/web/WindErrorHandler.php +++ b/wind/web/WindErrorHandler.php @@ -15,8 +15,8 @@ class WindErrorHandler extends WindController { * @see WindAction::beforeAction() */ public function beforeAction($handlerAdapter) { - $this->error = $this->getInput('error'); - $this->errorCode = (int) $this->getInput('errorCode'); + $this->error = $this->_vars['error']; + $this->errorCode = (int) $this->_vars['errorCode']; if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else diff --git a/wind/web/WindForward.php b/wind/web/WindForward.php index 4ad03521..5e919695 100644 --- a/wind/web/WindForward.php +++ b/wind/web/WindForward.php @@ -33,25 +33,7 @@ class WindForward extends WindModule { */ private $url; private $action; - private $controller; - private $args; - - /** - * 将请求重定向到另外一个Action操作 - * @param string $action | $action 操作 - * @param string $controller | controller 路径 , controller 为空是则指向当前的控制器 - * @param array $args | 参数 - * @param boolean $isRedirect | 是否重定向 - * - * @return - */ - public function forwardAnotherAction($action = 'run', $controller = '', $args = array(), $isRedirect = false) { - $this->setIsReAction(true); - $this->setAction($action); - $this->setController($controller); - $this->setArgs($args); - $this->setIsRedirect($isRedirect); - } + private $args = array(); /** * 将请求重定向到另外一个Action操作 @@ -149,13 +131,6 @@ public function getAction() { return $this->action; } - /** - * @return the $controller - */ - public function getController() { - return $this->controller; - } - /** * @return the $args */ @@ -170,13 +145,6 @@ public function setAction($action) { $this->action = $action; } - /** - * @param field_type $controller - */ - public function setController($controller) { - $this->controller = $controller; - } - /** * @param field_type $args */ diff --git a/wind/web/WindSimpleController.php b/wind/web/WindSimpleController.php index c73ab5af..18d71dba 100644 --- a/wind/web/WindSimpleController.php +++ b/wind/web/WindSimpleController.php @@ -26,8 +26,9 @@ abstract public function run(); * @see IWindController::doAction() */ public function doAction($handlerAdapter) { + $this->_vars = $this->getResponse()->getData('F'); if ($this->forward !== null) - $this->_vars = $this->forward->getVars(); + $this->_vars += $this->forward->getVars(); $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 5b11f0c0..f20f63cf 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -84,7 +84,7 @@ public function processRequest() { 404); $module = WindUtility::mergeArray($this->getModules('default'), $module); $this->setModules($this->handlerAdapter->getModule(), $module, true); - $handlerPath = @$module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . @$module['controller-suffix']; + $handlerPath = $module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . $module['controller-suffix']; if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( '[web.WindWebApplication.processRequest] \r\n\taction handl:' . $handlerPath, 'wind.core'); @@ -95,7 +95,6 @@ public function processRequest() { 'properties' => array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward'), 'urlHelper' => array('ref' => 'urlHelper')))); $handler = $this->windFactory->getInstance($handlerPath); - if (!$handler) throw new WindActionException( '[web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', @@ -135,10 +134,11 @@ protected function sendErrorMessage($exception) { $this->setModules('error', array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); } + /* @var $forward WindForward */ $forward = $this->getSystemFactory()->getInstance('forward'); $forward->forwardAction($_errorAction); - $this->getRequest()->setAttribute($errorMessage->getError(), 'error'); - $this->getRequest()->setAttribute($exception->getCode(), 'errorCode'); + $forward->setVars($errorMessage->getError(), 'error'); + $forward->setVars($exception->getCode(), 'errorCode'); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); } @@ -177,16 +177,6 @@ public function getModules($name = '') { return $this->getConfig('modules', $name, array()); } - /* (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - if (!$config) - return; - $config = @$config[Wind::getAppName()] ? $config[Wind::getAppName()] : $config; - $this->_config = $config; - } - /** * @param object $componentInstance * @param string $componentName From 136700a8c2a1e3b1e8f5f2b7d6b0490b30cb8a74 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 04:16:59 +0000 Subject: [PATCH 0473/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9AcreateUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2545 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindUrlHelper.php | 83 +++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 9 deletions(-) diff --git a/wind/web/WindUrlHelper.php b/wind/web/WindUrlHelper.php index a9bfa467..136aa9aa 100644 --- a/wind/web/WindUrlHelper.php +++ b/wind/web/WindUrlHelper.php @@ -5,21 +5,86 @@ * @version $Id$ * @package */ -class WindUrlHelper extends WindModule { - +class WindUrlHelper { + private static $_sep = '_array_'; + + /** + * @param string $url + * @return string + */ + public static function checkUrl($url) { + return $url; + } + + /** + * @param unknown_type $args + */ + public static function urlToArgs($url, $decode = true) { + if (!$url) + return array(); + if (false !== ($pos = strpos($url, '?'))) + $url = substr($url, $pos + 1); + $url = explode('&', $url); + $args = array(); + foreach ($url as $value) { + list($_k, $_v) = explode('=', $value . '='); + if ($_k) { + $decode && $_v = urldecode($_v); + if (strpos($_k, self::$_sep) === 0) { + $_k = substr($_k, strlen(self::$_sep)); + $_v = unserialize($_v); + } + $args[$_k] = $_v; + } + } + return $args; + } + + /** + * 将数组格式的参数列表转换为Url格式,并将url进行编码处理 + * @param array $args + * @return string + */ + public static function argsToUrl($args) { + $_tmp = ''; + foreach ((array) $args as $key => $value) { + if (is_array($value)) { + $_tmp .= self::$_sep . "$key=" . urlencode(serialize($value)) . "&"; + continue; + } + $_tmp .= "$key=" . urlencode($value) . "&"; + } + return $_tmp; + } + + /** + * 解析ControllerPath + * /module/controller/action/?a=a&b=b&c=c& + * 返回解析后的controller信息,controller,module,app + * + * @param string $controllerPath + * @return array + */ + public static function resolveAction($action, $args = array()) { + list($action, $_args) = explode('?', $action . '?'); + $args = array_merge($args, self::urlToArgs($_args, false)); + $action = explode('/', trim($action, '/') . '/'); + end($action); + return array(prev($action), prev($action), prev($action), self::argsToUrl($args)); + } + /** * 构造返回Url地址 - * * 将根据是否开启url重写来分别构造相对应的url - * * @param string $action 执行的操作 - * @param string $controller 执行的controller - * @param array $params 附带的参数 + * @param array $args 附带的参数 + * @param AbstractWindRoute $route * @return string */ - public function createUrl($action, $controller = '', $params = array()) { - $router = $this->getSystemFactory()->getInstance(COMPONENT_ROUTER); - return $router->buildUrl($action, $controller, $params); + public static function createUrl($action, $args = array(), $route = null) { + /* @var $router AbstractWindRouter */ + $router = Wind::getApp()->getComponent('router'); + return $router->assemble($action, $args, $route); } } ?> \ No newline at end of file From eaa4f76fa3fcac8430f24ff3cbf10aeaf7901424 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 04:17:09 +0000 Subject: [PATCH 0474/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9AcreateUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2546 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/base/WindHelper.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/wind/base/WindHelper.php b/wind/base/WindHelper.php index f0bd9a66..a6c7b9df 100644 --- a/wind/base/WindHelper.php +++ b/wind/base/WindHelper.php @@ -177,18 +177,5 @@ public static function errorInfo() { return $info; } - /** - * 解析ControllerPath - * 返回解析后的controller信息,controller,module,app - * - * @param string $controllerPath - * @return array - */ - public static function resolveAction($action, $args = array()) { - list($action, $_args) = explode('?', $action . '?'); - $action = explode('/', trim($action, '/') . '/'); - end($action); - return array(prev($action), prev($action), prev($action), $args); - } } ?> \ No newline at end of file From 62ac253c32e829af35282b0d3cd0d1b7c954c465 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 04:17:33 +0000 Subject: [PATCH 0475/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9AcreateUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2547 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/AbstractWindRouter.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php index 536b8458..ecd8aab2 100644 --- a/wind/router/AbstractWindRouter.php +++ b/wind/router/AbstractWindRouter.php @@ -16,7 +16,9 @@ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $module; protected $controller = 'index'; protected $action = 'run'; - + /** + * @var AbstractWindRoute + */ protected $currentRoute = null; /** @@ -29,7 +31,7 @@ abstract public function route(); * 创建Url,并返回 * @return string */ - abstract public function assemble(); + abstract public function assemble($action, $args = array(), $route = null); /* (non-PHPdoc) * @see WindModule::setConfig() @@ -48,7 +50,6 @@ public function setConfig($config) { /** * 设置路由变量信息 - * * @param string $params */ protected function setParams($params) { @@ -59,9 +60,8 @@ protected function setParams($params) { $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); - else { + else $this->getRequest()->setAttribute($value, $key); - } } } From 6c4f54b3244a374768bbaf25c54a71cae65abf24 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 04:17:42 +0000 Subject: [PATCH 0476/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9AcreateUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2548 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/WindRouter.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index 89e519a7..928e9848 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -20,8 +20,16 @@ public function route() { /* (non-PHPdoc) * @see AbstractWindRouter::assemble() */ - public function assemble() { - // TODO Auto-generated method stub + public function assemble($action, $args = array(), $route = null) { + if ($route !== null) + return $route->build($action, $args); + if ($this->currentRoute !== null) + return $this->currentRoute->build($action, $args); + list($_a, $_c, $_m, $args) = WindUrlHelper::resolveAction($action, $args); + $_baseUrl = $this->getRequest()->getBaseUrl(true) . '/' . $this->getRequest()->getScript(); + $_url = sprintf($_baseUrl . "?$this->moduleKey=%s&$this->controllerKey=%s&$this->actionKey=%s&%s", + ($_m ? $_m : $this->module), ($_c ? $_c : $this->controller), ($_a ? $_a : $this->action), $args); + return WindUrlHelper::checkUrl($_url); } /** @@ -29,8 +37,7 @@ public function assemble() { */ public function defaultRoute() { $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); - $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, - $this->controller); + $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); return $params; } From 15603cf36bc282f006d93009b4cc8c542f02e327 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 04:18:07 +0000 Subject: [PATCH 0477/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9AcreateUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2549 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindDispatcher.php | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/wind/web/WindDispatcher.php b/wind/web/WindDispatcher.php index 4f79a957..d316d19a 100644 --- a/wind/web/WindDispatcher.php +++ b/wind/web/WindDispatcher.php @@ -48,21 +48,12 @@ public function dispatch($forward, $router, $display) { /** * 请求分发一个重定向请求 * @param WindForward $forward - * @param WindUrlBasedRouter $router + * @param AbstractWindRouter $router * @return */ protected function dispatchWithRedirect($forward, $router) { - $_url = $forward->getUrl(); - if (!$_url && $forward->getIsReAction()) { - $_url = $this->_getUrlHelper()->createUrl($forward->getAction(), $forward->getController(), - $forward->getArgs()); - if ($this->checkToken($router)) - throw new WindFinalException( - '[web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, - WindException::ERROR_SYSTEM_ERROR); - - } else - $_url = $this->_getUrlHelper()->checkUrl($_url); + if (!($_url = $forward->getUrl())) + $_url = $router->assemble($forward->getAction(), $forward->getArgs()); $this->getResponse()->sendRedirect($_url); } @@ -79,7 +70,7 @@ protected function dispatchWithAction($forward, $router, $display) { throw new WindException('[web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $this->display = $display; - list($_a, $_c, $_m, $args) = WindHelper::resolveAction($action); + list($_a, $_c, $_m) = WindUrlHelper::resolveAction($action); if ($_var = $forward->getVars()) $this->getResponse()->setData($_var, 'F'); $_a && $router->setAction($_a); From 94f0695e0032741c1f468f24d15f68d0a4ed7803 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 04:22:48 +0000 Subject: [PATCH 0478/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9AcreateUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2550 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/AbstractWindRouter.php | 1 + 1 file changed, 1 insertion(+) diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php index ecd8aab2..fd7affab 100644 --- a/wind/router/AbstractWindRouter.php +++ b/wind/router/AbstractWindRouter.php @@ -16,6 +16,7 @@ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $module; protected $controller = 'index'; protected $action = 'run'; + protected $reverse = "%s?m=%s&c=%s&a=%s&"; /** * @var AbstractWindRoute */ From 322b81daf9feeb4fc183efdafae3a2daafda8f7e Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 04:22:57 +0000 Subject: [PATCH 0479/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9AcreateUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2551 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/WindRouter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index 928e9848..d1167a52 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -27,9 +27,9 @@ public function assemble($action, $args = array(), $route = null) { return $this->currentRoute->build($action, $args); list($_a, $_c, $_m, $args) = WindUrlHelper::resolveAction($action, $args); $_baseUrl = $this->getRequest()->getBaseUrl(true) . '/' . $this->getRequest()->getScript(); - $_url = sprintf($_baseUrl . "?$this->moduleKey=%s&$this->controllerKey=%s&$this->actionKey=%s&%s", - ($_m ? $_m : $this->module), ($_c ? $_c : $this->controller), ($_a ? $_a : $this->action), $args); - return WindUrlHelper::checkUrl($_url); + $_url = sprintf($this->reverse, $_baseUrl, ($_m ? $_m : $this->module), ($_c ? $_c : $this->controller), + ($_a ? $_a : $this->action)); + return WindUrlHelper::checkUrl($_url . $args); } /** From a947997051115333e493c02ae9d044ae0a3ec10c Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:02:57 +0000 Subject: [PATCH 0480/1065] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=9AcreateUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2552 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/WindRouter.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index d1167a52..119f7039 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -36,12 +36,9 @@ public function assemble($action, $args = array(), $route = null) { * 默认路由规则 */ public function defaultRoute() { - $params[$this->actionKey] = $this->getRequest()->getRequest($this->actionKey, $this->action); - $params[$this->controllerKey] = $this->getRequest()->getRequest($this->controllerKey, $this->controller); - $params[$this->moduleKey] = $this->getRequest()->getRequest($this->moduleKey, $this->module); - return $params; + $_pathInfo = $this->getRequest()->getPathInfo(); + return $_pathInfo ? WindUrlHelper::urlToArgs($_pathInfo) : array(); } - } ?> \ No newline at end of file From c4d0556edd61a6336e830bc33eca3bf0bca038d2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:03:17 +0000 Subject: [PATCH 0481/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20=E5=A4=9A=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2553 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/response/WindHttpResponse.php | 37 +++++++++++-------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/wind/http/response/WindHttpResponse.php b/wind/http/response/WindHttpResponse.php index 57d9d482..56862ac9 100644 --- a/wind/http/response/WindHttpResponse.php +++ b/wind/http/response/WindHttpResponse.php @@ -530,33 +530,28 @@ private function _normalizeHeader($name) { /** * @return array */ - public function getData($key1 = '', $key2 = '') { - if (!$key1) - return $this->_data; - if (!$key2) - return isset($this->_data[$key1]) ? $this->_data[$key1] : ''; - return isset($this->_data[$key1]) ? (isset($this->_data[$key1][$key2]) ? $this->_data[$key1][$key2] : '') : ''; + public function getData() { + $_tmp = $this->_data; + foreach (func_get_args() as $arg) { + if (is_array($_tmp) && isset($_tmp[$arg])) + $_tmp = $_tmp[$arg]; + else + return ''; + } + return $_tmp; } /** * @param $data */ - public function setData($data, $key = '', $isG = false) { - if ($key) { - if ($isG) - $this->_data['G'][$key] = $data; - else - $this->_data[$key] = $data; - return; - } - if (is_object($data)) - $data = get_object_vars($data); - if (is_array($data)) { - if ($isG) - $this->_data['G'] += $data; - else + public function setData($data, $key = '') { + if ($key) + $this->_data[$key] = $data; + else { + if (is_object($data)) + $data = get_object_vars($data); + if (is_array($data)) $this->_data += $data; - } } From fce0832d7351a7cee33d6474af59e8e072425f94 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:03:29 +0000 Subject: [PATCH 0482/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20=E5=A4=9A=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2554 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/compiler/WindTemplateCompilerEcho.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wind/viewer/compiler/WindTemplateCompilerEcho.php b/wind/viewer/compiler/WindTemplateCompilerEcho.php index fa967734..d956a640 100644 --- a/wind/viewer/compiler/WindTemplateCompilerEcho.php +++ b/wind/viewer/compiler/WindTemplateCompilerEcho.php @@ -23,7 +23,12 @@ public function compile($key, $content) { list($_output, $type) = explode('|', $_output . '|'); if (strpos($_output, '::') === false && strpos($_output, ':') !== false) { list($_namespace, $_var) = explode(':', $_output); - $_output = 'Wind::getApp()->getResponse()->getData(\'' . $_namespace . '\', \'' . $_var . '\')'; + $_args = explode(',', $_var . ','); + $_output = 'Wind::getApp()->getResponse()->getData(\'' . $_namespace . '\''; + foreach ($_args as $_arg) { + $_arg && $_output .= ',\'' . $_arg . '\''; + } + $_output .= ')'; } if (!strcasecmp($type, 'html')) return ''; From df0f5cefea5123111da9692658cd7a12a5f98254 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:03:48 +0000 Subject: [PATCH 0483/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20=E5=A4=9A=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2555 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindDispatcher.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wind/web/WindDispatcher.php b/wind/web/WindDispatcher.php index d316d19a..9e5e00b1 100644 --- a/wind/web/WindDispatcher.php +++ b/wind/web/WindDispatcher.php @@ -36,9 +36,7 @@ public function dispatch($forward, $router, $display) { else { $view = $forward->getWindView(); if ($view->templateName) { - $vars = $forward->getVars(); - Wind::getApp()->getResponse()->setData($vars, $view->templateName); - Wind::getApp()->getResponse()->setData($vars['G'], '', true); + Wind::getApp()->getResponse()->setData($forward->getVars(), $view->templateName); $view->render($this->display); } $this->display = false; From 5c2e5c35f158e48ec00c64c1e654ed851e0328af Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:04:28 +0000 Subject: [PATCH 0484/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20=E5=A4=9A=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2556 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindSimpleController.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wind/web/WindSimpleController.php b/wind/web/WindSimpleController.php index 18d71dba..fb385f78 100644 --- a/wind/web/WindSimpleController.php +++ b/wind/web/WindSimpleController.php @@ -7,7 +7,6 @@ * @package */ abstract class WindSimpleController extends WindModule implements IWindController { - protected $_vars = array(); /** * @var WindForward */ @@ -26,9 +25,10 @@ abstract public function run(); * @see IWindController::doAction() */ public function doAction($handlerAdapter) { - $this->_vars = $this->getResponse()->getData('F'); - if ($this->forward !== null) - $this->_vars += $this->forward->getVars(); + $_vars = $this->getResponse()->getData('F'); + if ($_vars) + $this->getForward()->setVars($_vars); + $this->beforeAction($handlerAdapter); $this->setDefaultTemplateName($handlerAdapter); $method = $this->resolvedActionMethod($handlerAdapter); @@ -43,10 +43,10 @@ public function doAction($handlerAdapter) { * @see IWindController::resolveActionFilter($action) */ protected function resolveActionFilter($__filters) { - @extract(@$this->getRequest()->getRequest(), EXTR_REFS); $chain = WindFactory::createInstance('WindHandlerInterceptorChain'); foreach ((array) $__filters as $__filter) { if (isset($__filter['expression']) && !empty($__filter['expression'])) { + if (!@eval('return ' . $__filter['expression'] . ';')) continue; /*list($p, $v) = explode('=', $__filter['expression'] . '='); @@ -111,7 +111,7 @@ protected function setOutput($data, $key = '') { * @return */ protected function setGlobal($data, $key = '') { - $this->getForward()->setVars($data, $key, true); + Wind::getApp()->setGlobal($data, $key); } /** From 35fc6ff8d800891063f515f809a92bc769594dda Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:04:43 +0000 Subject: [PATCH 0485/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20=E5=A4=9A=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2557 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindUrlHelper.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/wind/web/WindUrlHelper.php b/wind/web/WindUrlHelper.php index 136aa9aa..75a39bdc 100644 --- a/wind/web/WindUrlHelper.php +++ b/wind/web/WindUrlHelper.php @@ -20,11 +20,9 @@ public static function checkUrl($url) { * @param unknown_type $args */ public static function urlToArgs($url, $decode = true) { - if (!$url) - return array(); if (false !== ($pos = strpos($url, '?'))) $url = substr($url, $pos + 1); - $url = explode('&', $url); + $url = explode('&', $url . '&'); $args = array(); foreach ($url as $value) { list($_k, $_v) = explode('=', $value . '='); @@ -67,7 +65,7 @@ public static function argsToUrl($args) { */ public static function resolveAction($action, $args = array()) { list($action, $_args) = explode('?', $action . '?'); - $args = array_merge($args, self::urlToArgs($_args, false)); + $args = array_merge($args, ($_args ? self::urlToArgs($_args, false) : array())); $action = explode('/', trim($action, '/') . '/'); end($action); return array(prev($action), prev($action), prev($action), self::argsToUrl($args)); From 330ead48b1d2e16ec30020f9ddd9d7363d86969c Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:04:55 +0000 Subject: [PATCH 0486/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20=E5=A4=9A=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2558 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindForward.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/wind/web/WindForward.php b/wind/web/WindForward.php index 5e919695..e3b56e89 100644 --- a/wind/web/WindForward.php +++ b/wind/web/WindForward.php @@ -16,7 +16,7 @@ class WindForward extends WindModule { * 模板变量信息 * @var array */ - private $vars = array('G' => array()); + private $vars = array(); /** * 是否为Action请求 * @var boolean @@ -58,21 +58,14 @@ public function forwardAction($action, $args = array(), $isRedirect = false) { * @param string|array|object $vars * @param string $key */ - public function setVars($vars, $key = '', $isG = false) { + public function setVars($vars, $key = '') { if (!$key) { if (is_object($vars)) $vars = get_object_vars($vars); if (is_array($vars)) - if ($isG) - $this->vars['G'] = $vars; - else - $this->vars += $vars; - } else { - if ($isG) - $this->vars['G'][$key] = $vars; - else - $this->vars[$key] = $vars; - } + $this->vars += $vars; + } else + $this->vars[$key] = $vars; } /** @@ -107,7 +100,14 @@ public function setIsReAction($isReAction) { * @return the $vars */ public function getVars() { - return $this->vars; + $_tmp = $this->vars; + foreach (func_get_args() as $arg) { + if (is_array($_tmp) && isset($_tmp[$arg])) + $_tmp = $_tmp[$arg]; + else + return ''; + } + return $_tmp; } /** From ab5affb76497737744f6c82864e6caebe0a1b94b Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:05:14 +0000 Subject: [PATCH 0487/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20=E5=A4=9A=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2559 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindErrorHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/web/WindErrorHandler.php b/wind/web/WindErrorHandler.php index 8abb563c..930fcd98 100644 --- a/wind/web/WindErrorHandler.php +++ b/wind/web/WindErrorHandler.php @@ -15,8 +15,8 @@ class WindErrorHandler extends WindController { * @see WindAction::beforeAction() */ public function beforeAction($handlerAdapter) { - $this->error = $this->_vars['error']; - $this->errorCode = (int) $this->_vars['errorCode']; + $this->error = $this->getForward()->getVars('error'); + $this->errorCode = (int) $this->getForward()->getVars('errorCode'); if ($this->request->getUrlReferer()) $this->urlReferer = $this->getRequest()->getUrlReferer(); else From cfd77ee8e6d194917acdfe367eedb907b2904b6f Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:05:47 +0000 Subject: [PATCH 0488/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0=E5=AD=98=E5=82=A8global=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2560 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 82 ++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index f20f63cf..af06333f 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -108,38 +108,23 @@ public function processRequest() { } /** - * 异常处理请求 - * @param WindActionException actionException - * @return + * 设置全局变量 + * @param array|object|string $data + * @param string $key + * @return + */ + public function setGlobal($data, $key = '') { + $data = $key ? array($key => $data) : $data; + $this->response->setData($data, 'G'); + } + + /** + * 获取全局变量 + * @return string|object|array */ - protected function sendErrorMessage($exception) { - $moduleName = $this->handlerAdapter->getModule(); - if ($moduleName === 'error') - throw new WindFinalException($exception->getMessage()); - - $errorMessage = null; - if ($exception instanceof WindActionException) - $errorMessage = $exception->getError(); - if (!$errorMessage) { - $errorMessage = $this->windFactory->getInstance('errorMessage'); - $errorMessage->addError($exception->getMessage()); - } - if (!$_errorAction = $errorMessage->getErrorAction()) { - $module = $this->getModules($moduleName); - if (empty($module)) - $module = $this->getModules('default'); - preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); - $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0]) + 1))); - $_errorAction = 'error/' . @$matchs[0] . '/run/'; - $this->setModules('error', - array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); - } - /* @var $forward WindForward */ - $forward = $this->getSystemFactory()->getInstance('forward'); - $forward->forwardAction($_errorAction); - $forward->setVars($errorMessage->getError(), 'error'); - $forward->setVars($exception->getCode(), 'errorCode'); - $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); + public function getGlobal() { + $args = array('G') + func_get_args(); + return call_user_func_array(array($this->response, 'getData'), $args); } /** @@ -223,4 +208,39 @@ public function getResponse() { public function getWindFactory() { return $this->windFactory; } + + /** + * 异常处理请求 + * @param WindActionException actionException + * @return + */ + protected function sendErrorMessage($exception) { + $moduleName = $this->handlerAdapter->getModule(); + if ($moduleName === 'error') + throw new WindFinalException($exception->getMessage()); + + $errorMessage = null; + if ($exception instanceof WindActionException) + $errorMessage = $exception->getError(); + if (!$errorMessage) { + $errorMessage = $this->windFactory->getInstance('errorMessage'); + $errorMessage->addError($exception->getMessage()); + } + if (!$_errorAction = $errorMessage->getErrorAction()) { + $module = $this->getModules($moduleName); + if (empty($module)) + $module = $this->getModules('default'); + preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs); + $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0]) + 1))); + $_errorAction = 'error/' . @$matchs[0] . '/run/'; + $this->setModules('error', + array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => '')); + } + /* @var $forward WindForward */ + $forward = $this->getSystemFactory()->getInstance('forward'); + $forward->forwardAction($_errorAction); + $forward->setVars($errorMessage->getError(), 'error'); + $forward->setVars($exception->getCode(), 'errorCode'); + $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); + } } \ No newline at end of file From cfa8619660828094188eca773aa70443cc881639 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 08:07:12 +0000 Subject: [PATCH 0489/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20=E5=A4=9A=E5=8F=82=E6=95=B0=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2561 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/filter/WindActionFilter.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wind/filter/WindActionFilter.php b/wind/filter/WindActionFilter.php index adbad79e..4c289fcc 100644 --- a/wind/filter/WindActionFilter.php +++ b/wind/filter/WindActionFilter.php @@ -6,7 +6,6 @@ * @package */ abstract class WindActionFilter extends WindHandlerInterceptor { - protected $_vars = array(); /** * @var WindForward */ @@ -27,7 +26,6 @@ public function __construct($forward, $errorMessage) { unset($args[0], $args[1]); foreach ($args as $key => $value) property_exists(get_class($this), $key) && $this->$key = $value; - $this->_vars = $forward->getVars(); } /** @@ -47,7 +45,7 @@ protected function setOutput($data, $key = '') { * @return */ protected function setGlobal($data, $key = '') { - $this->forward->setVars($data, $key, true); + Wind::getApp()->setGlobal($data, $key); } /** From 861124856ab07a0d2bf08fd0eae604f3a59daf47 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 09:15:31 +0000 Subject: [PATCH 0490/1065] bug fixted: rootPath git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2562 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index cc15a110..aea65aaa 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -46,11 +46,10 @@ public static function application($appName = 'default', $config = array(), $roo if (!$application instanceof IWindApplication) throw new WindException('[Wind.application] ' . get_class($application), WindException::ERROR_CLASS_TYPE_ERROR); - $rootPath = $rootPath ? self::getRealPath($rootPath, true) : (isset($config['root-path']) && !empty( - $config['root-path']) ? self::getRealPath($config['root-path'], true) : dirname( - $_SERVER['SCRIPT_FILENAME'])); + $rootPath = $rootPath ? self::getRealPath($rootPath, false) : (!empty($config['root-path']) ? self::getRealPath( + $config['root-path'], false) : dirname($_SERVER['SCRIPT_FILENAME'])); Wind::register($rootPath, $appName, true); - self::$_app[$appName] = $application; + self::$_app[$appName] = $application; } return self::$_app[$appName]; } @@ -223,6 +222,8 @@ public static function setImports($imports) { * @return string|array('isPackage','fileName','extension','realPath') */ public static function getRealPath($filePath, $suffix = '', $absolut = false) { + if (false !== strpos($filePath, DIRECTORY_SEPARATOR)) + return realpath($filePath); if (false !== ($pos = strpos($filePath, ':'))) { $namespace = self::getRootPath(substr($filePath, 0, $pos)); $filePath = substr($filePath, $pos + 1); @@ -230,11 +231,9 @@ public static function getRealPath($filePath, $suffix = '', $absolut = false) { $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; if ($suffix === '') { $suffix = self::$_extensions; - } elseif ($suffix === true) { - if ($pos = strrpos($filePath, '.')) { - $suffix = substr($filePath, $pos + 1); - $filePath = substr($filePath, 0, $pos); - } + } elseif ($suffix === true && false !== ($pos = strrpos($filePath, '.'))) { + $suffix = substr($filePath, $pos + 1); + $filePath = substr($filePath, 0, $pos); } $filePath = str_replace('.', '/', $filePath); $namespace && $filePath = $namespace . $filePath; @@ -253,7 +252,7 @@ public static function getRealDir($dirPath, $absolut = false) { $dirPath = substr($dirPath, $pos + 1); } else $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; - $namespace && $dirPath = $namespace . '/' . str_replace('.', '/', $dirPath); + $namespace && $dirPath = $namespace . str_replace('.', '/', $dirPath); return $dirPath; } From d94b47c74ca9bbe9dae98db48a76974de670745c Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 10:29:37 +0000 Subject: [PATCH 0491/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=9A=20db=E9=93=BE=E6=8E=A5=E8=8E=B7=E5=8F=96=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2563 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/db/WindConnectionManager.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/wind/db/WindConnectionManager.php b/wind/db/WindConnectionManager.php index 049732eb..43e457df 100644 --- a/wind/db/WindConnectionManager.php +++ b/wind/db/WindConnectionManager.php @@ -50,6 +50,16 @@ class WindConnectionManager extends WindConnection { * @var string */ private $sqlType; + + private $forceMaster = false; + + /* (non-PHPdoc) + * @see WindConnection::createStatement() + */ + public function createStatement($sql = null, $forceMaster = false) { + $this->forceMaster = $forceMaster; + return parent::createStatement($sql); + } /* (non-PHPdoc) * @see WindConnection::getDbHandle() @@ -118,8 +128,8 @@ private function _resolveCurrentDb($_c) { if ($_c) switch ($this->sqlType) { case 'SELECT': - if (isset($_c['_s']) && is_array($_c['_s']) && !empty($_c['_s'])) { - $_count = count((array) $_c['_s']); + if (!$this->forceMaster && !empty($_c['_s'])) { + $_count = count($_c['_s']); if ($_count > 1) $this->except['_current'] = $_c['_s'][rand(0, $_count - 1)]; else From 9cb0c411d96a57f8568638252b8296d9f5b9efa6 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 5 Sep 2011 11:05:16 +0000 Subject: [PATCH 0492/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2564 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index aea65aaa..5e6d1598 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -49,7 +49,7 @@ public static function application($appName = 'default', $config = array(), $roo $rootPath = $rootPath ? self::getRealPath($rootPath, false) : (!empty($config['root-path']) ? self::getRealPath( $config['root-path'], false) : dirname($_SERVER['SCRIPT_FILENAME'])); Wind::register($rootPath, $appName, true); - self::$_app[$appName] = $application; + self::$_app[$appName] = $application; } return self::$_app[$appName]; } @@ -118,7 +118,7 @@ public static function import($filePath, $recursivePackage = false) { $isPackage = $fileName === '*'; if ($isPackage) { $filePath = substr($filePath, 0, $pos); - $dirPath = self::getRealDir($filePath); + $dirPath = self::getRealPath($filePath, false); if (!$dh = opendir($dirPath)) throw new Exception('the file ' . $dirPath . ' open failed!'); while (($file = readdir($dh)) !== false) { From fb3a43668c851b298c7af5b7e34618f9e53b5459 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 03:11:33 +0000 Subject: [PATCH 0493/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2565 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/WindUrlRewriteRouter.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wind/router/WindUrlRewriteRouter.php b/wind/router/WindUrlRewriteRouter.php index 00813caa..9b5c215f 100644 --- a/wind/router/WindUrlRewriteRouter.php +++ b/wind/router/WindUrlRewriteRouter.php @@ -337,10 +337,8 @@ public function route() { /* (non-PHPdoc) * @see AbstractWindRouter::assemble() */ - public function assemble() { + public function assemble($action, $args = array(), $route = null) { // TODO Auto-generated method stub - - } } From e8b033062222c6cb05994364d5c77335475ca087 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 03:58:36 +0000 Subject: [PATCH 0494/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2566 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/wind/components_config.php b/wind/components_config.php index cb7f980d..2d1e6af5 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -1,5 +1,5 @@ array( + 'windApplication' => array( 'path' => 'WIND:web.WindWebApplication', 'scope' => 'singleton', 'properties' => array( @@ -97,18 +97,11 @@ ), 'windCache' => array( 'path' => 'WIND:cache.strategy.WindFileCache', + 'scope' => 'singleton', 'config' => array( 'dir' => 'data.config', 'suffix' => 'php', 'expires' => '0', ), ), - 'viewCache' => array( - 'path' => 'WIND:cache.strategy.WindFileCache', - 'config' => array( - 'dir' => 'data.view', - 'suffix' => 'php', - 'expires' => '10', - ), - ), ); \ No newline at end of file From 94e4548cfe8b3db187a11f6a93a25f944f3e6644 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 03:58:51 +0000 Subject: [PATCH 0495/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2567 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 5e6d1598..cad6dd3c 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -38,16 +38,19 @@ public static function application($appName = 'default', $config = array(), $roo self::beforRun($appName, $config, $rootPath); if (!isset(self::$_app[$appName])) { $factory = new WindFactory(@include (Wind::getRealPath(self::$_components))); - if ($config && !is_array($config)) - $config = $factory->getInstance('configParser')->parse($config); - $config = isset($config[$appName]) ? $config[$appName] : $config; - $appClass = isset($config['class']) ? $config['class'] : 'windWebApp'; - $application = $factory->getInstance($appClass, array($config, $factory)); + if ($config) { + is_string($config) && $config = $factory->getInstance('configParser')->parse($config); + $_default = isset($config['default']) ? $config['default'] : array(); + $config = isset($config[$appName]) ? $config[$appName] : $config; + $_default && $config = WindUtility::mergeArray($_default, $config); + isset($config['components']) && $factory->loadClassDefinitions($config['components']); + } + $application = $factory->getInstance('windApplication', array($config, $factory)); if (!$application instanceof IWindApplication) throw new WindException('[Wind.application] ' . get_class($application), WindException::ERROR_CLASS_TYPE_ERROR); - $rootPath = $rootPath ? self::getRealPath($rootPath, false) : (!empty($config['root-path']) ? self::getRealPath( - $config['root-path'], false) : dirname($_SERVER['SCRIPT_FILENAME'])); + $rootPath = $rootPath ? self::getRealPath($rootPath, false, true) : (!empty($config['root-path']) ? self::getRealPath( + $config['root-path'], false, true) : dirname($_SERVER['SCRIPT_FILENAME'])); Wind::register($rootPath, $appName, true); self::$_app[$appName] = $application; } From 88cf8f91efc5e0e9a254f006d1c3f2bddbb267ff Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 04:43:52 +0000 Subject: [PATCH 0496/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2568 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index af06333f..77b961ed 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -51,8 +51,8 @@ public function __construct($config, $factory) { public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); - $this->setModules('default', $this->defaultModule); - $this->windFactory->loadClassDefinitions($this->getConfig('components')); + $_modules = $this->getConfig('modules', '', array()); + $this->setModules('default', !empty($_modules) ? current($_modules) : $this->defaultModule); $this->_getHandlerAdapter()->route(); $this->processRequest(); restore_error_handler(); From dc70ec82ebdde6aa66a9e31ad4ac5c738db10f77 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 05:08:21 +0000 Subject: [PATCH 0497/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2569 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 77b961ed..a3022b0a 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -51,8 +51,7 @@ public function __construct($config, $factory) { public function run() { set_error_handler('WindHelper::errorHandle'); set_exception_handler('WindHelper::exceptionHandle'); - $_modules = $this->getConfig('modules', '', array()); - $this->setModules('default', !empty($_modules) ? current($_modules) : $this->defaultModule); + $this->setModules('default', $this->defaultModule); $this->_getHandlerAdapter()->route(); $this->processRequest(); restore_error_handler(); From 149fc6eef4876af1304752766c326215dfeed5a8 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 06:04:39 +0000 Subject: [PATCH 0498/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2570 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index a3022b0a..413d73c7 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -98,6 +98,7 @@ public function processRequest() { throw new WindActionException( '[web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); + $this->resolveActionMapping($handler); $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { $this->sendErrorMessage($e); @@ -208,6 +209,26 @@ public function getWindFactory() { return $this->windFactory; } + /** + * @param WindClassProxy $handler + * @return + */ + protected function resolveActionMapping($handler) { + //TODO 缓存处理解析结果 + $_token = $this->handlerAdapter->getModule() . '_' . $this->handlerAdapter->getController() . '_' . $this->handlerAdapter->getAction(); + $_filters = $this->getConfig('filters'); + foreach ($_filters as $_filter) { + if (!isset($_filter['class'])) + continue; + if (!empty($_filter['pattern'])) { + preg_match('/^' . str_replace('*', '\w*', $_filter['pattern']) . '$/i', $_token, $_matchs); + if ($_matchs) + $handler->registerEventListener('doAction', + WindFactory::createInstance(Wind::import($_filter['class']))); + } + } + } + /** * 异常处理请求 * @param WindActionException actionException From 5ec0b82a4b1e69a54ff93090c4e37e4d313eb232 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 06:13:07 +0000 Subject: [PATCH 0499/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2571 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index cad6dd3c..02ea0ae8 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -170,9 +170,8 @@ public static function register($path, $alias = '', $includePath = false, $reset unset(self::$_includePaths[$pos]); } array_unshift(self::$_includePaths, $path); - if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) { - throw new Exception('set include path error.'); - } + if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) {throw new Exception( + 'set include path error.');} } } @@ -193,8 +192,7 @@ public static function getRootPath($namespace) { * @return null */ public static function autoLoad($className, $path = '') { - if (isset(self::$_classes[$className])) - $path = self::$_classes[$className]; + $path || $path = isset(self::$_classes[$className]) ? self::$_classes[$className] : $className; if (WIND_DEBUG & 1) include $path . '.' . self::$_extensions; From 0a537ca268229badf0da6ecbaf725e5196c120c4 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 06:47:26 +0000 Subject: [PATCH 0500/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2572 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindForward.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wind/web/WindForward.php b/wind/web/WindForward.php index e3b56e89..f7db5f4a 100644 --- a/wind/web/WindForward.php +++ b/wind/web/WindForward.php @@ -159,8 +159,10 @@ public function getWindView() { if ($this->windView === null) $this->_getWindView(); $module = Wind::getApp()->getModules(); - isset($module['template-dir']) && $this->windView->templateDir = $module['template-dir']; - isset($module['compile-dir']) && $this->windView->compileDir = $module['compile-dir']; + if (!$this->windView->templateDir && isset($module['template-dir'])) + $this->windView->templateDir = $module['template-dir']; + if (!$this->windView->compileDir && isset($module['compile-dir'])) + $this->windView->compileDir = $module['compile-dir']; return $this->windView; } From b6eb920035079374d6a30ca3d35eea491b2b5fda Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 06:47:45 +0000 Subject: [PATCH 0501/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2573 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 02ea0ae8..0302af6d 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -193,11 +193,7 @@ public static function getRootPath($namespace) { */ public static function autoLoad($className, $path = '') { $path || $path = isset(self::$_classes[$className]) ? self::$_classes[$className] : $className; - - if (WIND_DEBUG & 1) - include $path . '.' . self::$_extensions; - else - @include $path . '.' . self::$_extensions; + include $path . '.' . self::$_extensions; } /** From 428e3d63eab80c04e9a1eedac775bbd97d725b17 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 07:04:59 +0000 Subject: [PATCH 0502/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2574 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindForward.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wind/web/WindForward.php b/wind/web/WindForward.php index f7db5f4a..623157e1 100644 --- a/wind/web/WindForward.php +++ b/wind/web/WindForward.php @@ -156,13 +156,14 @@ public function setArgs($args) { * @return WindView */ public function getWindView() { - if ($this->windView === null) + if ($this->windView === null) { $this->_getWindView(); - $module = Wind::getApp()->getModules(); - if (!$this->windView->templateDir && isset($module['template-dir'])) - $this->windView->templateDir = $module['template-dir']; - if (!$this->windView->compileDir && isset($module['compile-dir'])) - $this->windView->compileDir = $module['compile-dir']; + $module = Wind::getApp()->getModules(); + if (isset($module['template-dir'])) + $this->windView->templateDir = $module['template-dir']; + if (isset($module['compile-dir'])) + $this->windView->compileDir = $module['compile-dir']; + } return $this->windView; } From 9c62bf1018eb1aa2c1d35065432552629972eb1e Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 07:10:33 +0000 Subject: [PATCH 0503/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2575 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindView.php | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index 50d78504..20b389f6 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -80,9 +80,7 @@ class WindView extends WindModule implements IWindView { * @param boolean $display */ public function render($display = false) { - if (!$this->templateName) - return; - + if (!$this->templateName) {return;} //TODO 其他输出类型 $viewResolver = $this->_getViewResolver(); $viewResolver->setWindView($this); @@ -118,8 +116,7 @@ public function setConfig($config) { * @return string | false */ public function getViewTemplate($template = '', $ext = '') { - if (!$template) - $template = $this->templateName; + !$template && $template = $this->templateName; !$ext && $ext = $this->templateExt; if (false === strpos($template, ':')) $template = $this->templateDir . '.' . $template; @@ -138,39 +135,18 @@ public function getViewTemplate($template = '', $ext = '') { * @return string | false */ public function getCompileFile($template = '') { - if (!$this->compileDir) - return; + if (!$this->compileDir) {return;} + if ($this->compileDir == $this->templateDir) + throw new WindViewException('[wind.viewer.WindView.getCompileFile] the same directory compile and template.'); if (!$template) $template = $this->templateName; elseif (false !== ($pos = strpos($template, ':'))) $template = '__external.' . substr($template, $pos + 1); - - $dir = Wind::getRealDir($this->compileDir, true); + $dir = realpath(Wind::getRealPath($this->compileDir, false, true)); if (!is_dir($dir)) throw new WindViewException( '[viewer.WindView.getCompileFile] Template compile dir ' . $this->compileDir . ' is not exist.'); $dir .= '/' . str_replace('.', '_', $template); - /*$_tmp = explode('.', $template); - foreach ($_tmp as $_dir) { - !is_dir($dir) && @mkdir($dir); - $dir .= DIRECTORY_SEPARATOR . $_dir; - }*/ return $this->compileExt ? $dir . '.' . $this->compileExt : $dir; } - - /** - * @return WindViewerResolver - */ - public function getViewResolver() { - if (null !== $this->viewResolver) - return $this->viewResolver; - $this->_getViewResolver(); - $this->viewResolver->setWindView($this); - if (!$this->getIsCache()) - return $this->viewResolver; - $this->viewResolver = new WindClassProxy($this->viewResolver); - $listener = Wind::import('WIND:viewer.listener.WindViewCacheListener'); - $this->viewResolver->registerEventListener('windFetch', new $listener($this)); - return $this->viewResolver; - } } \ No newline at end of file From a6d1984301989d3df89c0cafaf18c9f1a3b05d59 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 07:10:46 +0000 Subject: [PATCH 0504/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2576 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 58ccbd3d..b782035f 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -77,7 +77,7 @@ public function windAssign($vars, $key = '') {} public function compile($template, $suffix = '', $output = false) { $templateFile = $this->windView->getViewTemplate($template, $suffix); if (!is_file($templateFile)) - throw new WindViewException('[component.viewer.WindView.parseFilePath] ' . $templateFile, + throw new WindViewException('[component.viewer.WindViewerResolver.compile] ' . $templateFile, WindViewException::VIEW_NOT_EXIST); $compileFile = $this->windView->getCompileFile($template); @@ -139,7 +139,7 @@ class WindRender { public static function render($__tpl, $__vars, $__viewer) { @extract($__vars, EXTR_REFS); if (!@include ($__tpl)) - throw new WindViewException('[component.viewer.ViewerResolver.render] template name ' . $__tpl, + throw new WindViewException('[component.viewer.WindRender.render] template name ' . $__tpl, WindViewException::VIEW_NOT_EXIST); } } \ No newline at end of file From 6ec04678ada467ed368bcc325cb4dfd647440cb5 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 07:19:27 +0000 Subject: [PATCH 0505/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2577 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 413d73c7..400eb5c4 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -216,15 +216,16 @@ public function getWindFactory() { protected function resolveActionMapping($handler) { //TODO 缓存处理解析结果 $_token = $this->handlerAdapter->getModule() . '_' . $this->handlerAdapter->getController() . '_' . $this->handlerAdapter->getAction(); - $_filters = $this->getConfig('filters'); + $_filters = $this->getConfig('filters', '', array()); foreach ($_filters as $_filter) { if (!isset($_filter['class'])) continue; if (!empty($_filter['pattern'])) { preg_match('/^' . str_replace('*', '\w*', $_filter['pattern']) . '$/i', $_token, $_matchs); - if ($_matchs) - $handler->registerEventListener('doAction', - WindFactory::createInstance(Wind::import($_filter['class']))); + if (!$_matchs) + continue; + $handler->registerEventListener('doAction', + WindFactory::createInstance(Wind::import($_filter['class']))); } } } From 8ea8d6b9d74f4e5a618d55e2f647b28971406fa6 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 07:20:26 +0000 Subject: [PATCH 0506/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2578 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 400eb5c4..0dabb915 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -222,10 +222,9 @@ protected function resolveActionMapping($handler) { continue; if (!empty($_filter['pattern'])) { preg_match('/^' . str_replace('*', '\w*', $_filter['pattern']) . '$/i', $_token, $_matchs); - if (!$_matchs) - continue; - $handler->registerEventListener('doAction', - WindFactory::createInstance(Wind::import($_filter['class']))); + if ($_matchs) + $handler->registerEventListener('doAction', + WindFactory::createInstance(Wind::import($_filter['class']))); } } } From 9f6e7149d2bdde7550ab2d70ba2a1e592a76f74d Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 10:23:40 +0000 Subject: [PATCH 0507/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2579 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/cache/strategy/WindFileCache.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/wind/cache/strategy/WindFileCache.php b/wind/cache/strategy/WindFileCache.php index 027b49c5..5512f0c3 100644 --- a/wind/cache/strategy/WindFileCache.php +++ b/wind/cache/strategy/WindFileCache.php @@ -44,7 +44,8 @@ protected function setValue($key, $value, $expire = 0) { * @see AbstractWindCache::get() */ protected function getValue($key) { - if (!is_file($key)) return null; + if (!is_file($key)) + return null; return WindFile::read($key); } @@ -70,15 +71,17 @@ public function clear() { */ protected function buildSecurityKey($key) { $key = parent::buildSecurityKey($key); - if (false !== ($dir = $this->checkCacheDir($key))) return $dir; + if (false !== ($dir = $this->checkCacheDir($key))) + return $dir; $_dir = $this->getCacheDir(); if (0 < ($level = $this->getCacheDirectoryLevel())) { $_subdir = substr(md5($key), 0, $level); - $_dir .= DIRECTORY_SEPARATOR . $_subdir; - if (!is_dir($_dir)) mkdir($_dir, 0777, true); + $_dir .= '/' . $_subdir; + if (!is_dir($_dir)) + mkdir($_dir, 0777, true); } $filename = $key . '.' . $this->getCacheFileSuffix(); - $this->cacheFileList[$key] = ($_dir ? $_dir . DIRECTORY_SEPARATOR . $filename : $filename); + $this->cacheFileList[$key] = ($_dir ? $_dir . '/' . $filename : $filename); return $this->cacheFileList[$key]; } @@ -97,8 +100,9 @@ private function checkCacheDir($key) { * @param string $dir */ public function setCacheDir($dir) { - $_dir = Wind::getRealDir($dir); - if (!is_dir($_dir)) mkdir($_dir, 0777, true); + $_dir = Wind::getRealPath($dir, false, true); + if (!is_dir($_dir)) + mkdir($_dir, 0777, true); $this->cacheDir = $_dir; } From 14522d37d5ff33ddd47a1c0104201e7c19b9cb07 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 6 Sep 2011 10:23:53 +0000 Subject: [PATCH 0508/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2580 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index 0dabb915..e1ffd3ec 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -33,7 +33,6 @@ class WindWebApplication extends WindModule implements IWindApplication { /** * 应用初始化操作 - * * @param array|string $config * @param WindFactory $factory * @param string $runCallBack @@ -214,13 +213,11 @@ public function getWindFactory() { * @return */ protected function resolveActionMapping($handler) { - //TODO 缓存处理解析结果 + $filters = $this->getConfig('filters', '', array()); + if (!$filters) {return;} $_token = $this->handlerAdapter->getModule() . '_' . $this->handlerAdapter->getController() . '_' . $this->handlerAdapter->getAction(); - $_filters = $this->getConfig('filters', '', array()); - foreach ($_filters as $_filter) { - if (!isset($_filter['class'])) - continue; - if (!empty($_filter['pattern'])) { + foreach ($filters as $_filter) { + if (isset($_filter['class']) && !empty($_filter['pattern'])) { preg_match('/^' . str_replace('*', '\w*', $_filter['pattern']) . '$/i', $_token, $_matchs); if ($_matchs) $handler->registerEventListener('doAction', From f46dc703a643635d876012ec961f0c8d2c291ab5 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 7 Sep 2011 02:21:18 +0000 Subject: [PATCH 0509/1065] =?UTF-8?q?route=E8=B7=AF=E7=94=B1=E8=A7=84?= =?UTF-8?q?=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2581 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/AbstractWindRouter.php | 52 ++++++++-- wind/router/route/AbstractWindRoute.php | 22 ++++- wind/router/route/WindRoute.php | 121 ++++++++++++++++++------ wind/web/WindUrlHelper.php | 12 +-- 4 files changed, 165 insertions(+), 42 deletions(-) diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php index fd7affab..93c058e3 100644 --- a/wind/router/AbstractWindRouter.php +++ b/wind/router/AbstractWindRouter.php @@ -16,11 +16,13 @@ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $module; protected $controller = 'index'; protected $action = 'run'; - protected $reverse = "%s?m=%s&c=%s&a=%s&"; + protected $reverse = "%s?%s=%s&%s=%s&%s=%s&"; /** * @var AbstractWindRoute */ protected $currentRoute = null; + + protected $routeMap = array(); /** * 解析请求参数,并返回路由结果 @@ -46,6 +48,7 @@ public function setConfig($config) { $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); + $this->createRoute($this->getConfig('rules')); } } @@ -55,17 +58,35 @@ public function setConfig($config) { */ protected function setParams($params) { foreach ($params as $key => $value) { - if ($this->actionKey === $key) + if ($this->actionKey === $key && $value) $this->setAction($value); - elseif ($this->controllerKey === $key) + elseif ($this->controllerKey === $key && $value) $this->setController($value); - elseif ($this->moduleKey === $key) + elseif ($this->moduleKey === $key && $value) $this->setModule($value); else $this->getRequest()->setAttribute($value, $key); } } - + + /** + * 创建过滤链 + * @param array $config + */ + protected function createRoute($config) { + if (!$config) return ; + $index = 0; + foreach ($config as $ruleName => $rule) { + $class = isset($rule['class']) ? $rule['class'] : 'WIND:router.route.WindRoute'; + $class = Wind::import($class); + $instance = $this->getSystemFactory()->createInstance($class); + if (!$instance instanceof AbstractWindRoute) continue; + $this->routeMap[$ruleName] = $index ++; + $instance->setConfig($rule); + $this->addRoute($instance); + } + } + /** * 添加路由协议对象,如果添加的路由协议已经存在则抛出异常 * @param Object $routeInstance @@ -167,5 +188,24 @@ public function setControllerKey($controllerKey) { public function setActionKey($actionKey) { $this->actionKey = $actionKey; } - + + /** + * 设置当前使用的route + * Enter description here ... + * @param AbstractWindRoute $route + */ + public function setCurrentRoute($route) { + $this->currentRoute = $route; + } + + /** + * 根据rule的规则名称,从路由链中获得该路由的对象 + * @param string $key + * @return AbstractWindRoute + */ + public function getRoute($rule) { + $index = $this->routeMap[$rule]; + return isset($this->_interceptors[$index]) ? $this->_interceptors[$index] : null; + } + } \ No newline at end of file diff --git a/wind/router/route/AbstractWindRoute.php b/wind/router/route/AbstractWindRoute.php index a01947a9..56671d67 100644 --- a/wind/router/route/AbstractWindRoute.php +++ b/wind/router/route/AbstractWindRoute.php @@ -5,7 +5,11 @@ * @version $Id$ * @package */ -abstract class AbstractWindRoute extends WindModule { +abstract class AbstractWindRoute extends WindHandlerInterceptor { + protected $regex = ''; + /*反向生成url规则*/ + protected $reverse = ''; + protected $params = array(); /** * 根据匹配的路由规则,构建Url @@ -33,10 +37,24 @@ public function handle() { if (null !== ($handler = $this->interceptorChain->getHandler())) { $this->result = call_user_func_array(array($handler, 'handle'), $args); } else { - $this->result = $this->interceptorChain->execute(); + $this->result = $this->interceptorChain->handle(); } return $this->result; } + + /* (non-PHPdoc) + * @see WindModule::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->regex = trim($this->getConfig('regex'), '/'); + $this->reverse = trim($this->getConfig('reverse'), '/'); + $this->params = $config['params']; + } + + public function preHandle(){} + + public function postHandle(){} } ?> \ No newline at end of file diff --git a/wind/router/route/WindRoute.php b/wind/router/route/WindRoute.php index 98a44499..d34cecd1 100644 --- a/wind/router/route/WindRoute.php +++ b/wind/router/route/WindRoute.php @@ -6,48 +6,113 @@ * @package */ class WindRoute extends AbstractWindRoute { - /** - * 属性名称 - * - * @var array - */ - protected $params = array(); - /** - * 正则表达式 - * - * @var string - */ - protected $pattern; - /** - * 用于反响生成Url的表达式 - * - * @var string - */ - protected $reverse; - + private $separator = '&'; + private $keyValue = '='; + private $arrayKey = '_array_'; + /* (non-PHPdoc) * @see IWindRoute::match() */ public function match() { - //TODO + $requireUri = $this->getRequest()->getBaseUrl(true) . '/' . trim($this->getRequest()->getPathInfo(), '?/'); + if (!preg_match_all('/' . $this->regex . '/', $requireUri, $matches)) return null; + $this->interceptorChain->setCurrentRoute($this); + $args = array(); + foreach ($this->params as $key => $value) { + if (!isset($matches[$value])) continue; + $temp = $matches[$value][0]; + $args[$key] = $temp; + } + $args = array_merge($args, $this->urlToArgs($args['*'])); + unset($args['*']); + $_GET = array_merge($_GET, $args); + return $args; } /* (non-PHPdoc) * @see IWindRoute::build() */ public function build() { - // TODO Auto-generated method stub + list($action, $args) = func_get_args(); + list($params, $anchor) = $this->resolveParaments($action, $args); + + $temp = array(); + foreach ($this->params as $key => $val) { + if ($key != '*') { + $temp[$key] = $params[$key]; + unset($params[$key]); + } + } + + $temp['*'] = str_replace(array('&', '='), array($this->separator, $this->keyValue), WindUrlHelper::argsToUrl($params)); + $url = strtr($this->reverse, $temp); + + return $this->getRequest()->getBaseUrl(true) . '/' . $url . $anchor; + } + + /** + * 解析 + * 解析传入的action和参数,及锚点 + * + * @param string $action + * @param array $args + * @return array + */ + private function resolveParaments($action ,$args) { + $temp = explode('#', $action, 2); + $anchor = isset($temp[1]) ? $temp[1] : ''; + $action = $temp[0]; + + list($_a, $_c, $_m, $params) = WindUrlHelper::resolveAction($action, $args); + if (isset($params['#'])) { + $anchor = $params['#']; + unset($params['#']); + } + + $params[$this->interceptorChain->getControllerKey()] = $_c; + $params[$this->interceptorChain->getModuleKey()] = $_m; + $params[$this->interceptorChain->getActionKey()] = $_a; + return array($params, $anchor ? '#' . $anchor : ''); } - /* (non-PHPdoc) - * @see WindModule::setConfig() + /** + * 从url转化为数组 + * @param string $pathinfo + * @return boolean + */ + private function urlToArgs($pathinfo) { + if (!$pathinfo) return array(); + $params = explode($this->separator, $pathinfo); + $num = count($params); + $args = array(); + for($i = 0; $i < $num; $i++) { + if ($this->separator == $this->keyValue) { + $key = $params[$i]; + $value = isset($params[$i+1]) ? urldecode($params[$i+1]) : null; + $i ++; + } else { + list($key, $value) = explode($this->keyValue, $params[$i], 2); + $value = urldecode($value); + } + + if (strpos($key, $this->arrayKey) === 0) { + $key = substr($key, strlen($this->arrayKey)); + $value = unserialize($value); + } + $args[$key] = $value; + } + return $args; + } + + /** + * (non-PHPdoc) + * @see AbstractWindRoute::setConfig() */ public function setConfig($config) { - parent::setConfig($config); - $this->setParams($this->getConfig('params')); - $this->setPattern($this->getConfig('pattern')); - $this->setReverse($this->getConfig('reverse')); + if (!$config) return null; + parent::setConfig($config); + $this->separator = $this->getConfig('var-separator', '', '&'); + $this->keyValue = $this->getConfig('key-separator', '', '='); } - } ?> \ No newline at end of file diff --git a/wind/web/WindUrlHelper.php b/wind/web/WindUrlHelper.php index 75a39bdc..4a2fbc6a 100644 --- a/wind/web/WindUrlHelper.php +++ b/wind/web/WindUrlHelper.php @@ -44,15 +44,15 @@ public static function urlToArgs($url, $decode = true) { * @return string */ public static function argsToUrl($args) { - $_tmp = ''; + $_tmp = array(); foreach ((array) $args as $key => $value) { if (is_array($value)) { - $_tmp .= self::$_sep . "$key=" . urlencode(serialize($value)) . "&"; + $_tmp[] = self::$_sep . "$key=" . urlencode(serialize($value)); continue; } - $_tmp .= "$key=" . urlencode($value) . "&"; + $_tmp[] = "$key=" . urlencode($value); } - return $_tmp; + return implode('&', $_tmp); } /** @@ -68,7 +68,7 @@ public static function resolveAction($action, $args = array()) { $args = array_merge($args, ($_args ? self::urlToArgs($_args, false) : array())); $action = explode('/', trim($action, '/') . '/'); end($action); - return array(prev($action), prev($action), prev($action), self::argsToUrl($args)); + return array(prev($action), prev($action), prev($action), $args); } /** @@ -79,7 +79,7 @@ public static function resolveAction($action, $args = array()) { * @param AbstractWindRoute $route * @return string */ - public static function createUrl($action, $args = array(), $route = null) { + public static function createUrl($action, $args = array(), $route = null) { /* @var $router AbstractWindRouter */ $router = Wind::getApp()->getComponent('router'); return $router->assemble($action, $args, $route); From 80fe4162e3679f130aadb07c053b833ced717633 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 7 Sep 2011 02:23:29 +0000 Subject: [PATCH 0510/1065] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2582 18ba2127-5a84-46d4-baec-3457e417f034 --- docs/config/router_config.xml | 31 ++++++++++++++++++++++++++----- wind/router/WindRouter.php | 8 ++++---- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/docs/config/router_config.xml b/docs/config/router_config.xml index b79960ba..96f3f2e0 100644 --- a/docs/config/router_config.xml +++ b/docs/config/router_config.xml @@ -1,25 +1,46 @@ + - m/c-a/* + - htm + - / + - - + + + + + WIND:router.route.WindRoute + ([a-zA-Z]*)([\-]?)([a-zA-Z]*)([\-]?)([a-zA-Z]*)\/([\d]+)\/(.*).htm + + 1 + 3 + 5 + 6 + 7 + + + a-c-m/id/*.htm + + \ No newline at end of file diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index 119f7039..6c620ddf 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -21,15 +21,15 @@ public function route() { * @see AbstractWindRouter::assemble() */ public function assemble($action, $args = array(), $route = null) { - if ($route !== null) + if (null !== ($route = $this->getRoute($route))) return $route->build($action, $args); if ($this->currentRoute !== null) return $this->currentRoute->build($action, $args); list($_a, $_c, $_m, $args) = WindUrlHelper::resolveAction($action, $args); $_baseUrl = $this->getRequest()->getBaseUrl(true) . '/' . $this->getRequest()->getScript(); - $_url = sprintf($this->reverse, $_baseUrl, ($_m ? $_m : $this->module), ($_c ? $_c : $this->controller), - ($_a ? $_a : $this->action)); - return WindUrlHelper::checkUrl($_url . $args); + $_url = sprintf($this->reverse, $_baseUrl, $this->moduleKey, ($_m ? $_m : $this->module), $this->controllerKey, ($_c ? $_c : $this->controller), + $this->actionKey, ($_a ? $_a : $this->action)); + return WindUrlHelper::checkUrl($_url . WindUrlHelper::argsToUrl($args)); } /** From b435958e647f134d236cf7f3d95d33f1f482340c Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 7 Sep 2011 03:40:05 +0000 Subject: [PATCH 0511/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2583 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/AbstractWindRouter.php | 76 ++++++++++-------------------- wind/router/WindRouter.php | 6 +-- 2 files changed, 29 insertions(+), 53 deletions(-) diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php index 93c058e3..0e99a0fe 100644 --- a/wind/router/AbstractWindRouter.php +++ b/wind/router/AbstractWindRouter.php @@ -16,13 +16,11 @@ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $module; protected $controller = 'index'; protected $action = 'run'; - protected $reverse = "%s?%s=%s&%s=%s&%s=%s&"; + protected $reverse = "%s?m=%s&c=%s&a=%s&"; /** * @var AbstractWindRoute */ protected $currentRoute = null; - - protected $routeMap = array(); /** * 解析请求参数,并返回路由结果 @@ -48,7 +46,14 @@ public function setConfig($config) { $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); - $this->createRoute($this->getConfig('rules')); + foreach ($this->getConfig('rules', '', array()) as $ruleName => $rule) { + $class = isset($rule['class']) ? $rule['class'] : 'WIND:router.route.WindRoute'; + $instance = $this->getSystemFactory()->createInstance(Wind::import($class)); + if (!$instance instanceof AbstractWindRoute) + continue; + $instance->setConfig($rule); + $this->addRoute($ruleName, $instance); + } } } @@ -58,45 +63,36 @@ public function setConfig($config) { */ protected function setParams($params) { foreach ($params as $key => $value) { - if ($this->actionKey === $key && $value) + if ($this->actionKey === $key) $this->setAction($value); - elseif ($this->controllerKey === $key && $value) + elseif ($this->controllerKey === $key) $this->setController($value); - elseif ($this->moduleKey === $key && $value) + elseif ($this->moduleKey === $key) $this->setModule($value); else $this->getRequest()->setAttribute($value, $key); } } - - /** - * 创建过滤链 - * @param array $config - */ - protected function createRoute($config) { - if (!$config) return ; - $index = 0; - foreach ($config as $ruleName => $rule) { - $class = isset($rule['class']) ? $rule['class'] : 'WIND:router.route.WindRoute'; - $class = Wind::import($class); - $instance = $this->getSystemFactory()->createInstance($class); - if (!$instance instanceof AbstractWindRoute) continue; - $this->routeMap[$ruleName] = $index ++; - $instance->setConfig($rule); - $this->addRoute($instance); - } - } - + /** * 添加路由协议对象,如果添加的路由协议已经存在则抛出异常 + * @param string * @param Object $routeInstance * @throws WindException * @return */ - public function addRoute($routeInstance, $current = false) { - if ($current) - $this->currentRoute = $routeInstance; - $this->addInterceptors($routeInstance); + public function addRoute($alias, $route, $current = false) { + $this->addInterceptors(array($alias => $route)); + $current === true && $this->currentRoute = $alias; + } + + /** + * 根据rule的规则名称,从路由链中获得该路由的对象 + * @param string $key + * @return AbstractWindRoute + */ + public function getRoute($ruleName) { + return isset($this->_interceptors[$ruleName]) ? $this->_interceptors[$ruleName] : null; } /** @@ -188,24 +184,4 @@ public function setControllerKey($controllerKey) { public function setActionKey($actionKey) { $this->actionKey = $actionKey; } - - /** - * 设置当前使用的route - * Enter description here ... - * @param AbstractWindRoute $route - */ - public function setCurrentRoute($route) { - $this->currentRoute = $route; - } - - /** - * 根据rule的规则名称,从路由链中获得该路由的对象 - * @param string $key - * @return AbstractWindRoute - */ - public function getRoute($rule) { - $index = $this->routeMap[$rule]; - return isset($this->_interceptors[$index]) ? $this->_interceptors[$index] : null; - } - } \ No newline at end of file diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index 6c620ddf..ba6791e0 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -12,7 +12,7 @@ class WindRouter extends AbstractWindRouter { * @see IWindRouter::route() */ public function route() { - $this->setCallBack(array($this, 'defaultRoute')); + $this->setCallBack(array($this, 'defaultRoute'), array($this)); $params = $this->getHandler()->handle(); $this->setParams($params); } @@ -27,8 +27,8 @@ public function assemble($action, $args = array(), $route = null) { return $this->currentRoute->build($action, $args); list($_a, $_c, $_m, $args) = WindUrlHelper::resolveAction($action, $args); $_baseUrl = $this->getRequest()->getBaseUrl(true) . '/' . $this->getRequest()->getScript(); - $_url = sprintf($this->reverse, $_baseUrl, $this->moduleKey, ($_m ? $_m : $this->module), $this->controllerKey, ($_c ? $_c : $this->controller), - $this->actionKey, ($_a ? $_a : $this->action)); + $_url = sprintf($this->reverse, $_baseUrl, ($_m ? $_m : $this->module), ($_c ? $_c : $this->controller), + ($_a ? $_a : $this->action)); return WindUrlHelper::checkUrl($_url . WindUrlHelper::argsToUrl($args)); } From 039633334203b5de2461ba4eace89a79099f72ef Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 7 Sep 2011 04:59:33 +0000 Subject: [PATCH 0512/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2584 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/filter/WindHandlerInterceptorChain.php | 26 ++++++++------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/wind/filter/WindHandlerInterceptorChain.php b/wind/filter/WindHandlerInterceptorChain.php index 852ad3d9..e68dc9cb 100644 --- a/wind/filter/WindHandlerInterceptorChain.php +++ b/wind/filter/WindHandlerInterceptorChain.php @@ -6,10 +6,9 @@ * @package */ class WindHandlerInterceptorChain extends WindModule { - protected $_interceptors = array(); + protected $_interceptors = array('_Na' => null); protected $_callBack = null; protected $_args = array(); - protected $_state = 0; /** * 设置回调方法 @@ -30,13 +29,12 @@ public function setCallBack($callBack, $args = array()) { * @return void|mixed */ public function handle() { + reset($this->_interceptors); if ($this->_callBack === null) return null; - if (is_string($this->_callBack) && !function_exists($this->_callBack)) { - throw new WindException( + if (is_string($this->_callBack) && !function_exists($this->_callBack)) {throw new WindException( '[filter.WindHandlerInterceptorChain.execute]' . $this->_callBack, - WindException::ERROR_FUNCTION_NOT_EXIST); - } + WindException::ERROR_FUNCTION_NOT_EXIST);} return call_user_func_array($this->_callBack, (array) $this->_args); } @@ -46,19 +44,16 @@ public function handle() { * @return WindHandlerInterceptor */ public function getHandler() { - if (count($this->_interceptors) <= 0) { - return $this; - } - if ($this->_state >= count($this->_interceptors)) - return null; - $handler = $this->_interceptors[$this->_state++]; - if ($handler instanceof WindHandlerInterceptor) { + if (count($this->_interceptors) <= 1) {return $this;} + $handler = next($this->_interceptors); + if ($handler === false) {return null;} + if (method_exists($handler, 'handle')) { $handler->setHandlerInterceptorChain($this); return $handler; } return $this->getHandler(); } - + /** * 添加过滤连中的拦截器对象, 支持数组和对象两种类型 * @@ -77,10 +72,9 @@ public function addInterceptors($interceptors) { * @return boolean */ public function reset() { - $this->_interceptors = array(); + $this->_interceptors = array('_Na' => null); $this->_callBack = null; $this->_args = array(); - $this->_state = 0; return true; } } From bc446f579f26f94deac7195a8c7d8331d2c9016b Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 7 Sep 2011 09:14:04 +0000 Subject: [PATCH 0513/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2585 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/AbstractWindRouter.php | 16 ++-- wind/router/WindRouter.php | 22 ++--- wind/router/route/AbstractWindRoute.php | 43 ++++------ wind/router/route/WindRoute.php | 102 ++++++++++-------------- 4 files changed, 76 insertions(+), 107 deletions(-) diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php index 0e99a0fe..cdde4de3 100644 --- a/wind/router/AbstractWindRouter.php +++ b/wind/router/AbstractWindRouter.php @@ -17,10 +17,6 @@ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $controller = 'index'; protected $action = 'run'; protected $reverse = "%s?m=%s&c=%s&a=%s&"; - /** - * @var AbstractWindRoute - */ - protected $currentRoute = null; /** * 解析请求参数,并返回路由结果 @@ -46,11 +42,9 @@ public function setConfig($config) { $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); - foreach ($this->getConfig('rules', '', array()) as $ruleName => $rule) { + foreach ($this->getConfig('routes', '', array()) as $ruleName => $rule) { $class = isset($rule['class']) ? $rule['class'] : 'WIND:router.route.WindRoute'; $instance = $this->getSystemFactory()->createInstance(Wind::import($class)); - if (!$instance instanceof AbstractWindRoute) - continue; $instance->setConfig($rule); $this->addRoute($ruleName, $instance); } @@ -63,14 +57,15 @@ public function setConfig($config) { */ protected function setParams($params) { foreach ($params as $key => $value) { + $this->getRequest()->setAttribute($value, $key); + if (!$value) + continue; if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) $this->setController($value); elseif ($this->moduleKey === $key) $this->setModule($value); - else - $this->getRequest()->setAttribute($value, $key); } } @@ -81,9 +76,8 @@ protected function setParams($params) { * @throws WindException * @return */ - public function addRoute($alias, $route, $current = false) { + public function addRoute($alias, $route) { $this->addInterceptors(array($alias => $route)); - $current === true && $this->currentRoute = $alias; } /** diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index ba6791e0..e96a6f88 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -12,7 +12,7 @@ class WindRouter extends AbstractWindRouter { * @see IWindRouter::route() */ public function route() { - $this->setCallBack(array($this, 'defaultRoute'), array($this)); + $this->setCallBack(array($this, 'defaultRoute')); $params = $this->getHandler()->handle(); $this->setParams($params); } @@ -21,15 +21,17 @@ public function route() { * @see AbstractWindRouter::assemble() */ public function assemble($action, $args = array(), $route = null) { - if (null !== ($route = $this->getRoute($route))) - return $route->build($action, $args); - if ($this->currentRoute !== null) - return $this->currentRoute->build($action, $args); - list($_a, $_c, $_m, $args) = WindUrlHelper::resolveAction($action, $args); - $_baseUrl = $this->getRequest()->getBaseUrl(true) . '/' . $this->getRequest()->getScript(); - $_url = sprintf($this->reverse, $_baseUrl, ($_m ? $_m : $this->module), ($_c ? $_c : $this->controller), - ($_a ? $_a : $this->action)); - return WindUrlHelper::checkUrl($_url . WindUrlHelper::argsToUrl($args)); + $route || $route = current($this->_interceptors); + if ($route) + $_url = $route->build($this, $action, $args); + else { + list($_a, $_c, $_m, $args) = WindUrlHelper::resolveAction($action, $args); + $_baseUrl = $this->getRequest()->getBaseUrl(true) . '/' . $this->getRequest()->getScript(); + $_url = sprintf($this->reverse, $_baseUrl, ($_m ? $_m : $this->module), ($_c ? $_c : $this->controller), + ($_a ? $_a : $this->action)); + $_url .= WindUrlHelper::argsToUrl($args); + } + return WindUrlHelper::checkUrl($_url); } /** diff --git a/wind/router/route/AbstractWindRoute.php b/wind/router/route/AbstractWindRoute.php index 56671d67..9ea1749d 100644 --- a/wind/router/route/AbstractWindRoute.php +++ b/wind/router/route/AbstractWindRoute.php @@ -6,55 +6,46 @@ * @package */ abstract class AbstractWindRoute extends WindHandlerInterceptor { - protected $regex = ''; - /*反向生成url规则*/ + protected $pattern = ''; protected $reverse = ''; protected $params = array(); /** * 根据匹配的路由规则,构建Url - * + * @param AbstractWindRouter + * @param string $action + * @param array $args * @return string */ - abstract public function build(); + abstract public function build($route, $action, $args = array()); /** * 路由规则匹配方法,返回匹配到的参数列表 - * * @return array */ abstract public function match(); /* (non-PHPdoc) - * @see WindHandlerInterceptor::handle() + * @see WindHandlerInterceptor::preHandle() */ - public function handle() { - $args = func_get_args(); - $this->result = call_user_func_array(array($this, 'match'), $args); - if ($this->result !== null) { - return $this->result; - } - if (null !== ($handler = $this->interceptorChain->getHandler())) { - $this->result = call_user_func_array(array($handler, 'handle'), $args); - } else { - $this->result = $this->interceptorChain->handle(); - } - return $this->result; + public function preHandle() { + return $this->match(); } - + + /* (non-PHPdoc) + * @see WindHandlerInterceptor::postHandle() + */ + public function postHandle() {} + /* (non-PHPdoc) * @see WindModule::setConfig() */ public function setConfig($config) { parent::setConfig($config); - $this->regex = trim($this->getConfig('regex'), '/'); - $this->reverse = trim($this->getConfig('reverse'), '/'); - $this->params = $config['params']; + $this->pattern = $this->getConfig('pattern', '', $this->pattern); //trim($this->getConfig('regex'), '/'); + $this->reverse = $this->getConfig('reverse', '', $this->reverse); //trim($this->getConfig('reverse'), '/'); + $this->params = $this->getConfig('params', '', $this->params); } - - public function preHandle(){} - - public function postHandle(){} } ?> \ No newline at end of file diff --git a/wind/router/route/WindRoute.php b/wind/router/route/WindRoute.php index d34cecd1..0d3cafbe 100644 --- a/wind/router/route/WindRoute.php +++ b/wind/router/route/WindRoute.php @@ -6,73 +6,55 @@ * @package */ class WindRoute extends AbstractWindRoute { + protected $pattern = '\?(\w+)(\/\w+)?(\/\w+)?'; + protected $reverse = '%s/%s/%s/&'; + protected $params = array('a' => array('map' => 1), 'c' => array('map' => 2), 'm' => array('map' => 3)); private $separator = '&'; private $keyValue = '='; private $arrayKey = '_array_'; - + /* (non-PHPdoc) * @see IWindRoute::match() */ public function match() { - $requireUri = $this->getRequest()->getBaseUrl(true) . '/' . trim($this->getRequest()->getPathInfo(), '?/'); - if (!preg_match_all('/' . $this->regex . '/', $requireUri, $matches)) return null; - $this->interceptorChain->setCurrentRoute($this); - $args = array(); - foreach ($this->params as $key => $value) { - if (!isset($matches[$value])) continue; - $temp = $matches[$value][0]; - $args[$key] = $temp; + if (!preg_match_all('/' . $this->pattern . '/i', $this->getRequest()->getRequestUri(), $matches)) + return null; + $params = array(); + foreach ($this->params as $_n => $_p) { + if (isset($_p['map']) && isset($matches[$_p['map']][0])) + $_value = $matches[$_p['map']][0]; + else + $_value = isset($_p['default']) ? $_p['default'] : ''; + $params[$_n] = trim($_value, '-/'); } - $args = array_merge($args, $this->urlToArgs($args['*'])); - unset($args['*']); - $_GET = array_merge($_GET, $args); - return $args; + $_pathInfo = $this->getRequest()->getPathInfo(); + $_pathInfo && $params += WindUrlHelper::urlToArgs($_pathInfo); + return $params; } /* (non-PHPdoc) * @see IWindRoute::build() */ - public function build() { - list($action, $args) = func_get_args(); - list($params, $anchor) = $this->resolveParaments($action, $args); - - $temp = array(); + public function build($router, $action, $args = array()) { + list($_a, $_c, $_m, $args) = WindUrlHelper::resolveAction($action, $args); + $_args[] = $this->reverse; foreach ($this->params as $key => $val) { - if ($key != '*') { - $temp[$key] = $params[$key]; - unset($params[$key]); - } + if (!isset($val['map'])) + continue; + if ($key === $router->getModuleKey()) + $_args[$val['map']] = $_m ? $_m : $router->getModule(); + elseif ($key === $router->getControllerKey()) + $_args[$val['map']] = $_c ? $_c : $router->getController(); + elseif ($key === $router->getActionKey()) + $_args[$val['map']] = $_a ? $_a : $router->getAction(); + else + $_args[$val['map']] = $args[$key]; + unset($args[$key]); } - - $temp['*'] = str_replace(array('&', '='), array($this->separator, $this->keyValue), WindUrlHelper::argsToUrl($params)); - $url = strtr($this->reverse, $temp); - - return $this->getRequest()->getBaseUrl(true) . '/' . $url . $anchor; - } - - /** - * 解析 - * 解析传入的action和参数,及锚点 - * - * @param string $action - * @param array $args - * @return array - */ - private function resolveParaments($action ,$args) { - $temp = explode('#', $action, 2); - $anchor = isset($temp[1]) ? $temp[1] : ''; - $action = $temp[0]; - - list($_a, $_c, $_m, $params) = WindUrlHelper::resolveAction($action, $args); - if (isset($params['#'])) { - $anchor = $params['#']; - unset($params['#']); - } - - $params[$this->interceptorChain->getControllerKey()] = $_c; - $params[$this->interceptorChain->getModuleKey()] = $_m; - $params[$this->interceptorChain->getActionKey()] = $_a; - return array($params, $anchor ? '#' . $anchor : ''); + ksort($_args); + $url = call_user_func_array("sprintf", $_args); + $url .= WindUrlHelper::argsToUrl($args); + return $url; } /** @@ -81,15 +63,16 @@ private function resolveParaments($action ,$args) { * @return boolean */ private function urlToArgs($pathinfo) { - if (!$pathinfo) return array(); + if (!$pathinfo) + return array(); $params = explode($this->separator, $pathinfo); $num = count($params); $args = array(); - for($i = 0; $i < $num; $i++) { + for ($i = 0; $i < $num; $i++) { if ($this->separator == $this->keyValue) { $key = $params[$i]; - $value = isset($params[$i+1]) ? urldecode($params[$i+1]) : null; - $i ++; + $value = isset($params[$i + 1]) ? urldecode($params[$i + 1]) : null; + $i++; } else { list($key, $value) = explode($this->keyValue, $params[$i], 2); $value = urldecode($value); @@ -103,16 +86,15 @@ private function urlToArgs($pathinfo) { } return $args; } - + /** * (non-PHPdoc) * @see AbstractWindRoute::setConfig() */ public function setConfig($config) { - if (!$config) return null; - parent::setConfig($config); + parent::setConfig($config); $this->separator = $this->getConfig('var-separator', '', '&'); - $this->keyValue = $this->getConfig('key-separator', '', '='); + $this->keyValue = $this->getConfig('key-separator', '', '='); } } ?> \ No newline at end of file From adad64bbe61fbff1d160f6f9214025816a282b1f Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 7 Sep 2011 09:14:30 +0000 Subject: [PATCH 0514/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2586 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindUrlHelper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/web/WindUrlHelper.php b/wind/web/WindUrlHelper.php index 4a2fbc6a..a18df001 100644 --- a/wind/web/WindUrlHelper.php +++ b/wind/web/WindUrlHelper.php @@ -79,10 +79,10 @@ public static function resolveAction($action, $args = array()) { * @param AbstractWindRoute $route * @return string */ - public static function createUrl($action, $args = array(), $route = null) { + public static function createUrl($action, $args = array(), $anchor = '', $route = null) { /* @var $router AbstractWindRouter */ $router = Wind::getApp()->getComponent('router'); - return $router->assemble($action, $args, $route); + return $router->assemble($action, $args, $route) . ($anchor ? '#' . $anchor : ''); } } ?> \ No newline at end of file From 1ea006ab1dc91b6e87dd24fdb637540a6d4b805f Mon Sep 17 00:00:00 2001 From: yishuo Date: Wed, 7 Sep 2011 09:41:00 +0000 Subject: [PATCH 0515/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2587 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/route/WindRoute.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/router/route/WindRoute.php b/wind/router/route/WindRoute.php index 0d3cafbe..7f8a59ba 100644 --- a/wind/router/route/WindRoute.php +++ b/wind/router/route/WindRoute.php @@ -11,12 +11,12 @@ class WindRoute extends AbstractWindRoute { protected $params = array('a' => array('map' => 1), 'c' => array('map' => 2), 'm' => array('map' => 3)); private $separator = '&'; private $keyValue = '='; - private $arrayKey = '_array_'; /* (non-PHPdoc) * @see IWindRoute::match() */ public function match() { + echo $this->getRequest()->getPathInfo();exit; if (!preg_match_all('/' . $this->pattern . '/i', $this->getRequest()->getRequestUri(), $matches)) return null; $params = array(); From 4ba806e7fb667afe2d14b326caaf9b23676c3d65 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 7 Sep 2011 09:50:47 +0000 Subject: [PATCH 0516/1065] =?UTF-8?q?=E5=88=A0=E9=99=A4=E8=B0=83=E8=AF=95?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2588 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/route/WindRoute.php | 1 - 1 file changed, 1 deletion(-) diff --git a/wind/router/route/WindRoute.php b/wind/router/route/WindRoute.php index 7f8a59ba..1658ec14 100644 --- a/wind/router/route/WindRoute.php +++ b/wind/router/route/WindRoute.php @@ -16,7 +16,6 @@ class WindRoute extends AbstractWindRoute { * @see IWindRoute::match() */ public function match() { - echo $this->getRequest()->getPathInfo();exit; if (!preg_match_all('/' . $this->pattern . '/i', $this->getRequest()->getRequestUri(), $matches)) return null; $params = array(); From a4eec9e108fc8ba6b3076e04ac8f1aabf1df6ea1 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 7 Sep 2011 09:55:02 +0000 Subject: [PATCH 0517/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2589 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/AbstractWindUserSession.php | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 wind/http/session/AbstractWindUserSession.php diff --git a/wind/http/session/AbstractWindUserSession.php b/wind/http/session/AbstractWindUserSession.php deleted file mode 100644 index a3da2a70..00000000 --- a/wind/http/session/AbstractWindUserSession.php +++ /dev/null @@ -1,57 +0,0 @@ - 2010-12-17 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * 用户定义session存储机制 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -abstract class AbstractWindUserSession { - - /** - * 打开会话存储机制 - * @param string $savePath - * @param string $sessionName - * @return bollean - */ - public static abstract function open($savePath, $sessionName); - /** - * 关闭会话存储存储机制 - * @return bollean - */ - public static abstract function close(); - /** - * 将sessionID对应的数据写到存储 - * @param string $name - * @param mixed $value - */ - public static abstract function write($name,$value); - /** - * 从存储中装载session数据 - * @param mixed $sessid - */ - public static abstract function read($name); - /** - * 对存储系统中的数据进行垃圾收集 - * @param mixed $maxlifetime - */ - public static abstract function gc($maxlifetime); - /** - * 破坏与指定的会话ID相关联的数据 - * @param mixed $name - */ - public static abstract function destroy($name); - - public static function callUserSessionHandler(){ - $className = get_class($this); - session_set_save_handler(array($className,'open'),array($className,'close'),array($className,'read'),array($className,'write'),array($className,'destroy'),array($className,'gc')); - } -} - From 8d20d07fe6b530ca3c31139dd396046a18f8f8f8 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Wed, 7 Sep 2011 09:55:25 +0000 Subject: [PATCH 0518/1065] =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2590 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/AbstractWindSession.php | 97 +++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 wind/http/session/AbstractWindSession.php diff --git a/wind/http/session/AbstractWindSession.php b/wind/http/session/AbstractWindSession.php new file mode 100644 index 00000000..dcffb59b --- /dev/null +++ b/wind/http/session/AbstractWindSession.php @@ -0,0 +1,97 @@ + 2010-12-17 + * @link http://www.phpwind.com + * @copyright Copyright © 2003-2110 phpwind.com + * @license + */ + +/** + * 用户定义session存储机制 + * the last known user to change this file in the repository <$LastChangedBy: weihu $> + * @author Qian Su + * @version $Id: AbstractWindUserSession.php 1704 2011-03-08 10:40:17Z weihu $ + * @package + */ +abstract class AbstractWindSession extends WindModule { + protected $handler = null; + + /** + * 打开会话存储机制 + * @param string $savePath + * @param string $sessionName + * @return bollean + */ + public abstract function open($savePath, $sessionName); + /** + * 关闭会话存储存储机制 + * @return bollean + */ + public abstract function close(); + /** + * 将sessionID对应的数据写到存储 + * @param string $name + * @param mixed $value + */ + public abstract function write($sessId, $sessData); + /** + * 从存储中装载session数据 + * @param mixed $sessid + */ + public abstract function read($sessId); + /** + * 对存储系统中的数据进行垃圾收集 + * @param mixed $maxlifetime + */ + public abstract function gc($maxlifetime); + /** + * 破坏与指定的会话ID相关联的数据 + * @param mixed $name + */ + public abstract function destroy($sessId); + + /** + * 数据序列化 + * @param mixed $sessData + * @return string + */ + protected function serializeData($sessData) { + return (is_array($sessData) || is_object($sessData)) ? serialize($sessData) : $sessData; + } + + /** + * 数据反序列化 + * @param string $sessData + * @return mixed + */ + protected function unserializeData($sessData) { + $data = unserialize($sessData); + return (is_array($data) || is_object($data)) ? $data : $sessData; + } + + /** + * 设置监听接口 + */ + public function setSessionHandler(){ + session_set_save_handler(array($this,'open'),array($this,'close'),array($this,'read'),array($this,'write'),array($this,'destroy'),array($this,'gc')); + } + + + /** + * 设置链接对象 + * @param AbstractWindCache $handler + */ + public function setHandler($handler) { + if ($handler instanceof AbstractWindCache) + $this->handler = $handler; + } + + /** + * 获得链接对象 + * @return AbstractWindCache + */ + public function getHandler() { + return $this->_getHandler(); + } +} + From c45aff3919976cfcf2238d04e2eb73cb61c28c20 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 05:26:08 +0000 Subject: [PATCH 0519/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2591 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/route/WindRoute.php | 54 +++++---------------------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/wind/router/route/WindRoute.php b/wind/router/route/WindRoute.php index 1658ec14..4a9152a4 100644 --- a/wind/router/route/WindRoute.php +++ b/wind/router/route/WindRoute.php @@ -6,17 +6,17 @@ * @package */ class WindRoute extends AbstractWindRoute { - protected $pattern = '\?(\w+)(\/\w+)?(\/\w+)?'; + protected $pattern = '(\w+)(\/\w+)?(\/\w+)?\/*(&[\w+\/]*)*'; protected $reverse = '%s/%s/%s/&'; protected $params = array('a' => array('map' => 1), 'c' => array('map' => 2), 'm' => array('map' => 3)); - private $separator = '&'; - private $keyValue = '='; + protected $separator = '/'; /* (non-PHPdoc) * @see IWindRoute::match() */ public function match() { - if (!preg_match_all('/' . $this->pattern . '/i', $this->getRequest()->getRequestUri(), $matches)) + $_pathInfo = $this->getRequest()->getPathInfo(); + if (!preg_match_all('/' . $this->pattern . '/i', $_pathInfo, $matches)) return null; $params = array(); foreach ($this->params as $_n => $_p) { @@ -26,8 +26,8 @@ public function match() { $_value = isset($_p['default']) ? $_p['default'] : ''; $params[$_n] = trim($_value, '-/'); } - $_pathInfo = $this->getRequest()->getPathInfo(); - $_pathInfo && $params += WindUrlHelper::urlToArgs($_pathInfo); + list(, $_args) = explode('&', $_pathInfo . '&'); + $_args && $params += WindUrlHelper::urlToArgs($_args, true, $this->separator); return $params; } @@ -52,48 +52,8 @@ public function build($router, $action, $args = array()) { } ksort($_args); $url = call_user_func_array("sprintf", $_args); - $url .= WindUrlHelper::argsToUrl($args); + $url .= WindUrlHelper::argsToUrl($args, true, $this->separator); return $url; } - - /** - * 从url转化为数组 - * @param string $pathinfo - * @return boolean - */ - private function urlToArgs($pathinfo) { - if (!$pathinfo) - return array(); - $params = explode($this->separator, $pathinfo); - $num = count($params); - $args = array(); - for ($i = 0; $i < $num; $i++) { - if ($this->separator == $this->keyValue) { - $key = $params[$i]; - $value = isset($params[$i + 1]) ? urldecode($params[$i + 1]) : null; - $i++; - } else { - list($key, $value) = explode($this->keyValue, $params[$i], 2); - $value = urldecode($value); - } - - if (strpos($key, $this->arrayKey) === 0) { - $key = substr($key, strlen($this->arrayKey)); - $value = unserialize($value); - } - $args[$key] = $value; - } - return $args; - } - - /** - * (non-PHPdoc) - * @see AbstractWindRoute::setConfig() - */ - public function setConfig($config) { - parent::setConfig($config); - $this->separator = $this->getConfig('var-separator', '', '&'); - $this->keyValue = $this->getConfig('key-separator', '', '='); - } } ?> \ No newline at end of file From 14c2fa42f45daf22006e7c90f93191053d4cb445 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 05:26:23 +0000 Subject: [PATCH 0520/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2592 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/utility/WindUtility.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/wind/utility/WindUtility.php b/wind/utility/WindUtility.php index 921e7ce1..abe0382c 100644 --- a/wind/utility/WindUtility.php +++ b/wind/utility/WindUtility.php @@ -8,7 +8,24 @@ * @package */ class WindUtility { - + + /** + * 执行简单的条件表达式 + * @param string $v1 + * @param string $v2 + * @param string $expression + * @return + */ + public static function evalExpression($v1, $v2, $expression) { + switch ($expression) { + case '==': + return $v1 == $v2; + case '===': + return $v1 === $v2; + + } + } + /** * 递归合并两个数组 * @@ -73,8 +90,8 @@ public static function generateRandStr($length) { * @return array */ public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') { - return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, - 'default' => $default, 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); + return array('field' => $field, 'validator' => $validator, 'args' => (array) $args, 'default' => $default, + 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败')); } } From 1e993fe67a788d707907d6275d29f630c93eb0ee Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 05:26:36 +0000 Subject: [PATCH 0521/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2593 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindUrlHelper.php | 56 +++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/wind/web/WindUrlHelper.php b/wind/web/WindUrlHelper.php index a18df001..52b5213a 100644 --- a/wind/web/WindUrlHelper.php +++ b/wind/web/WindUrlHelper.php @@ -17,23 +17,31 @@ public static function checkUrl($url) { } /** - * @param unknown_type $args + * @param string $url + * @param boolean $decode + * @param string $separator + * @return array */ - public static function urlToArgs($url, $decode = true) { - if (false !== ($pos = strpos($url, '?'))) - $url = substr($url, $pos + 1); - $url = explode('&', $url . '&'); + public static function urlToArgs($url, $decode = true, $separator = '&=') { + !$separator && $separator = '&='; + false !== ($pos = strpos($url, '?')) && $url = substr($url, $pos + 1); + $_sep1 = substr($separator, 0, 1); + if ($_sep2 = substr($separator, 1, 1)) { + $url = preg_replace('/' . preg_quote($_sep1) . '[\w+]' . preg_quote($_sep1) . '/i', $_sep1, $url); + $url = str_replace($_sep2, $_sep1, $url); + } + $url = explode($_sep1, trim($url, $_sep1) . $_sep1); $args = array(); - foreach ($url as $value) { - list($_k, $_v) = explode('=', $value . '='); - if ($_k) { - $decode && $_v = urldecode($_v); - if (strpos($_k, self::$_sep) === 0) { - $_k = substr($_k, strlen(self::$_sep)); - $_v = unserialize($_v); - } - $args[$_k] = $_v; + for ($i = 0; $i < count($url); $i = $i + 2) { + if (!isset($url[$i]) || !isset($url[$i + 1])) + continue; + $_v = $decode ? urldecode($url[$i + 1]) : $url[$i + 1]; + $_k = $url[$i]; + if (strpos($_k, self::$_sep) === 0) { + $_k = substr($_k, strlen(self::$_sep)); + $_v = unserialize($_v); } + $args[$_k] = $_v; } return $args; } @@ -43,16 +51,20 @@ public static function urlToArgs($url, $decode = true) { * @param array $args * @return string */ - public static function argsToUrl($args) { - $_tmp = array(); + public static function argsToUrl($args, $encode = true, $separator = '&=') { + !$separator && $separator = '&='; + $_sep1 = substr($separator, 0, 1); + $_sep2 = substr($separator, 1, 1); + !$_sep2 && $_sep2 = $_sep1; + $_tmp = ''; foreach ((array) $args as $key => $value) { - if (is_array($value)) { - $_tmp[] = self::$_sep . "$key=" . urlencode(serialize($value)); - continue; - } - $_tmp[] = "$key=" . urlencode($value); + if (is_array($value)) + $_tmp .= self::$_sep . "$key" . $_sep2 . urlencode(serialize($value)); + else + $_tmp .= "$key" . $_sep2 . urlencode($value); + $_tmp .= $_sep1; } - return implode('&', $_tmp); + return $_tmp; } /** From 186cd69bfbfc03b1080ef5dad6d0b2cb3ef9a916 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 07:59:48 +0000 Subject: [PATCH 0522/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2594 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/AbstractWindRouter.php | 9 +++++---- wind/router/route/WindRoute.php | 31 ++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php index cdde4de3..166e0d95 100644 --- a/wind/router/AbstractWindRouter.php +++ b/wind/router/AbstractWindRouter.php @@ -10,6 +10,7 @@ * @package */ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { + protected $defaultRoute = 'WIND:router.route.WindRoute'; protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; @@ -42,11 +43,11 @@ public function setConfig($config) { $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey); $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); - foreach ($this->getConfig('routes', '', array()) as $ruleName => $rule) { - $class = isset($rule['class']) ? $rule['class'] : 'WIND:router.route.WindRoute'; + foreach ($this->getConfig('routes', '', array()) as $routeName => $route) { + $class = isset($route['class']) ? $route['class'] : $this->defaultRoute; $instance = $this->getSystemFactory()->createInstance(Wind::import($class)); - $instance->setConfig($rule); - $this->addRoute($ruleName, $instance); + $instance->setConfig($route); + $this->addRoute($routeName, $instance); } } } diff --git a/wind/router/route/WindRoute.php b/wind/router/route/WindRoute.php index 4a9152a4..c0096531 100644 --- a/wind/router/route/WindRoute.php +++ b/wind/router/route/WindRoute.php @@ -1,30 +1,33 @@ * @author Qiong Wu * @version $Id$ * @package */ class WindRoute extends AbstractWindRoute { - protected $pattern = '(\w+)(\/\w+)?(\/\w+)?\/*(&[\w+\/]*)*'; - protected $reverse = '%s/%s/%s/&'; - protected $params = array('a' => array('map' => 1), 'c' => array('map' => 2), 'm' => array('map' => 3)); + protected $pattern = '^([\w-_\.]+\.\w+\?|\?|\w+\.\w+\?\/)*(\w+)(\/\w+)?(\/\w+)?(\/|\/?&.*)*$'; + protected $reverse = '%s%s/%s/%s/'; + protected $params = array('script' => array('map' => 1), 'a' => array('map' => 2), 'c' => array('map' => 3), + 'm' => array('map' => 4)); protected $separator = '/'; /* (non-PHPdoc) * @see IWindRoute::match() */ public function match() { - $_pathInfo = $this->getRequest()->getPathInfo(); - if (!preg_match_all('/' . $this->pattern . '/i', $_pathInfo, $matches)) - return null; - $params = array(); + $_pathInfo = str_replace($this->getRequest()->getBaseUrl(), '', $this->getRequest()->getRequestUri()); + if (!preg_match_all('/' . $this->pattern . '/i', trim($_pathInfo, '/'), $matches)) {return null;} foreach ($this->params as $_n => $_p) { if (isset($_p['map']) && isset($matches[$_p['map']][0])) $_value = $matches[$_p['map']][0]; else $_value = isset($_p['default']) ? $_p['default'] : ''; - $params[$_n] = trim($_value, '-/'); + $this->params[$_n]['value'] = $params[$_n] = trim($_value, '-/'); } list(, $_args) = explode('&', $_pathInfo . '&'); $_args && $params += WindUrlHelper::urlToArgs($_args, true, $this->separator); @@ -47,13 +50,21 @@ public function build($router, $action, $args = array()) { elseif ($key === $router->getActionKey()) $_args[$val['map']] = $_a ? $_a : $router->getAction(); else - $_args[$val['map']] = $args[$key]; + $_args[$val['map']] = isset($args[$key]) ? $args[$key] : $val['value']; unset($args[$key]); } ksort($_args); $url = call_user_func_array("sprintf", $_args); - $url .= WindUrlHelper::argsToUrl($args, true, $this->separator); + $url .= '&' . WindUrlHelper::argsToUrl($args, true, $this->separator); return $url; } + + /* (non-PHPdoc) + * @see AbstractWindRoute::setConfig() + */ + public function setConfig($config) { + parent::setConfig($config); + $this->separator = $this->getConfig('separator', '', $this->separator); + } } ?> \ No newline at end of file From bc375b79484124ff21f48d2a3b8dbe4f64a4e16d Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 08:06:12 +0000 Subject: [PATCH 0523/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2595 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/route/WindRoute.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/router/route/WindRoute.php b/wind/router/route/WindRoute.php index c0096531..e3715557 100644 --- a/wind/router/route/WindRoute.php +++ b/wind/router/route/WindRoute.php @@ -20,8 +20,8 @@ class WindRoute extends AbstractWindRoute { * @see IWindRoute::match() */ public function match() { - $_pathInfo = str_replace($this->getRequest()->getBaseUrl(), '', $this->getRequest()->getRequestUri()); - if (!preg_match_all('/' . $this->pattern . '/i', trim($_pathInfo, '/'), $matches)) {return null;} + $_pathInfo = trim(str_replace($this->getRequest()->getBaseUrl(), '', $this->getRequest()->getRequestUri()), '/'); + if (!$_pathInfo || !preg_match_all('/' . $this->pattern . '/i', trim($_pathInfo, '/'), $matches)) {return null;} foreach ($this->params as $_n => $_p) { if (isset($_p['map']) && isset($matches[$_p['map']][0])) $_value = $matches[$_p['map']][0]; From 776faab2c8b3158a67393f2aa6b2bdc41cc91672 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 08:28:07 +0000 Subject: [PATCH 0524/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2596 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindWebApplication.php | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index e1ffd3ec..c2579236 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -187,27 +187,6 @@ public function getComponent($componentName) { return $component; } - /** - * @return WindHttpRequest $request - */ - public function getRequest() { - return $this->request; - } - - /** - * @return WindHttpResponse $response - */ - public function getResponse() { - return $this->response; - } - - /** - * @return WindFactory $windFactory - */ - public function getWindFactory() { - return $this->windFactory; - } - /** * @param WindClassProxy $handler * @return @@ -217,11 +196,11 @@ protected function resolveActionMapping($handler) { if (!$filters) {return;} $_token = $this->handlerAdapter->getModule() . '_' . $this->handlerAdapter->getController() . '_' . $this->handlerAdapter->getAction(); foreach ($filters as $_filter) { - if (isset($_filter['class']) && !empty($_filter['pattern'])) { - preg_match('/^' . str_replace('*', '\w*', $_filter['pattern']) . '$/i', $_token, $_matchs); - if ($_matchs) - $handler->registerEventListener('doAction', - WindFactory::createInstance(Wind::import($_filter['class']))); + if (!isset($_filter['class'])) + continue; + if (!$_filter['pattern'] || preg_match('/^' . str_replace('*', '\w*', $_filter['pattern']) . '$/i', $_token)) { + $handler->registerEventListener('doAction', + WindFactory::createInstance(Wind::import($_filter['class']))); } } } @@ -260,4 +239,25 @@ protected function sendErrorMessage($exception) { $forward->setVars($exception->getCode(), 'errorCode'); $this->_getDispatcher()->dispatch($forward, $this->handlerAdapter, false); } + + /** + * @return WindHttpRequest $request + */ + public function getRequest() { + return $this->request; + } + + /** + * @return WindHttpResponse $response + */ + public function getResponse() { + return $this->response; + } + + /** + * @return WindFactory $windFactory + */ + public function getWindFactory() { + return $this->windFactory; + } } \ No newline at end of file From eb6624a9f4c072b696b3e76203c187015b459781 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 08:28:17 +0000 Subject: [PATCH 0525/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2597 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindSimpleController.php | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/wind/web/WindSimpleController.php b/wind/web/WindSimpleController.php index fb385f78..7f355ddb 100644 --- a/wind/web/WindSimpleController.php +++ b/wind/web/WindSimpleController.php @@ -45,13 +45,29 @@ public function doAction($handlerAdapter) { protected function resolveActionFilter($__filters) { $chain = WindFactory::createInstance('WindHandlerInterceptorChain'); foreach ((array) $__filters as $__filter) { - if (isset($__filter['expression']) && !empty($__filter['expression'])) { + if (!empty($__filter['expression'])) { + $__v1 = ''; + list($__p, $__o, $__v2) = explode('#', str_replace(array('=='), '#==#', $__filter['expression'])); + $__p = explode('.', $__p); + switch (strtolower($__p[0])) { + case 'forward': + unset($__p[0]); + $__v1 = call_user_func_array(array($this->getForward(), 'getVars'), $__p); + break; + case 'g': + unset($__p[0]); + $__v1 = call_user_func_array(array(Wind::getApp(), 'getGlobal'), $__p); + break; + case 'requset': + unset($__p[0]); + $__v1 = $this->getInput($__p[2], $__p[1]); + break; + default: + isset($__p[1]) && $__v1 = $this->getInput($__p[1], $__p[0]); + break; + } - if (!@eval('return ' . $__filter['expression'] . ';')) - continue; - /*list($p, $v) = explode('=', $__filter['expression'] . '='); - if ($this->getRequest()->getRequest($p) != $v) - continue;*/ + continue; } $__args = array($this->getForward(), $this->getErrorMessage()); if (isset($__filter['args'])) @@ -79,7 +95,6 @@ protected function afterAction($handlerAdapter) {} * @return */ protected function forwardAction($action = 'run', $args = array(), $isRedirect = false) { - //$this->getForward()->forwardAnotherAction($action, $controller, $args, $isRedirect); $this->getForward()->forwardAction($action, $args, $isRedirect); } From 1c55c5176a9c0ff37d510d9fb8cd874a3d573fbe Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 8 Sep 2011 09:15:08 +0000 Subject: [PATCH 0526/1065] =?UTF-8?q?session=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2598 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/AbstractWindSession.php | 151 ++++--- wind/http/session/WindDbSession.php | 42 -- wind/http/session/WindSession.php | 465 +++++----------------- 3 files changed, 180 insertions(+), 478 deletions(-) delete mode 100644 wind/http/session/WindDbSession.php diff --git a/wind/http/session/AbstractWindSession.php b/wind/http/session/AbstractWindSession.php index dcffb59b..9847639b 100644 --- a/wind/http/session/AbstractWindSession.php +++ b/wind/http/session/AbstractWindSession.php @@ -1,97 +1,116 @@ - 2010-12-17 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - + * @author Qian Su * @version $Id: AbstractWindUserSession.php 1704 2011-03-08 10:40:17Z weihu $ * @package - */ -abstract class AbstractWindSession extends WindModule { - protected $handler = null; - + */ +abstract class AbstractWindSession extends WindModule { + + protected $handler = null; + + /** + * 构造函数 + * @param AbstractWindCache $handler + */ + public function __construct(AbstractWindCache $handler = null) { + $handler && $this->setHandler($handler); + register_shutdown_function('session_write_close'); + } + /** * 打开会话存储机制 + * 在session_start()执行的时候执行。 + * * @param string $savePath * @param string $sessionName * @return bollean - */ - public abstract function open($savePath, $sessionName); + */ + public abstract function open($savePath, $sessionName); + /** * 关闭会话存储存储机制 + * 在页面执行完的时候执行 + * * @return bollean - */ - public abstract function close(); + */ + public abstract function close(); + /** - * 将sessionID对应的数据写到存储 + * 将sessionID对应的数据写到存储 + * 在需要写入session数据的时候执行 + * * @param string $name * @param mixed $value - */ - public abstract function write($sessId, $sessData); + */ + public abstract function write($sessId, $sessData); + /** - * 从存储中装载session数据 + * 从存储中装载session数据 + * 在执行session_start的时候执行在open之后 + * * @param mixed $sessid - */ - public abstract function read($sessId); + */ + public abstract function read($sessId); + /** - * 对存储系统中的数据进行垃圾收集 + * 对存储系统中的数据进行垃圾收集 + * 在执行session过期策略的时候执行,注意,session的过期并不是时时的,需要根据php.ini中的配置项: + * session.gc_probability = 1 + * session.gc_divisor = 1000 + * 执行的概率是gc_probability/gc_divisor . + * session.gc_maxlifetime = 1440 设置的session的过期时间 + * * @param mixed $maxlifetime - */ - public abstract function gc($maxlifetime); + */ + public abstract function gc($maxlifetime); + /** - * 破坏与指定的会话ID相关联的数据 + * 破坏与指定的会话ID相关联的数据 + * 在执行session_destroy的时候执行。 + * * @param mixed $name - */ - public abstract function destroy($sessId); - + */ + public abstract function destroy($sessId); + /** - * 数据序列化 - * @param mixed $sessData - * @return string - */ - protected function serializeData($sessData) { - return (is_array($sessData) || is_object($sessData)) ? serialize($sessData) : $sessData; - } - + * 开启session + * + * @param string $id + */ + public function start() { + $this->getHandler() && $this->setSessionHandler(); + if ('' === session_id() && '1' !== ini_get('session.auto_start')) { + session_start(); + } + } + /** - * 数据反序列化 - * @param string $sessData - * @return mixed - */ - protected function unserializeData($sessData) { - $data = unserialize($sessData); - return (is_array($data) || is_object($data)) ? $data : $sessData; - } - - /** - * 设置监听接口 - */ - public function setSessionHandler(){ - session_set_save_handler(array($this,'open'),array($this,'close'),array($this,'read'),array($this,'write'),array($this,'destroy'),array($this,'gc')); - } - - + * 设置session的回调函数 + */ + public function setSessionHandler() { + session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, + 'write'), array($this, 'destroy'), array($this, 'gc')); + } + /** - * 设置链接对象 + * 设置链接对象 + * * @param AbstractWindCache $handler - */ - public function setHandler($handler) { - if ($handler instanceof AbstractWindCache) - $this->handler = $handler; - } - + */ + public function setHandler($handler) { + if ($handler instanceof AbstractWindCache) $this->handler = $handler; + } + /** - * 获得链接对象 + * 获得链接对象 + * * @return AbstractWindCache - */ - public function getHandler() { - return $this->_getHandler(); - } + */ + public function getHandler() { + return $this->_getHandler(); + } } diff --git a/wind/http/session/WindDbSession.php b/wind/http/session/WindDbSession.php deleted file mode 100644 index eeed85e2..00000000 --- a/wind/http/session/WindDbSession.php +++ /dev/null @@ -1,42 +0,0 @@ - 2011-3-8 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ -Wind::import('WIND:http.session.AbstractWindUserSession'); -/** - * 数据库会话存储机制,可以实现统一登陆 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindDbSession extends AbstractWindUserSession { - - public static function open($savePath, $sessionName){ - return true; - } - - public static function close(){ - return true; - } - - public static function write($name,$value){ - - } - - public static function read($name){ - - } - - public static function gc($maxlifetime){ - - } - - public static function destroy($name){ - - } -} - diff --git a/wind/http/session/WindSession.php b/wind/http/session/WindSession.php index 1a22ebbd..3b044aa8 100644 --- a/wind/http/session/WindSession.php +++ b/wind/http/session/WindSession.php @@ -1,370 +1,95 @@ - 2010-12-17 - * @link http://www.phpwind.com - * @copyright Copyright © 2003-2110 phpwind.com - * @license - */ - -/** - * Session会话操作 - * the last known user to change this file in the repository <$LastChangedBy$> - * @author Qian Su - * @version $Id$ - * @package - */ -class WindSession implements IteratorAggregate, ArrayAccess, Countable { - /** - * @var boolean 是否自动启动session - */ - public $autostart = false; - /** - * @var int 没有启用cookie传用sessionid - */ - const COOKIE_MODE_NONE = 1; - /** - * @var int 仅仅启用cookiew传递sessionid - */ - const COOKIE_MODE_ONLY = 2; - /** - * @var int 启用cookie传用sessionid - */ - const COOKIE_MODE_ALLOW = 3; - - /** - * @var string 以files格式将session在服务端的保存 - */ - const SESSION_SAVE_FILES = 'files'; - /** - * @var string 以user(用户自定义)格式将session在服务端的保存 - */ - const SESSION_SAVE_USER = 'user'; - - /** - * @var array $read 只读session - */ - public static $read = array(); - /** - * @var array $write 只写session - */ - public static $write = array(); - - public function __construct($autostart = false) { - $this->autostart = $autostart; - } - - public function start() { - if (!$this->isStart() && !$this->getAutoStart()) { - $this->autostart ? $this->setAutoStart(1) : session_start(); - } - } - - /** - * session是否开启 - * @return boolean - */ - public function isStart() { - return '' !== $this->getSessionId(); - } - - /** - * 写入和结束session - */ - public function close() { - if ($this->isStart()) { - session_write_close(); - } - } - - /** - * 获取session - * @param string $name session名称 - * @return string - */ - public function get($name) { - return isset($_SESSION[$name]) ? $_SESSION[$name] : null; - } - - /** - * 设置一个会话 - * @param string $name session名称 - * @param string $value $name对应的值 - * @return string - */ - public function set($name, $value) { - if (empty($name) && empty($value)) { - return false; - } - $_SESSION[$name] = $value; - return true; - } - - /** - * 删除一个会话 - * @param string $name session名称 - * @return string - */ - public function remove($name) { - if (isset($_SESSION[$name])) { - $sessionValue = $_SESSION[$name]; - unset($_SESSION[$name]); - return $sessionValue; - } - return null; - } - - /** - * 判断一个session是否存在 - * @param string $name session名称 - * @return string - */ - public function exist($name) { - return isset($_SESSION[$name]); - } - - /** - * 销毁当前所有会话 - * @return string - */ - public function destroy() { - if (($name = $this->getSessionName()) && isset($_COOKIE[$name])) { - setcookie($name, '', time() - 3600); - } - session_unset(); - session_destroy(); - return true; - } - - /** - * 获取当前会话名称 - * @return string - */ - public function getSessionName() { - return session_name(); - } - /** - * 设置当前会话名称 - * @return string $name - */ - public function setSessionName($name) { - return session_name($name); - } - - /** - * 获取当前会话 id - * @return string - */ - public function getSessionId() { - return session_id(); - } - - /** - * 设置当前会话 id - * @param string $id - * @return string - */ - public function setSessionId($id) { - return session_id($id); - } - - /** - * 如果session在服务端的以files方式保存,获取session在服务器端存储路径 - * @return string - */ - public function getSavePath() { - return session_save_path(); - } - - /** - * 如果session在服务端的以files方式保存,设置session在服务器端存储路径 - * @param string $path - * @return string - */ - public function setSavePath($path) { - if (is_dir($path)) { - session_save_path($path); - return true; - } - return false; - } - - /** - * 获取session在服务端的保存方式 - * @return string - */ - public function getSessionSaveMode() { - return session_module_name(); - } - - /** - * 定义session在服务端的保存方式,files意为把sesion保存到一个临时文件里,如果我们想自定义别的方式保存(比如用数据库),则需要把该项设置为user; - * @param unknown_type $mode - * @return string - */ - public function setSessionSaveMode($mode = self::SESSION_SAVE_FILES) { - return session_module_name($mode); - } - - /** - * 取得session相关的cookie参数 - * @return array - */ - public function getCookieParams() { - return session_get_cookie_params(); - } - - /** - * 设置session相关的cookie参数 - * @param array $cookie - * @return string - */ - public function setCookieParams($cookie = array()) { - extract($this->getCookieParams()); - extract($cookie); - if (isset($httponly)) { - session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); - } else { - session_set_cookie_params($lifetime, $path, $domain, $secure); - } - return true; - } - - /** - * 取得cookie传递sessionid的模式 - * @return number - */ - public function getCookieMode() { - if ('0' === ini_get('session.use_cookies')) { - self::COOKIE_MODE_NONE; - } else if ('0' === ini_get('session.use_only_cookies')) { - return self::COOKIE_MODE_ALLOW; - } else { - return self::COOKIE_MODE_ONLY; - } - return false; - } - - /** - * 设置cookie传递sessionid的模式 - * @param int $mode - * @return string - */ - public function setCookieMode($mode = self::COOKIE_MODE_ONLY) { - if (self::COOKIE_MODE_NONE === $mode) { - ini_set('session.use_cookies', '0'); - } else if (self::COOKIE_MODE_ALLOW === $mode) { - ini_set('session.use_cookies', '1'); - ini_set('session.use_only_cookies', '0'); - } else if (self::COOKIE_MODE_ONLY === $mode) { - ini_set('session.use_cookies', '1'); - ini_set('session.use_only_cookies', '1'); - } else { - return false; - } - return true; - } - - /** - * 获取session进行清理的概率 - * @return number - */ - public function getGCProbability() { - return (int) ini_get('session.gc_probability'); - } - - /** - * 设置session进行清理的概率 - * @param int $probability 概率数 - * @return string|string - */ - public function setGCProbability($probability) { - if (!is_int($probability) || 0 >= $probability || 100 <= $probability) { - return false; - } - ini_set('session.gc_probability', $probability); - ini_set('session.gc_divisor', '100'); - return true; - } - - /** - * 是否允许sessionid通过url参数传递 - * @return boolean - */ - public function getTransSessionID() { - return '1' === ini_get('session.use_trans_sid'); - } - - /** - * 设置是否允许sessionid通过url参数传递 - * @param int $ifTrans - * @return string - */ - public function setTransSessionID($ifTrans = 0) { - return ini_set('session.use_trans_sid', $ifTrans ? '1' : '0'); - } - - /** - * 获取session存活时间 - * @return number - */ - public function getSessionLifeTime() { - return (int) ini_get('session.gc_maxlifetime'); - } - - /** - * 设置session存活时间 - * @param int $time - * @return number - */ - public function setSessionLifeTime($time = 0) { - return (int) ini_set('session.gc_maxlifetime', (int) $time); - } - - /** - * 是否自动启动session - * @return boolean - */ - public function getAutoStart() { - return '1' === ini_get('session.auto_start'); - } - - /** - * 设置自动启动 - * @param boolean $autostart 是否自动启动 - * @return string - */ - public function setAutoStart($autostart) { - return ini_set('session.auto_start', $autostart ? '1' : '0'); - } - - /** - * 获取当前session的文件名 - * @return string - */ - public function getCurrentSessionFileName(){ - return $this->getSavePath().'/sess_'.$this->getSessionId(); - } - - public function offsetExists($offset) { - $this->exist($offset); - } - - public function offsetSet($offset, $value) { - $this->set($offset, $value); - } - - public function offsetGet($offset) { - $this->get($offset); - } - public function offsetUnset($offset) { - $this->remove($offset); - } - - public function getIterator($name = null) { - return new ArrayObject(($name && isset($_SESSION[$name])) ? $_SESSION[$name] : $_SESSION); - } - - public function count() { - return count($_SESSION); - } -} \ No newline at end of file + + * 'WindSession' => array( + * 'path' => 'WIND:http.session.WindSession', + * 'scope' => 'singleton', + * 'properties' => array( + * 'handler' => array( + * 'ref' => 'sessionSave',//用户配置的缓存类型--缓存组件的配置格式参照缓存配置文件 + * ), + * ), + * ) + * + * 【使用】调用时使用: + *
+ * $session = $this->getSystemFactory()->getInstance('WindSession');
+ * $session->start();
+ * 
+ * $_SESSION['name'] = 'test';
+ * echo $_SESSION['name'];
+ * 
+ * 【使用原生】: + * 如果用户不需要配置自己其他存储方式的session,则不许要修改任何调用,只要在WindSession的配置中将properties配置项去掉即可。如下: + *
+ * 'WindSession' => array(
+ *		'path' => 'WIND:http.session.WindSession',
+ *		'scope' => 'singleton',
+ *  )
+ * 
+ * 【扩展】 + * 如果用户实现了自己的实现,需要调用自己的实现,则只需要更改path的值指定到自己的实现,即可。 + * + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia.xu + * @version $Id$ + * @package + */ +class WindSession extends AbstractWindSession { + + /* (non-PHPdoc) + * @see AbstractWindSession::open() + */ + public function open($savePath, $sessionName) { + $handler = $this->getHandler(); + $lifeTime = get_cfg_var("session.gc_maxlifetime"); + if (($expire = $handler->getExpire()) == '0') { + $lifeTime = get_cfg_var("session.gc_maxlifetime"); + $handler->setExpire($lifeTime ? $lifeTime : 0); + } else { + ini_set("session.gc_maxlifetime", $expire); + } + return true; + } + + /* (non-PHPdoc) + * @see AbstractWindSession::close() + */ + public function close() { + session_write_close(); + return true; + } + + /* (non-PHPdoc) + * @see AbstractWindSession::write() + */ + public function write($sessID, $sessData) { + return $this->getHandler()->set($sessID, $sessData); + } + + /* (non-PHPdoc) + * @see AbstractWindSession::read() + */ + public function read($sessID) { + return $this->getHandler()->get($sessID); + } + + /* (non-PHPdoc) + * @see AbstractWindSession::gc() + */ + public function gc($maxlifetime) { + return $this->getHandler()->clear(true); + } + + /* (non-PHPdoc) + * @see AbstractWindSession::destroy() + */ + public function destroy($sessID) { + return $this->getHandler()->delete($sessID); + } +} + From b6222a16875062089f2aa2f0e9a7fb394279fd54 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 8 Sep 2011 09:16:54 +0000 Subject: [PATCH 0527/1065] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E6=B8=85=E6=A5=9A=E7=BC=93=E5=AD=98=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B8=85=E6=A5=9A=E8=BF=87=E6=9C=9F=E7=AD=96?= =?UTF-8?q?=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2599 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/cache/strategy/WindDbCache.php | 33 +++++++++++++++------------ wind/cache/strategy/WindFileCache.php | 4 ++-- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/wind/cache/strategy/WindDbCache.php b/wind/cache/strategy/WindDbCache.php index 2c4485a8..2e254219 100644 --- a/wind/cache/strategy/WindDbCache.php +++ b/wind/cache/strategy/WindDbCache.php @@ -50,15 +50,15 @@ public function __construct(WindConnection $connection = null, $config = array() $config && $this->setConfig($config); } - /* - * @see AbstractWindCache#setValue() + /* (non-PHPdoc) + * @see AbstractWindCache::setValue() */ protected function setValue($key, $value, $expire = 0) { return $this->store($key, $value, $expire); } - /* - * @see AbstractWindCache#getValue() + /* (non-PHPdoc) + * @see AbstractWindCache::getValue() */ protected function getValue($key) { $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)'; @@ -66,8 +66,8 @@ protected function getValue($key) { return $data[$this->valueField]; } - /* - * @see AbstractWindCache#batchFetch() + /* (non-PHPdoc) + * @see AbstractWindCache::batchFetch() */ public function batchGet(array $keys) { foreach ($keys as $key => $value) { @@ -83,16 +83,16 @@ public function batchGet(array $keys) { return $result; } - /* - * @see AbstractWindCache#deleteValue() + /* (non-PHPdoc) + * @see AbstractWindCache::deleteValue() */ protected function deleteValue($key) { $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` = ? '; return $this->getConnection()->createStatement($sql)->update(array($key)); } - /* - * @see AbstractWindCache#batchDelete() + /* (non-PHPdoc) + * @see AbstractWindCache::batchDelete() */ public function batchDelete(array $keys) { foreach ($keys as $key => $value) { @@ -103,11 +103,16 @@ public function batchDelete(array $keys) { return $this->getConnection()->execute($sql); } - /* - * @see AbstractWindCache#clear() + /* (non-PHPdoc) + * @see AbstractWindCache::clear() + * 删除过期数据或是全部删除 */ - public function clear() { - return $this->getConnection()->execute('DELETE FROM ' . $this->getTableName()); + public function clear($expireOnly = false) { + $sql = sprintf('DELETE FROM `%s`', $this->getTableName()); + if ($expireOnly) { + $sql = sprintf('DELETE FROM `%s` WHERE `%s` < ', $this->getTableName(), $this->expireField) . $this->getConnection()->quote(time()); + } + return $this->getConnection()->execute($sql); } /* (non-PHPdoc) diff --git a/wind/cache/strategy/WindFileCache.php b/wind/cache/strategy/WindFileCache.php index 5512f0c3..191c932b 100644 --- a/wind/cache/strategy/WindFileCache.php +++ b/wind/cache/strategy/WindFileCache.php @@ -59,8 +59,8 @@ protected function deleteValue($key) { /* (non-PHPdoc) * @see AbstractWindCache::clear() */ - public function clear() { - return WindFile::clearDir($this->getCacheDir()); + public function clear($expireOnly = false) { + return WindFile::clearDir($this->getCacheDir(), $expireOnly); } /** From 521d5ffb8b2e5f9553e1ecff0aa50c03b69d8f9c Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Thu, 8 Sep 2011 12:20:53 +0000 Subject: [PATCH 0528/1065] =?UTF-8?q?session=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2600 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/AbstractWindSession.php | 116 ---------------------- 1 file changed, 116 deletions(-) delete mode 100644 wind/http/session/AbstractWindSession.php diff --git a/wind/http/session/AbstractWindSession.php b/wind/http/session/AbstractWindSession.php deleted file mode 100644 index 9847639b..00000000 --- a/wind/http/session/AbstractWindSession.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @author Qian Su - * @version $Id: AbstractWindUserSession.php 1704 2011-03-08 10:40:17Z weihu $ - * @package - */ -abstract class AbstractWindSession extends WindModule { - - protected $handler = null; - - /** - * 构造函数 - * @param AbstractWindCache $handler - */ - public function __construct(AbstractWindCache $handler = null) { - $handler && $this->setHandler($handler); - register_shutdown_function('session_write_close'); - } - - /** - * 打开会话存储机制 - * 在session_start()执行的时候执行。 - * - * @param string $savePath - * @param string $sessionName - * @return bollean - */ - public abstract function open($savePath, $sessionName); - - /** - * 关闭会话存储存储机制 - * 在页面执行完的时候执行 - * - * @return bollean - */ - public abstract function close(); - - /** - * 将sessionID对应的数据写到存储 - * 在需要写入session数据的时候执行 - * - * @param string $name - * @param mixed $value - */ - public abstract function write($sessId, $sessData); - - /** - * 从存储中装载session数据 - * 在执行session_start的时候执行在open之后 - * - * @param mixed $sessid - */ - public abstract function read($sessId); - - /** - * 对存储系统中的数据进行垃圾收集 - * 在执行session过期策略的时候执行,注意,session的过期并不是时时的,需要根据php.ini中的配置项: - * session.gc_probability = 1 - * session.gc_divisor = 1000 - * 执行的概率是gc_probability/gc_divisor . - * session.gc_maxlifetime = 1440 设置的session的过期时间 - * - * @param mixed $maxlifetime - */ - public abstract function gc($maxlifetime); - - /** - * 破坏与指定的会话ID相关联的数据 - * 在执行session_destroy的时候执行。 - * - * @param mixed $name - */ - public abstract function destroy($sessId); - - /** - * 开启session - * - * @param string $id - */ - public function start() { - $this->getHandler() && $this->setSessionHandler(); - if ('' === session_id() && '1' !== ini_get('session.auto_start')) { - session_start(); - } - } - - /** - * 设置session的回调函数 - */ - public function setSessionHandler() { - session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, - 'write'), array($this, 'destroy'), array($this, 'gc')); - } - - /** - * 设置链接对象 - * - * @param AbstractWindCache $handler - */ - public function setHandler($handler) { - if ($handler instanceof AbstractWindCache) $this->handler = $handler; - } - - /** - * 获得链接对象 - * - * @return AbstractWindCache - */ - public function getHandler() { - return $this->_getHandler(); - } -} - From f8002b8307b694a8e0c82c7a48dcb407b93b9b40 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 12:54:48 +0000 Subject: [PATCH 0529/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2601 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/base/WindFactory.php | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/wind/base/WindFactory.php b/wind/base/WindFactory.php index 61e6c1f6..a4c56888 100644 --- a/wind/base/WindFactory.php +++ b/wind/base/WindFactory.php @@ -15,6 +15,7 @@ class WindFactory implements IWindFactory { protected $classDefinitions = array(); protected $instances = array(); protected $prototype = array(); + protected $destories = array(); /** * 初始化抽象工厂类 @@ -40,8 +41,7 @@ public function getInstance($alias, $args = array()) { $instance = $this->instances[$alias]; } else { if (!$definition) - throw new WindException( - '[factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); + throw new WindException('[factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); if (isset($definition['constructor-arg'])) foreach ((array) $definition['constructor-arg'] as $_var) { @@ -62,7 +62,8 @@ public function getInstance($alias, $args = array()) { !isset($definition['scope']) && $definition['scope'] = 'application'; $this->setScope($alias, $definition['scope'], $instance); } - + if (isset($definition['destroy'])) + $this->setDestroy($definition['destroy'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); return $instance; @@ -95,8 +96,7 @@ static public function createInstance($className, $args = array()) { return call_user_func_array(array($reflection, 'newInstance'), (array) $args); } } catch (Exception $e) { - throw new WindException( - '[base.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), + throw new WindException('[base.WindFactory] create instance \'' . $className . '\' fail.' . $e->getMessage(), WindException::ERROR_CLASS_NOT_EXIST); } } @@ -119,8 +119,7 @@ public function addClassDefinitions($alias, $classDefinition) { if (!isset($this->classDefinitions[$alias])) $this->classDefinitions[$alias] = $classDefinition; } else - throw new WindException( - '[base.WindFactory.addClassDefinitions] class alias is empty.', + throw new WindException('[base.WindFactory.addClassDefinitions] class alias is empty.', WindException::ERROR_PARAMETER_TYPE_ERROR); } @@ -138,8 +137,7 @@ public function loadClassDefinitions($classDefinitions, $merge = true) { $this->classDefinitions[$alias] = $definition; continue; } - $this->classDefinitions[$alias] = WindUtility::mergeArray( - $this->classDefinitions[$alias], $definition); + $this->classDefinitions[$alias] = WindUtility::mergeArray($this->classDefinitions[$alias], $definition); unset($this->instances[$alias], $this->prototype[$alias]); } } @@ -157,6 +155,24 @@ public function checkAlias($alias) { return false; } + /** + * @return boolean + */ + public function executeDestroyMethod() { + foreach ($this->destories as $call) { + call_user_func_array($call); + } + } + + /** + * @param string $destroy + * @param string $instance + * @return + */ + protected function setDestroy($destroy, $instance) { + $this->destories[] = array($instance, $destroy); + } + /** * @param string $alias * @param string $scope @@ -189,8 +205,7 @@ protected function resolveConfig($config, $alias, $instance) { if (isset($config['resource'])) { $_configPath = Wind::getRealPath($config['resource'], true); $configParser = $this->getInstance('configParser'); - $config = $configParser->parse($_configPath, $alias, true, - Wind::getApp()->getComponent('windCache')); + $config = $configParser->parse($_configPath, $alias, true, Wind::getApp()->getComponent('windCache')); } if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config); From ab653810944db0772fb51fcee0972c3252aebbfd Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 12:55:06 +0000 Subject: [PATCH 0530/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2602 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/db/WindConnectionManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/db/WindConnectionManager.php b/wind/db/WindConnectionManager.php index 43e457df..315b7892 100644 --- a/wind/db/WindConnectionManager.php +++ b/wind/db/WindConnectionManager.php @@ -131,7 +131,7 @@ private function _resolveCurrentDb($_c) { if (!$this->forceMaster && !empty($_c['_s'])) { $_count = count($_c['_s']); if ($_count > 1) - $this->except['_current'] = $_c['_s'][rand(0, $_count - 1)]; + $this->except['_current'] = $_c['_s'][mt_rand(0, $_count - 1)]; else $this->except['_current'] = $_c['_s'][0]; break; From 6c55cdb6d5746366deaf0d22b05973faa4ffed97 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 12:55:18 +0000 Subject: [PATCH 0531/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2603 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/utility/WindUtility.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/utility/WindUtility.php b/wind/utility/WindUtility.php index abe0382c..08f6841a 100644 --- a/wind/utility/WindUtility.php +++ b/wind/utility/WindUtility.php @@ -22,7 +22,7 @@ public static function evalExpression($v1, $v2, $expression) { return $v1 == $v2; case '===': return $v1 === $v2; - + } } @@ -67,7 +67,7 @@ public static function lcfirst($str) { public static function generateRandStr($length) { $randstr = ""; for ($i = 0; $i < (int) $length; $i++) { - $randnum = rand(0, 61); + $randnum = mt_rand(0, 61); if ($randnum < 10) { $randstr .= chr($randnum + 48); } else if ($randnum < 36) { From a2f359f358ffa242495c5cfe0694d74a90eabb7d Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 12:56:21 +0000 Subject: [PATCH 0532/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2604 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wind/components_config.php b/wind/components_config.php index 2d1e6af5..8c12881c 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -14,6 +14,7 @@ 'windLogger' => array( 'path' => 'WIND:log.WindLogger', 'scope' => 'singleton', + 'destroy' => 'flush', 'constructor-arg' => array( '0' => array( 'value' => 'data.log', @@ -99,7 +100,7 @@ 'path' => 'WIND:cache.strategy.WindFileCache', 'scope' => 'singleton', 'config' => array( - 'dir' => 'data.config', + 'dir' => 'data.caches', 'suffix' => 'php', 'expires' => '0', ), From d31be15200e260de6c627e82b47ec0b969af91b3 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 12:56:41 +0000 Subject: [PATCH 0533/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2605 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 0302af6d..37a4f58d 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -85,8 +85,6 @@ public static function getApp() { * @return */ public static function resetApp() { - if (WIND_DEBUG & 2) - self::getApp()->getComponent('windLogger')->flush(); array_pop(self::$_currentApp); self::$_currentAppName = end(self::$_currentApp); } From 1faeecead0372ddd06c71b4629d765577dfd159a Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 13:47:54 +0000 Subject: [PATCH 0534/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2606 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/cache/AbstractWindCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/cache/AbstractWindCache.php b/wind/cache/AbstractWindCache.php index fc82e65e..65e59590 100644 --- a/wind/cache/AbstractWindCache.php +++ b/wind/cache/AbstractWindCache.php @@ -101,7 +101,7 @@ public function set($key, $value, $expires = 0, AbstractWindCacheDependency $den } return $this->setValue($this->buildSecurityKey($key), serialize($data), $data[self::EXPIRE]); } catch (Exception $e) { - throw new WindCacheException('Setting cache failed.' . $e->getMessage()); + throw new WindCacheException('[cache.AbstractWindCache.set]Setting cache failed.' . $e->getMessage()); } } From 16c6a79817a871e074566ed944ee7a11ff10742b Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 13:48:05 +0000 Subject: [PATCH 0535/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2607 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/cache/strategy/WindFileCache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/cache/strategy/WindFileCache.php b/wind/cache/strategy/WindFileCache.php index 191c932b..0e67b785 100644 --- a/wind/cache/strategy/WindFileCache.php +++ b/wind/cache/strategy/WindFileCache.php @@ -103,7 +103,7 @@ public function setCacheDir($dir) { $_dir = Wind::getRealPath($dir, false, true); if (!is_dir($_dir)) mkdir($_dir, 0777, true); - $this->cacheDir = $_dir; + $this->cacheDir = realpath($_dir); } /** From 79519546e236786b6e5e16801ff95f73cfcf8409 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 14:08:10 +0000 Subject: [PATCH 0536/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2608 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/base/WindFactory.php | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/wind/base/WindFactory.php b/wind/base/WindFactory.php index a4c56888..1d0b477d 100644 --- a/wind/base/WindFactory.php +++ b/wind/base/WindFactory.php @@ -37,6 +37,8 @@ public function getInstance($alias, $args = array()) { $definition = isset($this->classDefinitions[$alias]) ? $this->classDefinitions[$alias] : array(); if (isset($this->prototype[$alias])) { $instance = clone $this->prototype[$alias]; + if (isset($definition['destroy'])) + $this->destories[] = array($instance, $definition['destroy']); } elseif (isset($this->instances[$alias])) { $instance = $this->instances[$alias]; } else { @@ -60,10 +62,8 @@ public function getInstance($alias, $args = array()) { if (isset($definition['initMethod'])) $this->executeInitMethod($definition['initMethod'], $instance); !isset($definition['scope']) && $definition['scope'] = 'application'; - $this->setScope($alias, $definition['scope'], $instance); + $this->setScope($alias, $definition['scope'], $instance, $definition); } - if (isset($definition['destroy'])) - $this->setDestroy($definition['destroy'], $instance); if (isset($definition['proxy'])) $instance = $this->setProxyForClass($definition['proxy'], $instance); return $instance; @@ -159,37 +159,32 @@ public function checkAlias($alias) { * @return boolean */ public function executeDestroyMethod() { - foreach ($this->destories as $call) { - call_user_func_array($call); + try { + foreach ($this->destories as $call) + call_user_func_array($call, array()); + } catch (Exception $e) { + throw new WindException($e->getMessage()); } } - /** - * @param string $destroy - * @param string $instance - * @return - */ - protected function setDestroy($destroy, $instance) { - $this->destories[] = array($instance, $destroy); - } - /** * @param string $alias * @param string $scope * @param object $instance */ - protected function setScope($alias, $scope, $instance) { + protected function setScope($alias, $scope, $instance, $definition) { switch ($scope) { case 'prototype': $this->prototype[$alias] = clone $instance; break; case 'application': $this->instances[$alias] = $instance; - break; - default: + case 'singleton': $this->instances[$alias] = $instance; + default: + if (isset($definition['destroy'])) + $this->destories[$alias] = array($instance, $definition['destroy']); break; - } return true; } From ca4028886b865e739202c06295437b0502104690 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 14:08:23 +0000 Subject: [PATCH 0537/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2609 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/log/WindLogger.php | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/wind/log/WindLogger.php b/wind/log/WindLogger.php index b45775bb..d7dcf813 100644 --- a/wind/log/WindLogger.php +++ b/wind/log/WindLogger.php @@ -106,8 +106,7 @@ public function log($msg, $level = self::LEVEL_INFO, $type = 'wind.system', $flu else $this->_logCount >= $this->_autoFlush && $this->flush(); if ($level === self::LEVEL_PROFILE) - $message = $this->_build($msg, $level, $type, microtime(true), - $this->getMemoryUsage(false)); + $message = $this->_build($msg, $level, $type, microtime(true), $this->getMemoryUsage(false)); elseif ($level === self::LEVEL_DEBUG) $message = $this->_build($msg, $level, $type, microtime(true)); else @@ -130,9 +129,8 @@ public function flush() { return false; Wind::import('WIND:utility.WindFile'); $_l = $_logTypes = $_logLevels = array(); - $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', - self::LEVEL_DEBUG => 'debug', self::LEVEL_TRACE => 'trace', - self::LEVEL_PROFILE => 'profile'); + $_map = array(self::LEVEL_INFO => 'info', self::LEVEL_ERROR => 'error', self::LEVEL_DEBUG => 'debug', + self::LEVEL_TRACE => 'trace', self::LEVEL_PROFILE => 'profile'); foreach ($this->_logs as $key => $value) { $_l[] = $value[2]; @@ -223,8 +221,8 @@ private function _buildProfile($msg, $type, $timer, $mem) { if (strncasecmp($msg, self::TOKEN_BEGIN, strlen(self::TOKEN_BEGIN)) == 0) { $_token = substr($msg, strlen(self::TOKEN_BEGIN)); $_token = substr($_token, 0, strpos($_token, ':')); - $this->_profiles[] = array($_token, - substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, $timer, $mem); + $this->_profiles[] = array($_token, substr($msg, strpos($msg, ':', strlen(self::TOKEN_BEGIN)) + 1), $type, + $timer, $mem); } elseif (strncasecmp(self::TOKEN_END, $msg, strlen(self::TOKEN_END)) == 0) { $_msg = "PROFILE! Message:"; $_token = substr($msg, strlen(self::TOKEN_END)); @@ -352,27 +350,21 @@ private function _getFileName($suffix = '') { $_maxsize = ($this->_maxFileSize ? $this->_maxFileSize : 100) * 1024; $_logfile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '.txt'; if (is_file($_logfile) && $_maxsize <= filesize($_logfile)) { - $counter = 0; do { - $counter++; - $_newFile = $_logfile . '_' . date("Y_m_d_{$counter}"); + $_newFile = $this->_logDir . '/log' . ($suffix ? '_' . $suffix : '') . '_' . time() . '.txt'; } while (is_file($_newFile)); @rename($_logfile, $_newFile); } return $_logfile; } - public function __destruct() { - $this->flush(); - } - /** * @param string $logFile */ public function setLogDir($logDir) { if (!is_dir($logDir)) $logDir = Wind::getRealDir($logDir); - $this->_logDir = $logDir; + $this->_logDir = realpath($logDir); } /** From 834a84b87752dacaeaf372bf2d9dba20a385d745 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 14:08:49 +0000 Subject: [PATCH 0538/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2610 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/route/AbstractWindRoute.php | 4 ++-- wind/router/route/WindRewriteRoute.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wind/router/route/AbstractWindRoute.php b/wind/router/route/AbstractWindRoute.php index 9ea1749d..cbba5669 100644 --- a/wind/router/route/AbstractWindRoute.php +++ b/wind/router/route/AbstractWindRoute.php @@ -12,12 +12,12 @@ abstract class AbstractWindRoute extends WindHandlerInterceptor { /** * 根据匹配的路由规则,构建Url - * @param AbstractWindRouter + * @param AbstractWindRouter $router * @param string $action * @param array $args * @return string */ - abstract public function build($route, $action, $args = array()); + abstract public function build($router, $action, $args = array()); /** * 路由规则匹配方法,返回匹配到的参数列表 diff --git a/wind/router/route/WindRewriteRoute.php b/wind/router/route/WindRewriteRoute.php index 78b47b25..ddf78697 100644 --- a/wind/router/route/WindRewriteRoute.php +++ b/wind/router/route/WindRewriteRoute.php @@ -6,12 +6,12 @@ * @version $Id$ * @package */ -class WindRewriteRoute extends AbstractWindRoute { +class WindRewriteRoute extends AbstractWindRoute { /* (non-PHPdoc) * @see AbstractWindRoute::build() */ - public function build() { + public function build($router, $action, $args = array()) { // TODO Auto-generated method stub From 0d16e1f2b8c0e905b69b41bdaa5f82ae4c268421 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 14:09:15 +0000 Subject: [PATCH 0539/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2611 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/WindUrlRewriteRouter.php | 344 ------------------------- wind/router/route/WindRewriteRoute.php | 31 --- 2 files changed, 375 deletions(-) delete mode 100644 wind/router/WindUrlRewriteRouter.php delete mode 100644 wind/router/route/WindRewriteRoute.php diff --git a/wind/router/WindUrlRewriteRouter.php b/wind/router/WindUrlRewriteRouter.php deleted file mode 100644 index 9b5c215f..00000000 --- a/wind/router/WindUrlRewriteRouter.php +++ /dev/null @@ -1,344 +0,0 @@ - - * @author xiaoxiao - * @version 2011-8-12 xiaoxiao - */ -class WindUrlRewriteRouter extends AbstractWindRouter { - private $urlPatttern = ''; - private $keyValueSep = ''; - private $separator = ''; - private $suffix = ''; - private $isRewrite = 0; - private $keyPrefix = ''; - private $baseUrl = ''; - private $patterns = array(); - - /** - * 是否开启重写 - * - * @return boolean - */ - public function isRewrite() { - return $this->isRewrite == '1' || $this->isRewrite == 'true'; - } - - /* - * (non-PHPdoc) - * @see AbstractWindRouter::parse() - */ - public function parse() { - $this->isRewrite() && $this->parseUrl(); - $this->setModule($this->getUrlParamValue('module', $this->getModule())); - $this->setController($this->getUrlParamValue('controller', $this->getController())); - $this->setAction($this->getUrlParamValue('action', $this->getAction())); - } - - /** - * 解析Url - * - * 没有配置解析规则,直接返回 - * 获得则匹配RequestUri,根据用户的配置分隔符分割信息 - * 同时设置到超全局变量$_GET中 - */ - public function parseUrl() { - if (!$this->isRewrite()) - return; - $url = array(); - if ($this->getRequest()->getServer('SERVER_PROTOCOL')) { //http协议 - $pathInfo = $this->getRequest()->getServer('PATH_INFO'); - if ($pathInfo && !empty($pathInfo)) { - $url = rtrim($pathInfo, $this->suffix); - } elseif ('' != ($url = $this->getRequest()->getRequestUri())) { - $scriptName = $this->getRequest()->getScriptUrl(); - if (0 === strpos($url, $scriptName)) { - $url = substr($url, strlen($scriptName)); - } - $url = rtrim($url, $this->suffix); - } - $url = trim($url, '?/'); - $url && $params = $this->doParserUrl($url); - } else { // 命令行下 - $i = 0; - $args = $this->getRequest()->getServer('argv', array()); - while (isset($args[$i]) && isset($args[$i + 1])) { - $params[$args[$i]] = $args[$i + 1]; - $i += 2; - } - } - foreach ($params as $k => $v) { - !isset($_GET[$k]) && $_GET[$k] = $v; - } - } - - /** - * 构造返回Url地址 - * - * 将根据是否开启url重写来分别构造相对应的url - * - * @param string $action 执行的操作 - * @param string $controller 执行的controller - * @param array $params 附带的参数 - * @return string - */ - public function buildUrl($action = '', $controller = '', $params = array()) { - list($module, $controller, $action) = $this->resolveMvc($action, $controller); - $m = $this->getConfig('module', 'url-param'); - $c = $this->getConfig('controller', 'url-param'); - $a = $this->getConfig('action', 'url-param'); - $params = array_merge(array($m => $module, $c => $controller, $a => $action), $params); - return $this->isRewrite() ? $this->buildRewriteUrl($params) : $this->baseUrl . '/index.php?' . http_build_query( - $params, '', '&'); - } - - /** - * 解析module, controller, action - * 如果不存在该值,则采用配置的默认值 - * - * @param AbstractWindRouter $urlRouter - * @param string $action - * @param string $controller - * @return array - */ - private function resolveMvc($action, $controller) { - list($controller, $module) = WindHelper::resolveController($controller); - !$module && $module = $this->getConfig('module', 'default-value'); - !$controller && $controller = $this->getConfig('controller', 'default-value'); - !$action && $action = $this->getConfig('action', 'default-value'); - return array($module, $controller, $action); - } - - /** - * 构造重写的url - * @param string $m - * @param string $c - * @param string $action - * @param string $params - * @return string - */ - private function buildRewriteUrl($params) { - $url = $this->urlPatttern; - foreach ($this->patterns as $key => $value) { - if ('*' == $value[0]) { - $url = str_replace($value, $this->buildNomalKeys($params), $url); - } else { - $url = $this->buildVars($value, $params, $url); - } - } - return $this->baseUrl . '/' . $url . $this->suffix; - } - - /** - * 构建变量 不是* - * - * @param string $value - * @param array $params - * @param string $url - * @return string - */ - private function buildVars($value, &$params, $url) { - $keys = explode($this->keyValueSep, $value); - $values = array(); - foreach ($keys as $v) { - if (!isset($params[$v])) - continue; - $values[] = $params[$v]; - unset($params[$v]); - } - return str_replace($keys, $values, $url); - } - - /** - * 构建rewriteurl的参数部分 - * @param array $params - * @param string $parentKey - * @param boolean $first 只有第一级的变量才加前缀 - * @return string - */ - private function buildNomalKeys($params, $parentKey = '', $first = true) { - $tmp = array(); - foreach ($params as $k => $v) { - if (is_int($k) && $this->keyPrefix != null && $first) { - $k = urlencode($this->keyPrefix . $k); - } - if (!empty($parentKey)) - $k = $parentKey . '[' . $k . ']'; - if (is_array($v)) { - array_push($tmp, $this->buildNomalKeys($v, $k, false)); - } else { - array_push($tmp, $k . $this->keyValueSep . urlencode($v)); - } - } - return implode($this->separator, $tmp); - } - - /** - * 执行匹配 - * patterns中的匹配模式去匹配url中的信息 - * urlPatterns中可以根据需求将mca进行组合配置。 - * - * - htm - / - - - myvar_ - 1 - - * url-pattern中:*匹配表示其他的变量信息 - * 用户也可以将自己的其他信息添加到格式中比如m/c-a/tid/* - * suffix : url的后缀 - * separator: 变量分隔符 - * key-value-sep: key和value的分隔符,默认和separator一致 - * key-prefix: 数字索引的前缀 - * is-rewrite: 是否采用rewrite机制 - * - * 遍历url模式:采用separator配置的分隔符获得该模式数组 - * 如果模式是*,则代表该位置开始往后为为传递的变量信息 - * 如果模式不是*,则代表该位置为特殊模式。 - * 如果含有key-value-sep配置的分隔符: 则分别对url中相同key下的值和模式中的值分别做分割,对应的模式下获得的数组作为key,url中获得数组作为value - * 如果不含:则该值就作为Key,url对应位置上的值作为value - * - * @param string 待分析匹配的路径信息 - * @return array - */ - private function doParserUrl($url) { - if (!$url) - return array(); - if (is_string($url)) { - $url = explode($this->separator, trim($url, $this->separator)); - } - $vars = array(); - foreach ($this->patterns as $key => $value) { - if ('*' == $value[0]) - $this->parseNomalKeys($key, $url, $vars); - else { - if (!isset($url[$key])) - continue; - if (false === strrpos($value, $this->keyValueSep)) { - $vars[$value] = $url[$key]; - continue; - } - $keys = explode($this->keyValueSep, $value); - $values = explode($this->keyValueSep, $url[$key]); - foreach ($keys as $pos => $key) { - isset($values[$pos]) && $vars[$key] = $values[$pos]; - } - } - } - return $vars; - } - - /** - * 解析url普通参数 - * 如果separator和key-value-sep配置相同:则采用每两个元素为一对key-value的规则获得变量 - * 如果不相同:则将会以每个元素为key-value的组合,之间的分隔符以key-value-sep划分,如果没有该分隔符,则默认该值的索引为数字索引。 - * 如果为没有分隔符:则该值索引以数字索引给出,同时该数字索引将会根据用户是否配置key前缀key-prefix来给出key。 - * 如果有分隔符:则该值将会用分隔符分割获得的两个值来分别作为key和value. - * @param int $key - * @param array $urlParams - * @param array $params - */ - private function parseNomalKeys($key, $urlParams, &$params) { - $pos = 0; - while (isset($urlParams[$key])) { - if ($this->separator == $this->keyValueSep) { - if (isset($urlParams[$key + 1])) { - $this->parseKey($params, $urlParams[$key], urldecode($urlParams[$key + 1])); - $key += 2; - } - continue; - } - if (false === strrpos($urlParams[$key], $this->keyValueSep)) { - $params[$this->keyPrefix . $pos] = urldecode($urlParams[$key]); - $pos++; - } else { - list($k, $v) = explode($this->keyValueSep, $urlParams[$key], 2); - $this->parseKey($params, $k, urldecode($v)); - } - $key += 1; - } - } - - /** - * 解析url的parama信息中的key值 - * - * 如果key值不存在'[',']'字符,则该key为字符串,直接返回 - * 如果key值存在,并且'['和']'之前没有字符,则表示该key是将是一个数组,并且键值自增,返回array($key) - * 如果key值存在,并且'['和']'之前有字符,则表示该key是一个数组,并且'['和']'其中的字符是该数组中的键值,返回array(key值, 键值) - * - * //TODO 需要考虑多维数组的情况 - * @param string $key - * @return string|array 返回匹配的结果 - */ - private function parseKey(&$params, $key, $value) { - if (($pos = strpos($key, '[')) === false || ($pos2 = strpos($key, ']', $pos + 1)) === false) { - $params[$key] = $value; - return; - } - $name = substr($key, 0, $pos); - if ($pos2 === $pos + 1) { - $params[$name][] = $value; - return; - } else { - $key = substr($key, $pos + 1, $pos2 - $pos - 1); - $params[$name][$key] = $value; - return; - } - } - - /* - * (non-PHPdoc) - * @see WindModule::setConfig() - */ - public function setConfig($config) { - $usrConfig = $this->getSystemConfig()->getConfig('router', 'config'); - $usrConfig && $config = array_merge($config, $usrConfig); - parent::setConfig($config); - $this->urlPatttern = $this->getConfig('url-pattern'); - $this->separator = $this->getConfig('separator'); - $this->keyValueSep = $this->getConfig('key-value-sep'); - $this->keyValueSep == "" && $this->keyValueSep = $this->separator; - $this->suffix = '.' . trim($this->getConfig('suffix'), '.'); - $this->isRewrite = $this->getConfig('is-rewrite'); - $this->keyPrefix = $this->getConfig('key-prefix'); - $this->patterns = explode($this->separator, trim($this->urlPatttern, $this->separator)); - $this->baseUrl = rtrim($this->getRequest()->getBaseUrl(true), '/'); - if (!$this->isRewrite()) - $this->baseUrl = $this->baseUrl . $this->getRequest()->getScriptUrl(); - } - - /** - * 返回路由的配置信息 - * - * @param urlParam - * @param defaultValue - * @return string - */ - private function getUrlParamValue($type, $defaultValue = '') { - if ($_param = $this->getConfig($type, 'url-param')) { - $_defaultValue = $this->getConfig($type, 'default-value', $defaultValue); - $tmp = $this->getRequest()->getRequest($_param, $defaultValue); - return !$tmp ? $defaultValue : $tmp; - } - return $defaultValue; - } - - /* (non-PHPdoc) - * @see AbstractWindRouter::route() - */ - public function route() { - // TODO Auto-generated method stub - - } - - /* (non-PHPdoc) - * @see AbstractWindRouter::assemble() - */ - public function assemble($action, $args = array(), $route = null) { - // TODO Auto-generated method stub - } - -} diff --git a/wind/router/route/WindRewriteRoute.php b/wind/router/route/WindRewriteRoute.php deleted file mode 100644 index ddf78697..00000000 --- a/wind/router/route/WindRewriteRoute.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @author Qiong Wu - * @version $Id$ - * @package - */ -class WindRewriteRoute extends AbstractWindRoute { - - /* (non-PHPdoc) - * @see AbstractWindRoute::build() - */ - public function build($router, $action, $args = array()) { - // TODO Auto-generated method stub - - - } - - /* (non-PHPdoc) - * @see AbstractWindRoute::match() - */ - public function match() { - // TODO Auto-generated method stub - - - } - -} - -?> \ No newline at end of file From cdce78c04c377203f56e99788bab3f11e1078a63 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 14:10:30 +0000 Subject: [PATCH 0540/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2612 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/utility/WindFile.php | 12 +++--------- wind/utility/WindSecurity.php | 36 +++++++++++------------------------ 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/wind/utility/WindFile.php b/wind/utility/WindFile.php index 88bfd37a..e99b0bf2 100644 --- a/wind/utility/WindFile.php +++ b/wind/utility/WindFile.php @@ -141,9 +141,7 @@ public static function clearDir($dir, $ifexpiled = false) { */ public static function delFiles($path, $delDir = false, $level = 0) { $path = rtrim($path, DIRECTORY_SEPARATOR); - if (!$handler = opendir($path)) { - return false; - } + if (!$handler = opendir($path)) {return false;} while (false !== ($filename = readdir($handler))) { if ("." != $filename && ".." != $filename) { if (is_dir($path . DIRECTORY_SEPARATOR . $filename)) { @@ -192,9 +190,7 @@ public static function getDirectoryIterator($dir) { * @return string|number */ public static function getFileInfo($fileName) { - if (false === is_file($fileName)) { - return array(); - } + if (false === is_file($fileName)) {return array();} $fileInfo['name'] = substr(strrchr($fileName, DIRECTORY_SEPARATOR), 1); $fileInfo['path'] = $fileName; $fileInfo['size'] = filesize($fileName); @@ -217,9 +213,7 @@ public static function getFileInfo($fileName) { * @return string|multitype: */ public static function getDirectoryInfo($dir) { - if (false !== is_dir($dir)) { - return array(); - } + if (false !== is_dir($dir)) {return array();} return stat($dir); } diff --git a/wind/utility/WindSecurity.php b/wind/utility/WindSecurity.php index 2048283f..73326f0e 100644 --- a/wind/utility/WindSecurity.php +++ b/wind/utility/WindSecurity.php @@ -55,9 +55,8 @@ public static function stripTags($str, $allowTags = "") { * @return string */ public static function escapePath($fileName, $ifCheck = true) { - if (!self::_escapePath($fileName, $ifCheck)) { - throw new WindException('file name is illegal'); - } + if (!self::_escapePath($fileName, $ifCheck)) + throw new WindException('[utility.WindSecurity.escapePath] file name is illegal'); return $fileName; } @@ -68,8 +67,7 @@ public static function escapePath($fileName, $ifCheck = true) { */ public static function escapeDir($dir) { $dir = strtr($dir, - array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', - ';' => '')); + array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '')); return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $dir), '/'); } @@ -98,11 +96,9 @@ public static function escapeChar($value) { */ public static function escapeString($string) { $string = strtr($string, - array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', - "\r\n" => '', "\n" => '', "%3C" => '<', '<' => '<', "%3E" => '>', - '>' => '>', '"' => '"', "'" => ''')); - return preg_replace( - array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), + array("\0" => '', "%00" => '', "\t" => ' ', ' ' => '  ', "\r" => '', "\r\n" => '', "\n" => '', + "%3C" => '<', '<' => '<', "%3E" => '>', '>' => '>', '"' => '"', "'" => ''')); + return preg_replace(array('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', '/&(?!(#[0-9]+|[a-z]+);)/is'), array('', '&'), $string); } @@ -164,16 +160,10 @@ public static function addSlashesForOutput($str) { * @return string */ public static function addSlashes($value, $gpc = false, $df = false) { - if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable))) { - return $value; - } + if (!$value || (!is_array($value) && !is_string($value) && !($value instanceof Traversable))) {return $value;} if (is_string($value)) { - if (false === $gpc && true === $df) { - return self::addSlashesForOutput($value); - } - if (false === $df && true === $gpc) { - return self::addSlashesForInput($value); - } + if (false === $gpc && true === $df) {return self::addSlashesForOutput($value);} + if (false === $df && true === $gpc) {return self::addSlashesForInput($value);} return addslashes($value); } foreach ($value as $key => $_value) { @@ -256,9 +246,7 @@ public static function sqlSingle($array, $strip = true) { * @return string */ public static function sqlMulti($array, $strip = true) { - if (!is_array($array)) { - return ''; - } + if (!is_array($array)) {return '';} $str = ''; foreach ($array as $val) { if (!empty($val) && is_array($val)) { @@ -291,9 +279,7 @@ private static function _escapePath($fileName, $ifCheck = true) { $tmpname = strtolower($fileName); $tmparray = array('://' => '', "\0" => ''); $ifCheck && $tmparray['..'] = ''; - if (strtr($tmpname, $tmparray) != $tmpname) { - return false; - } + if (strtr($tmpname, $tmparray) != $tmpname) {return false;} return true; } From 16febff46776a2d47c13447f674b38b0fd40523c Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 14:26:19 +0000 Subject: [PATCH 0541/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2613 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wind/components_config.php b/wind/components_config.php index 8c12881c..feab60e3 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -17,7 +17,7 @@ 'destroy' => 'flush', 'constructor-arg' => array( '0' => array( - 'value' => 'data.log', + 'value' => 'DATA:log', ), '1' => array( 'value' => '0', @@ -100,7 +100,7 @@ 'path' => 'WIND:cache.strategy.WindFileCache', 'scope' => 'singleton', 'config' => array( - 'dir' => 'data.caches', + 'dir' => 'DATA:caches', 'suffix' => 'php', 'expires' => '0', ), From ba669cb0b6a2dfccd7e52334d9f37d2c250fb03f Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 16:44:01 +0000 Subject: [PATCH 0542/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2614 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/utility/WindUtility.php | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/wind/utility/WindUtility.php b/wind/utility/WindUtility.php index 08f6841a..62733cb5 100644 --- a/wind/utility/WindUtility.php +++ b/wind/utility/WindUtility.php @@ -9,6 +9,12 @@ */ class WindUtility { + public static function resolveExpression($expression) { + $operators = array('==', '!=', '<', '>', '<=', '>='); + $operatorsReplace = array('#==#', '#!=#', '#<#', '#>#', '#<=#', '#>=#'); + return explode('#', str_replace($operators, $operatorsReplace, $expression)); + } + /** * 执行简单的条件表达式 * @param string $v1 @@ -16,14 +22,24 @@ class WindUtility { * @param string $expression * @return */ - public static function evalExpression($v1, $v2, $expression) { - switch ($expression) { + public static function evalExpression($v1, $v2, $operator) { + switch ($operator) { case '==': return $v1 == $v2; - case '===': - return $v1 === $v2; - + case '!=': + return $v1 != $v2; + case '<': + return $v1 < $v2; + case '>': + return $v1 > $v2; + case '<=': + return $v1 <= $v2; + case '>=': + return $v1 >= $v2; + default: + return false; } + return false; } /** From da12255b0befb33ad5b04415f061d085848f51f0 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 16:44:11 +0000 Subject: [PATCH 0543/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2615 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindSimpleController.php | 67 ++++++++++++++++++------------- wind/web/WindWebApplication.php | 33 ++++++++++----- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/wind/web/WindSimpleController.php b/wind/web/WindSimpleController.php index 7f355ddb..c9552fd0 100644 --- a/wind/web/WindSimpleController.php +++ b/wind/web/WindSimpleController.php @@ -42,37 +42,48 @@ public function doAction($handlerAdapter) { /* (non-PHPdoc) * @see IWindController::resolveActionFilter($action) */ - protected function resolveActionFilter($__filters) { + protected function resolveActionFilter($filters) { + if (!$filters) {return;} + $_fitlers = array(); + if ($cache = Wind::getApp()->getComponent('windCache')) { + $_key = md5(serialize($filters)); + $_fitlers = $cache->get($_key); + } $chain = WindFactory::createInstance('WindHandlerInterceptorChain'); - foreach ((array) $__filters as $__filter) { - if (!empty($__filter['expression'])) { - $__v1 = ''; - list($__p, $__o, $__v2) = explode('#', str_replace(array('=='), '#==#', $__filter['expression'])); - $__p = explode('.', $__p); - switch (strtolower($__p[0])) { - case 'forward': - unset($__p[0]); - $__v1 = call_user_func_array(array($this->getForward(), 'getVars'), $__p); - break; - case 'g': - unset($__p[0]); - $__v1 = call_user_func_array(array(Wind::getApp(), 'getGlobal'), $__p); - break; - case 'requset': - unset($__p[0]); - $__v1 = $this->getInput($__p[2], $__p[1]); - break; - default: - isset($__p[1]) && $__v1 = $this->getInput($__p[1], $__p[0]); - break; + if (!$_fitlers) { + foreach ((array) $filters as $filter) { + if (empty($filter['class'])) { + if (!empty($filter['expression'])) { + $v1 = ''; + list($p, $o, $v2) = WindUtility::resolveExpression($filter['expression']); + $p = explode('.', $p); + switch (strtolower($p[0])) { + case 'forward': + $call = array($this->getForward(), 'getVars'); + case 'g': + $call = array(Wind::getApp(), 'getGlobal'); + case 'request': + $call = array($this->getRequest(), 'getRequest'); + default: + if (!isset($call)) + $call = array($this, 'getInput'); + else + unset($p[0]); + $v1 = call_user_func_array($call, $p); + break; + } + if (!WindUtility::evalExpression($v1, $v2, $o)) + continue; + } + $_fitlers[] = $filter['class']; } - - continue; } - $__args = array($this->getForward(), $this->getErrorMessage()); - if (isset($__filter['args'])) - $__args = $__args + (array) $__filter['args']; - $chain->addInterceptors(WindFactory::createInstance(Wind::import(@$__filter['class']), $__args)); + } + if (!$_fitlers) {return;} + $cache && $cache->set($_key, $_fitlers); + $args = array($this->getForward(), $this->getErrorMessage()); + foreach ((array) $_fitlers as $value) { + $chain->addInterceptors(WindFactory::createInstance(Wind::import($value), $args)); } $chain->getHandler()->handle(); } diff --git a/wind/web/WindWebApplication.php b/wind/web/WindWebApplication.php index c2579236..8799d843 100644 --- a/wind/web/WindWebApplication.php +++ b/wind/web/WindWebApplication.php @@ -56,6 +56,7 @@ public function run() { restore_error_handler(); restore_exception_handler(); $this->response->sendResponse(); + $this->windFactory->executeDestroyMethod(); Wind::resetApp(); } @@ -97,7 +98,8 @@ public function processRequest() { throw new WindActionException( '[web.WindWebApplication.processRequest] Your requested \'' . $handlerPath . '\' was not found on this server.', 404); - $this->resolveActionMapping($handler); + if ($filters = $this->getConfig('filters')) + $this->resolveActionMapping($filters, $handler); $this->doDispatch($handler->doAction($this->handlerAdapter)); } catch (WindActionException $e) { $this->sendErrorMessage($e); @@ -188,20 +190,31 @@ public function getComponent($componentName) { } /** + * @param array $filters * @param WindClassProxy $handler * @return */ - protected function resolveActionMapping($handler) { - $filters = $this->getConfig('filters', '', array()); - if (!$filters) {return;} + protected function resolveActionMapping($filters, $handler) { + /* @var $cache AbstractWindCache */ + $_filters = array(); + if ($cache = $this->getComponent('windCache')) { + $key = md5(serialize($filters)); + $_filters = $cache->get($key); + } $_token = $this->handlerAdapter->getModule() . '_' . $this->handlerAdapter->getController() . '_' . $this->handlerAdapter->getAction(); - foreach ($filters as $_filter) { - if (!isset($_filter['class'])) - continue; - if (!$_filter['pattern'] || preg_match('/^' . str_replace('*', '\w*', $_filter['pattern']) . '$/i', $_token)) { - $handler->registerEventListener('doAction', - WindFactory::createInstance(Wind::import($_filter['class']))); + if (!isset($_filters[$_token])) { + foreach ($filters as $_filter) { + if (isset($_filter['class'])) + if (!$_filter['pattern'] || preg_match('/^' . str_replace('*', '\w*', $_filter['pattern']) . '$/i', + $_token)) { + $_filters[$_token][] = $_filter['class']; + } } + $cache && $cache->set($key, $_filters); + } + if (empty($_filters[$_token])) {return;} + foreach ($_filters[$_token] as $key => $value) { + $handler->registerEventListener('doAction', $this->windFactory->createInstance(Wind::import($value))); } } From eeb80d6de3942aebcbd3f48de50a7a8932cccd97 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 17:23:42 +0000 Subject: [PATCH 0544/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2616 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindLayout.php | 37 ++++++++++-------------------- wind/viewer/WindView.php | 2 ++ wind/viewer/WindViewerResolver.php | 9 +++++--- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/wind/viewer/WindLayout.php b/wind/viewer/WindLayout.php index 543e4ebc..08848d91 100644 --- a/wind/viewer/WindLayout.php +++ b/wind/viewer/WindLayout.php @@ -11,11 +11,6 @@ class WindLayout extends WindModule { /* 编译结果缓存 */ protected $blockKey = ""; - /** - * 定义主题包的位置 - * @var string - */ - private $theme; /** * javascript集合 * @var string @@ -53,24 +48,24 @@ public function __construct($layoutFile = '') { */ public function parser($viewer) { $this->viewer = $viewer; - $content = ''; ob_start(); if ($this->layout) { + $__theme = $this->viewer->getWindView()->theme; + $themeUrl = $__theme ? $__theme : $this->getRequest()->getBaseUrl(true); + unset($__theme); list($tpl) = $this->viewer->compile($this->layout); - if (!@include ($tpl)) { - throw new WindViewException('[component.viewer.WindLayout.parser] layout file ' . $tpl, - WindViewException::VIEW_NOT_EXIST); - } + if (!@include ($tpl)) {throw new WindViewException('[component.viewer.WindLayout.parser] layout file ' . $tpl, + WindViewException::VIEW_NOT_EXIST);} } else $this->content(); - $content = ob_get_clean(); - foreach ($this->segments as $key => $value) { - if ($key) - $content = str_replace("", $value[1], $content); + $__content = ob_get_clean(); + foreach ($this->segments as $__key => $__value) { + if ($__key) + $__content = str_replace("", $__value[1], $__content); } - $content = preg_replace('/(<\/body>)/i', $this->script . '\\1', $content); - //$content = preg_replace('/<\/head>/i', $this->css . '', $content); - return $content; + $this->script && $__content = preg_replace('/(<\/body>)/i', $this->script . '\\1', $__content); + $this->css && $__content = preg_replace('/<\/head>/i', $this->css . '', $__content); + return $__content; } /** @@ -91,13 +86,6 @@ public function content() { $this->segment($template); } - /** - * @param string $theme - */ - public function setTheme($theme) { - $this->theme = $theme; - } - /** * @param string $layout */ @@ -118,5 +106,4 @@ public function setScript($script) { public function setCss($css) { $this->css .= $css; } - } \ No newline at end of file diff --git a/wind/viewer/WindView.php b/wind/viewer/WindView.php index 20b389f6..0da7988a 100644 --- a/wind/viewer/WindView.php +++ b/wind/viewer/WindView.php @@ -102,6 +102,8 @@ public function setConfig($config) { $this->compileDir = $this->getConfig('compile-dir', '', $this->compileDir); $this->compileExt = $this->getConfig('compile-ext', '', $this->compileExt); $this->isCompile = $this->getConfig('is-compile', '', $this->isCompile); + $this->layout = $this->getConfig('layout', '', $this->layout); + $this->theme = $this->getConfig('theme', '', $this->theme); $this->htmlspecialchars = $this->getConfig('htmlspecialchars', '', $this->htmlspecialchars); } } diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index b782035f..1df630f5 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -131,12 +131,15 @@ public function getWindLayout() { class WindRender { /** - * @param string $tpl - * @param array $vars - * @param WindViewerResolver $viewer + * @param string $__tpl + * @param array $__vars + * @param WindViewerResolver $__viewer * @throws WindViewException */ public static function render($__tpl, $__vars, $__viewer) { + $__theme = $__viewer->getWindView()->theme; + $themeUrl = $__theme ? $__theme : Wind::getApp()->getRequest()->getBaseUrl(true); + unset($__theme); @extract($__vars, EXTR_REFS); if (!@include ($__tpl)) throw new WindViewException('[component.viewer.WindRender.render] template name ' . $__tpl, From cb16f5626a1868a9e1c8ed69253060b86065ae10 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 21:45:03 +0000 Subject: [PATCH 0545/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2617 18ba2127-5a84-46d4-baec-3457e417f034 --- .../compiler/WindTemplateCompilerAction.php | 15 ++++-------- .../compiler/WindTemplateCompilerTemplate.php | 24 +++++++++---------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/wind/viewer/compiler/WindTemplateCompilerAction.php b/wind/viewer/compiler/WindTemplateCompilerAction.php index 1e9b5b49..a89363de 100644 --- a/wind/viewer/compiler/WindTemplateCompilerAction.php +++ b/wind/viewer/compiler/WindTemplateCompilerAction.php @@ -17,17 +17,10 @@ class WindTemplateCompilerAction extends AbstractWindTemplateCompiler { * @see AbstractWindTemplateCompiler::compile() */ public function compile($key, $content) { - return 'getComponent(\'forward\'); - $_tpl_forward->forwardAction(\'' . $this->action . '\'); - Wind::getApp()->doDispatch($_tpl_forward, true); ?>'; - } - - /** - * @return string - */ - public function getScript() { - $_tmp = '$_tpl_forward = $this->getSystemFactory()->getInstance(COMPONENT_FORWARD);' . '$_tpl_forward->setDisplay(true);' . '$_tpl_forward->forwardAnotherAction(\'' . $this->action . '\', \'' . $this->controller . '\');' . '$_tpl_app = $this->getSystemFactory()->getInstance(COMPONENT_WEBAPP);' . '$_tpl_app->doDispatch($_tpl_forward);'; - return $_tmp; + $content = 'getComponent(\'forward\');'; + $content .= '$_tpl_forward->forwardAction(\'' . $this->action . '\');'; + $content .= 'Wind::getApp()->doDispatch($_tpl_forward, true); ?>'; + return $content; } /* (non-PHPdoc) diff --git a/wind/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/viewer/compiler/WindTemplateCompilerTemplate.php index 4bf9584b..4291a59f 100644 --- a/wind/viewer/compiler/WindTemplateCompilerTemplate.php +++ b/wind/viewer/compiler/WindTemplateCompilerTemplate.php @@ -26,19 +26,19 @@ public function compile($key, $content) { if (!$this->source) return $content; - preg_match('/^{?\$(\w+)}?$/Ui', $this->source, $_tmp); - if (!empty($_tmp)) { - $_tpl = $this->windViewerResolver->getWindView()->templateName; - $this->source = Wind::getApp()->getResponse()->getData($_tpl, $_tmp[1]); - } - if ($this->load === 'false') { - list($compileFile) = $this->windViewerResolver->compile($this->source, $this->suffix); - if (!empty($_tmp)) - $compileFile = str_replace($this->source, '{$' . $_tmp[1] . '}', $compileFile); - $content = ''; + if (preg_match('/^{?\$(\w+)}?$/Ui', $this->source, $_tmp)) { + $content = 'source . '))'; + $content .= 'list($' . $this->source . ') = $__viewer->compile(' . $this->source . ', ' . $this->suffix . ');'; + $content .= 'include_once($' . $this->source . ');?>'; } else { - list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, - true); + if ($this->load === 'false') { + list($compileFile) = $this->windViewerResolver->compile($this->source, $this->suffix); + if (!empty($_tmp)) + $compileFile = str_replace($this->source, '{$' . $_tmp[1] . '}', $compileFile); + $content = ''; + } else { + list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, true); + } } return $content; } From e94fbb4e2eb7e0bc3273afd8e331406d50d12fdc Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 21:53:10 +0000 Subject: [PATCH 0546/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2618 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/compiler/WindTemplateCompilerTemplate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/viewer/compiler/WindTemplateCompilerTemplate.php b/wind/viewer/compiler/WindTemplateCompilerTemplate.php index 4291a59f..1e216f16 100644 --- a/wind/viewer/compiler/WindTemplateCompilerTemplate.php +++ b/wind/viewer/compiler/WindTemplateCompilerTemplate.php @@ -35,7 +35,7 @@ public function compile($key, $content) { list($compileFile) = $this->windViewerResolver->compile($this->source, $this->suffix); if (!empty($_tmp)) $compileFile = str_replace($this->source, '{$' . $_tmp[1] . '}', $compileFile); - $content = ''; + $content = ''; } else { list(, $content) = $this->windViewerResolver->compile($this->source, $this->suffix, true); } From 5d872a891669fe83e96951b6d35b4a75d1463fee Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 21:55:01 +0000 Subject: [PATCH 0547/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2619 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 1df630f5..41e9c88a 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -141,7 +141,7 @@ public static function render($__tpl, $__vars, $__viewer) { $themeUrl = $__theme ? $__theme : Wind::getApp()->getRequest()->getBaseUrl(true); unset($__theme); @extract($__vars, EXTR_REFS); - if (!@include ($__tpl)) + if (!@include_once ($__tpl)) throw new WindViewException('[component.viewer.WindRender.render] template name ' . $__tpl, WindViewException::VIEW_NOT_EXIST); } From aea59df9d1151f0b1cc1b5cdedb5870c6bf2ded7 Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 21:55:15 +0000 Subject: [PATCH 0548/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2620 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 41e9c88a..1df630f5 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -141,7 +141,7 @@ public static function render($__tpl, $__vars, $__viewer) { $themeUrl = $__theme ? $__theme : Wind::getApp()->getRequest()->getBaseUrl(true); unset($__theme); @extract($__vars, EXTR_REFS); - if (!@include_once ($__tpl)) + if (!@include ($__tpl)) throw new WindViewException('[component.viewer.WindRender.render] template name ' . $__tpl, WindViewException::VIEW_NOT_EXIST); } From bd741a3e427cbd24beceeda9a7e97775a35fc2aa Mon Sep 17 00:00:00 2001 From: yishuo Date: Thu, 8 Sep 2011 21:55:33 +0000 Subject: [PATCH 0549/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2621 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 1df630f5..41e9c88a 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -141,7 +141,7 @@ public static function render($__tpl, $__vars, $__viewer) { $themeUrl = $__theme ? $__theme : Wind::getApp()->getRequest()->getBaseUrl(true); unset($__theme); @extract($__vars, EXTR_REFS); - if (!@include ($__tpl)) + if (!@include_once ($__tpl)) throw new WindViewException('[component.viewer.WindRender.render] template name ' . $__tpl, WindViewException::VIEW_NOT_EXIST); } From 307ee60aa01596be4f26acc9d07bb92e4a0b88c9 Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 9 Sep 2011 04:15:05 +0000 Subject: [PATCH 0550/1065] =?UTF-8?q?session=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2622 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/WindSession.php | 278 +++++++++++++++++++++++++----- 1 file changed, 232 insertions(+), 46 deletions(-) diff --git a/wind/http/session/WindSession.php b/wind/http/session/WindSession.php index 3b044aa8..212a5b51 100644 --- a/wind/http/session/WindSession.php +++ b/wind/http/session/WindSession.php @@ -1,36 +1,40 @@ - * 'WindSession' => array( - * 'path' => 'WIND:http.session.WindSession', - * 'scope' => 'singleton', - * 'properties' => array( - * 'handler' => array( - * 'ref' => 'sessionSave',//用户配置的缓存类型--缓存组件的配置格式参照缓存配置文件 - * ), - * ), - * ) + * 'WindSession' => array( + * 'path' => 'WIND:http.session.WindSession', + * 'scope' => 'singleton', + * 'destroy' => 'close', //配置在进程结束时使用的方法,执行session write和close + * 'properties' => array( + * 'handler' => array( + * 'ref' => 'sessionSave',//用户配置的缓存类型--缓存组件的配置格式参照缓存配置文件 + * ), + * ), + * ) * * 【使用】调用时使用: *
  * $session = $this->getSystemFactory()->getInstance('WindSession');
- * $session->start();
  * 
- * $_SESSION['name'] = 'test';
- * echo $_SESSION['name'];
+ * $session->set('name', 'test');    //等同:$_SESSION['name'] = 'test';
+ * echo $session->get('name');       //等同:echo $_SESSION['name'];
+ * 
+ * $session->delete('name');         //等同: unset($_SESSION['name');
+ * echo $session->sessionName();     //等同: echo session_name();
+ * echo $session->sessionId();       //等同: echo session_id();
+ * $session->destroy();              //等同: session_unset();session_destroy();
  * 
* 【使用原生】: * 如果用户不需要配置自己其他存储方式的session,则不许要修改任何调用,只要在WindSession的配置中将properties配置项去掉即可。如下: *
- * 'WindSession' => array(
- *		'path' => 'WIND:http.session.WindSession',
- *		'scope' => 'singleton',
- *  )
+ * 	'WindSession' => array(
+ * 		'path' => 'WIND:http.session.WindSession',
+ * 		'scope' => 'singleton',
+ * 	)
  * 
- * 【扩展】 + * 【扩展】: * 如果用户实现了自己的实现,需要调用自己的实现,则只需要更改path的值指定到自己的实现,即可。 * * @@ -39,57 +43,239 @@ * @version $Id$ * @package */ -class WindSession extends AbstractWindSession { +class WindSession extends WindModule { + + protected $handler = null; + + /** + * 构造函数 + * @param AbstractWindCache $handler + */ + public function __construct(AbstractWindCache $handler = null) { + $handler && $this->setHandler($handler); + } + + /** + * 开启session + * + * @param string $id + */ + public function start() { + if ('' === $this->sessionId() && '1' !== ini_get('session.auto_start')) { + session_start(); + } + } + + /** + * 设置数据 + * + * @param string $key + * @param mixed $value + * @return boolean + */ + public function set($key, $value) { + is_array($value) || is_object($value) && $value = serialize($value); + $_SESSION[$key] = $value; + return true; + } + + /** + * 获得数据 + * + * @param string $key + * @return mixed + */ + public function get($key) { + $value = isset($_SESSION[$key]) ? $_SESSION[$key] : null; + $tmp = unserialize($value); + return (is_array($tmp) || is_object($tmp)) ? $tmp : $value; + } - /* (non-PHPdoc) - * @see AbstractWindSession::open() + /** + * 删除数据 + * + * @param string $key + */ + public function delete($key) { + $_SESSION[$key] = null; + unset($_SESSION[$key]); + } + + /** + * 清除会话信息 + * + * @return boolean + */ + public function destroy() { + session_unset(); + return session_destroy(); + } + + /** + * 检测变量是否已经被注册 + * + * @param string $key + * @return boolean + */ + public function isRegister($key) { + return session_is_registered($key); + } + + /** + * 获得session的名字 + * + * @return string + */ + public function sessionName() { + return session_name(); + } + + /** + * 获得sessionId + * + * @return string + */ + public function sessionId() { + return session_id(); + } + + /** + * 设置链接对象 + * + * @param AbstractWindCache $handler */ - public function open($savePath, $sessionName) { - $handler = $this->getHandler(); + public function setHandler($handler) { + if ($handler instanceof AbstractWindCache) { + $this->handler = $handler; + $this->close(); + WindSessionHandler::registerHandler(); + } + } + + /** + * 获得链接对象 + * + * @return AbstractWindCache + */ + public function getHandler() { + return $this->_getHandler(); + } + + /** + * 在进程结束前执行session的write和close操作 + */ + public function close() { + session_write_close(); + } +} + +/** + * 注册session处理的方法 + * + * the last known user to change this file in the repository <$LastChangedBy$> + * @author xiaoxia.xu + * @version $Id$ + * @package + */ +final class WindSessionHandler { + + /** + * 获得句柄 + * @return AbstractWindCache + */ + static private function getHandler() { + $session = Wind::getApp()->getComponent('WindSession'); + return $session ? $session->getHandler() : null; + } + + /** + * 打开会话存储机制 + * 在session_start()执行的时候执行。 + * + * @param string $savePath + * @param string $sessionName + * @return bollean + */ + static public function open($savePath, $sessionName) { + if (null === self::getHandler()) return true; $lifeTime = get_cfg_var("session.gc_maxlifetime"); - if (($expire = $handler->getExpire()) == '0') { + if (($expire = self::getHandler()->getExpire()) == '0') { $lifeTime = get_cfg_var("session.gc_maxlifetime"); - $handler->setExpire($lifeTime ? $lifeTime : 0); + self::getHandler()->setExpire($lifeTime ? $lifeTime : 0); } else { ini_set("session.gc_maxlifetime", $expire); } return true; } - /* (non-PHPdoc) - * @see AbstractWindSession::close() + /** + * 关闭会话存储存储机制 + * 在页面执行完的时候执行 + * + * @return bollean */ - public function close() { - session_write_close(); + static public function close() { return true; } - /* (non-PHPdoc) - * @see AbstractWindSession::write() + /** + * 将sessionID对应的数据写到存储 + * 在需要写入session数据的时候执行 + * + * @param string $name + * @param mixed $value */ - public function write($sessID, $sessData) { - return $this->getHandler()->set($sessID, $sessData); + static public function write($sessID, $sessData) { + if (null === self::getHandler()) return true; + return self::getHandler()->set($sessID, $sessData); } - /* (non-PHPdoc) - * @see AbstractWindSession::read() + /** + * 从存储中装载session数据 + * 在执行session_start的时候执行在open之后 + * + * @param mixed $sessid */ - public function read($sessID) { - return $this->getHandler()->get($sessID); + static public function read($sessID) { + if (null === self::getHandler()) return true; + return self::getHandler()->get($sessID); } - /* (non-PHPdoc) - * @see AbstractWindSession::gc() + /** + * 对存储系统中的数据进行垃圾收集 + * 在执行session过期策略的时候执行,注意,session的过期并不是时时的,需要根据php.ini中的配置项: + * session.gc_probability = 1 + * session.gc_divisor = 1000 + * 执行的概率是gc_probability/gc_divisor . + * session.gc_maxlifetime = 1440 设置的session的过期时间 + * + * @param mixed $maxlifetime */ - public function gc($maxlifetime) { - return $this->getHandler()->clear(true); + static public function gc($maxlifetime) { + if (null === self::getHandler()) return true; + return self::getHandler()->clear(true); } - /* (non-PHPdoc) - * @see AbstractWindSession::destroy() + /** + * 破坏与指定的会话ID相关联的数据 + * 在执行session_destroy的时候执行。 + * + * @param mixed $name */ - public function destroy($sessID) { - return $this->getHandler()->delete($sessID); + static public function destroy($sessID) { + if (null === self::getHandler()) return true; + return self::getHandler()->delete($sessID); + } + + /** + * 设置session的存储方法 + * 同时启动session + */ + static public function registerHandler() { + if (null === self::getHandler()) return true; + session_set_save_handler(array('WindSessionHandler', 'open'), array('WindSessionHandler', 'close'), array('WindSessionHandler', 'read'), + array('WindSessionHandler', 'write'), array('WindSessionHandler', 'destroy'), array('WindSessionHandler', 'gc')); + Wind::getApp()->getComponent('WindSession')->start(); } } - +WindSessionHandler::registerHandler(); \ No newline at end of file From fc10d0a3fd5f82bbb9fe512e09b355957f81d21b Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 9 Sep 2011 04:23:43 +0000 Subject: [PATCH 0551/1065] =?UTF-8?q?session=E6=9C=BA=E5=88=B6=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=E6=96=87=E6=A1=A3=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2623 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/WindSession.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/wind/http/session/WindSession.php b/wind/http/session/WindSession.php index 212a5b51..31fd5b10 100644 --- a/wind/http/session/WindSession.php +++ b/wind/http/session/WindSession.php @@ -34,9 +34,11 @@ * 'scope' => 'singleton', * ) * - * 【扩展】: - * 如果用户实现了自己的实现,需要调用自己的实现,则只需要更改path的值指定到自己的实现,即可。 - * + * 【切忌】: + * 虽然框架的组件支持初始化方法的配置initMethod,但是在session这个配置中,当你需要使用其他的存储方式来存储session内容的时候, + * 是【不允许】被配置的,因为session_set_save_handler必须在session_start之前被设置,而设置了initMethod之后,将会使 + * session_start在session_set_save_handler之前被启动。 + * * * the last known user to change this file in the repository <$LastChangedBy$> * @author xiaoxia.xu From e15e5c3eecdef62f2564594109a43ee542fc9a0e Mon Sep 17 00:00:00 2001 From: "xiaoxia.xuxx" Date: Fri, 9 Sep 2011 08:52:23 +0000 Subject: [PATCH 0552/1065] =?UTF-8?q?=E7=BC=93=E5=AD=98=E7=AD=96=E7=95=A5?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=8C=E9=87=8D=E6=96=B0=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E7=9A=84=E6=B8=85=E7=90=86=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E8=BF=87=E6=9C=9F=E6=95=B0=E6=8D=AE=E7=9A=84=E6=B8=85?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2624 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/cache/AbstractWindCache.php | 6 ++++-- wind/cache/strategy/WindApcCache.php | 2 +- wind/cache/strategy/WindEacceleratorCache.php | 3 ++- wind/cache/strategy/WindMemCache.php | 4 ++-- wind/cache/strategy/WindWinCache.php | 4 ++-- wind/cache/strategy/WindXCache.php | 3 ++- wind/cache/strategy/WindZendCache.php | 4 ++-- 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/wind/cache/AbstractWindCache.php b/wind/cache/AbstractWindCache.php index 65e59590..0cab6cf4 100644 --- a/wind/cache/AbstractWindCache.php +++ b/wind/cache/AbstractWindCache.php @@ -78,10 +78,12 @@ protected abstract function getValue($key); protected abstract function deleteValue($key); /** - * 清空所有缓存 + * 清楚缓存,过期及所有缓存 + * + * @param boolean $expireOnly 如果为true则仅仅只删除过期的数据 * @return */ - public abstract function clear(); + public abstract function clear($expireOnly = false); /** * 设置缓存,如果key不存在,设置缓存,否则,替换已有key的缓存。 diff --git a/wind/cache/strategy/WindApcCache.php b/wind/cache/strategy/WindApcCache.php index 6e483c36..43a8f34a 100644 --- a/wind/cache/strategy/WindApcCache.php +++ b/wind/cache/strategy/WindApcCache.php @@ -38,7 +38,7 @@ protected function deleteValue($key) { /* * @see AbstractWindCache#clear() */ - public function clear() { + public function clear($expireOnly = false) { apc_clear_cache(); return apc_clear_cache('user'); } diff --git a/wind/cache/strategy/WindEacceleratorCache.php b/wind/cache/strategy/WindEacceleratorCache.php index 1cada601..648d8174 100644 --- a/wind/cache/strategy/WindEacceleratorCache.php +++ b/wind/cache/strategy/WindEacceleratorCache.php @@ -42,8 +42,9 @@ protected function deleteValue($key) { * @see AbstractWindCache#clear() * @return boolean */ - public function clear() { + public function clear($expireOnly = false) { eaccelerator_gc(); + if ($expireOnly) return true; $cacheKeys = eaccelerator_list_keys(); foreach ($cacheKeys as $key) { $this->delete(substr($key['name'], 1)); diff --git a/wind/cache/strategy/WindMemCache.php b/wind/cache/strategy/WindMemCache.php index 17b3e2d3..24c52e6e 100644 --- a/wind/cache/strategy/WindMemCache.php +++ b/wind/cache/strategy/WindMemCache.php @@ -62,8 +62,8 @@ protected function deleteValue($key) { /* * @see AbstractWindCache::clear() */ - public function clear() { - return $this->memcache->flush(); + public function clear($expireOnly = false) { + return false === $expireOnly ? $this->memcache->flush() : true; } /* (non-PHPdoc) diff --git a/wind/cache/strategy/WindWinCache.php b/wind/cache/strategy/WindWinCache.php index 1514e667..698f5528 100644 --- a/wind/cache/strategy/WindWinCache.php +++ b/wind/cache/strategy/WindWinCache.php @@ -39,8 +39,8 @@ protected function deleteValue($key) { /* * @see AbstractWindCache#clear() */ - public function clear() { - return wincache_ucache_clear(); + public function clear($expireOnly = false) { + return false === $expireOnly ? wincache_ucache_clear() : true; } } \ No newline at end of file diff --git a/wind/cache/strategy/WindXCache.php b/wind/cache/strategy/WindXCache.php index 8ec5def0..01e9f8ac 100644 --- a/wind/cache/strategy/WindXCache.php +++ b/wind/cache/strategy/WindXCache.php @@ -40,7 +40,8 @@ protected function deleteValue($key) { /* * @see AbstractWindCache#clear() */ - public function clear() { + public function clear($expireOnly = false) { + if (true === $expireOnly) return true; //xcache_clear_cache需要验证权限 $tmp['user'] = isset($_SERVER['PHP_AUTH_USER']) ? null : $_SERVER['PHP_AUTH_USER']; $tmp['pwd'] = isset($_SERVER['PHP_AUTH_PW']) ? null : $_SERVER['PHP_AUTH_PW']; diff --git a/wind/cache/strategy/WindZendCache.php b/wind/cache/strategy/WindZendCache.php index 696c25af..a05a94ba 100644 --- a/wind/cache/strategy/WindZendCache.php +++ b/wind/cache/strategy/WindZendCache.php @@ -38,8 +38,8 @@ protected function deleteValue($key) { /* (non-PHPdoc) * @see AbstractWindCache::clear() */ - public function clear() { - return zend_shm_cache_clear(); + public function clear($expireOnly = false) { + return (false === $expireOnly) ? zend_shm_cache_clear() : true; } } \ No newline at end of file From b81f593e929658b82af5ccb094500a7719b30c55 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 12 Sep 2011 07:46:05 +0000 Subject: [PATCH 0553/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2625 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 41e9c88a..4ab794ba 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -45,17 +45,18 @@ public function windFetch($template = '') { ob_start(); if (!$template) { $template = $this->windView->templateName; - $_tpl = $this->windView->getCompileFile($template); - if ($this->checkReCompile()) { + $templateFilePath = $this->windView->getViewTemplate($template); + $compileFilePath = $this->windView->getCompileFile($template); + if ($this->checkReCompile($templateFilePath, $compileFilePath)) { $layout = $this->getWindLayout(); $layout->setLayout($this->windView->layout); $layout->setTheme($this->windView->theme); - WindFile::write($_tpl, $layout->parser($this)); + WindFile::write($compileFilePath, $layout->parser($this)); } } else - list($_tpl) = $this->compile($template); + list($compileFilePath) = $this->compile($template); - WindRender::render($_tpl, Wind::getApp()->getResponse()->getData($template), $this); + WindRender::render($compileFilePath, Wind::getApp()->getResponse()->getData($template), $this); return ob_get_clean(); } @@ -94,10 +95,19 @@ public function compile($template, $suffix = '', $output = false) { /** * 检查是否需要重新编译,需要编译返回false,不需要编译返回true + * + * @param string $templateFilePath + * @param string $compileFilePath * @return boolean */ - private function checkReCompile() { - return WIND_DEBUG || $this->getWindView()->isCompile; + private function checkReCompile($templateFilePath, $compileFilePath) { + if (WIND_DEBUG) {return true;} + if ($this->getWindView()->isCompile) { + $_c_m_t = @filemtime($compileFilePath); + if ((int) $_c_m_t <= (int) @filemtime($templateFilePath)) + return true; + } + return false; } /** From 30e9ae09f24ffd58b38faef5088f16fb5379f493 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 12 Sep 2011 07:53:05 +0000 Subject: [PATCH 0554/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2626 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/config/components_config.xml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index e792d7b4..b947ea6f 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -1,14 +1,14 @@ + proxy='' destroy=''> --> - @@ -16,8 +16,8 @@ - + scope='singleton' destroy='flush'> + htm
0 compile.template - 0 + tpl + + @@ -72,7 +74,7 @@ - data.config + DATA:caches php 0 From 7cec1b38c62781da15d9723dbb45edf7ade65a38 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 12 Sep 2011 09:29:13 +0000 Subject: [PATCH 0555/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2627 18ba2127-5a84-46d4-baec-3457e417f034 --- _compile/config/components_config.xml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/_compile/config/components_config.xml b/_compile/config/components_config.xml index b947ea6f..aa86814d 100644 --- a/_compile/config/components_config.xml +++ b/_compile/config/components_config.xml @@ -17,8 +17,10 @@
- - + + + + @@ -69,7 +71,7 @@ scope='singleton'> - @@ -79,4 +81,7 @@ 0 + + From 355cb3a799cd698946491ba5237ddd557dff2dc1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 12 Sep 2011 09:29:24 +0000 Subject: [PATCH 0556/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2628 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/wind/components_config.php b/wind/components_config.php index feab60e3..16e60636 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -15,11 +15,11 @@ 'path' => 'WIND:log.WindLogger', 'scope' => 'singleton', 'destroy' => 'flush', - 'constructor-arg' => array( - '0' => array( + 'constructor-args' => array( + 'constructor-arg' => array( 'value' => 'DATA:log', ), - '1' => array( + '0' => array( 'value' => '0', ), ), @@ -53,7 +53,9 @@ 'template-ext' => 'htm', 'is-compile' => '0', 'compile-dir' => 'compile.template', - 'is-cache' => '0', + 'compile-ext' => 'tpl', + 'layout' => '', + 'theme' => '', ), 'properties' => array( 'viewResolver' => array( @@ -105,4 +107,8 @@ 'expires' => '0', ), ), + 'windSession' => array( + 'path' => 'WIND:http.session.WindSession', + 'scope' => 'singleton', + ), ); \ No newline at end of file From a426c1af87facbc196e52340f4419c14ac3a7f2b Mon Sep 17 00:00:00 2001 From: yishuo Date: Mon, 12 Sep 2011 09:43:18 +0000 Subject: [PATCH 0557/1065] =?UTF-8?q?bug=20fix:=20=E5=BD=93=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=E4=B8=BA0=E6=97=B6=EF=BC=8C=E5=87=BA=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2629 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/parser/WindXmlParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/parser/WindXmlParser.php b/wind/parser/WindXmlParser.php index cee4d7a6..14bc8c79 100644 --- a/wind/parser/WindXmlParser.php +++ b/wind/parser/WindXmlParser.php @@ -68,7 +68,7 @@ public function getChilds($node) { } if (1 !== $node->nodeType) continue; - $nodeName = ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; + $nodeName = "" !== ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; $tempChilds = $this->getChilds($node); $tempChilds = array_merge($attributes, $tempChilds); if (empty($tempChilds)) $tempChilds = ''; From 6d3c295b701fb96b5588dc29775ca9e02b50ace6 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 03:50:28 +0000 Subject: [PATCH 0558/1065] =?UTF-8?q?bug=20fix:=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=BC=96=E8=AF=91=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2630 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/viewer/WindViewerResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/viewer/WindViewerResolver.php b/wind/viewer/WindViewerResolver.php index 4ab794ba..81e16d92 100644 --- a/wind/viewer/WindViewerResolver.php +++ b/wind/viewer/WindViewerResolver.php @@ -82,7 +82,7 @@ public function compile($template, $suffix = '', $output = false) { WindViewException::VIEW_NOT_EXIST); $compileFile = $this->windView->getCompileFile($template); - if (!$this->checkReCompile()) + if (!$this->checkReCompile($templateFile, $compileFile)) return array($compileFile, ''); /* @var $_windTemplate WindViewTemplate */ $_windTemplate = Wind::getApp()->getWindFactory()->getInstance('template'); From 4ffdd206a90b60744fc0a46adcd561a5e6ec3f46 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 06:31:42 +0000 Subject: [PATCH 0559/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2631 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/WindSession.php | 238 ++++++----------------- wind/http/session/WindSessionHandler.php | 141 ++++++++++++++ 2 files changed, 200 insertions(+), 179 deletions(-) create mode 100644 wind/http/session/WindSessionHandler.php diff --git a/wind/http/session/WindSession.php b/wind/http/session/WindSession.php index 31fd5b10..207eafee 100644 --- a/wind/http/session/WindSession.php +++ b/wind/http/session/WindSession.php @@ -3,16 +3,16 @@ * 会话机制,依赖Cache机制实现,应用可以根据自己的需求配置需要的存储方式实现会话存储 * 【配置】支持组件配置格式: *
- * 	'WindSession' => array(
- * 		'path'       => 'WIND:http.session.WindSession',
- * 		'scope'      => 'singleton',
- *      'destroy'    => 'close',  //配置在进程结束时使用的方法,执行session  write和close
- * 		'properties' => array(
- * 			'handler' => array(
- * 				'ref' => 'sessionSave',//用户配置的缓存类型--缓存组件的配置格式参照缓存配置文件
- * 			),
- * 		),
- * 	)
+ * 'WindSession' => array(
+ * 'path'       => 'WIND:http.session.WindSession',
+ * 'scope'      => 'singleton',
+ * 'destroy'    => 'close',  //配置在进程结束时使用的方法,执行session  write和close
+ * 'properties' => array(
+ * 'handler' => array(
+ * 'ref' => 'sessionSave',//用户配置的缓存类型--缓存组件的配置格式参照缓存配置文件
+ * ),
+ * ),
+ * )
  * 
* 【使用】调用时使用: *
@@ -29,16 +29,16 @@
  * 【使用原生】:
  * 如果用户不需要配置自己其他存储方式的session,则不许要修改任何调用,只要在WindSession的配置中将properties配置项去掉即可。如下:
  * 
- * 	'WindSession' => array(
- * 		'path' => 'WIND:http.session.WindSession',
- * 		'scope' => 'singleton',
- * 	)
+ * 'WindSession' => array(
+ * 'path' => 'WIND:http.session.WindSession',
+ * 'scope' => 'singleton',
+ * )
  * 
* 【切忌】: - * 虽然框架的组件支持初始化方法的配置initMethod,但是在session这个配置中,当你需要使用其他的存储方式来存储session内容的时候, - * 是【不允许】被配置的,因为session_set_save_handler必须在session_start之前被设置,而设置了initMethod之后,将会使 - * session_start在session_set_save_handler之前被启动。 - * + * 虽然框架的组件支持初始化方法的配置initMethod,但是在session这个配置中,当你需要使用其他的存储方式来存储session内容的时候, + * 是【不允许】被配置的,因为session_set_save_handler必须在session_start之前被设置,而设置了initMethod之后,将会使 + * session_start在session_set_save_handler之前被启动。 + * * * the last known user to change this file in the repository <$LastChangedBy$> * @author xiaoxia.xu @@ -47,237 +47,117 @@ */ class WindSession extends WindModule { - protected $handler = null; - /** * 构造函数 - * @param AbstractWindCache $handler + * @param AbstractWindCache $dataStoreHandler */ - public function __construct(AbstractWindCache $handler = null) { - $handler && $this->setHandler($handler); + public function __construct($dataStoreHandler = null, $sessionHandler = null) { + $this->setDataStoreHandler($dataStoreHandler, $sessionHandler); } /** * 开启session - * * @param string $id */ public function start() { - if ('' === $this->sessionId() && '1' !== ini_get('session.auto_start')) { - session_start(); - } + '' === $this->getCurrentId() && session_start(); } /** * 设置数据 - * * @param string $key * @param mixed $value - * @return boolean */ public function set($key, $value) { - is_array($value) || is_object($value) && $value = serialize($value); - $_SESSION[$key] = $value; - return true; + $key && $_SESSION[$key] = $value; } /** * 获得数据 - * * @param string $key * @return mixed */ public function get($key) { - $value = isset($_SESSION[$key]) ? $_SESSION[$key] : null; - $tmp = unserialize($value); - return (is_array($tmp) || is_object($tmp)) ? $tmp : $value; + var_dump(session_is_registered($key)); + return $this->isRegistered($key) ? $_SESSION[$key] : ''; } - + /** * 删除数据 - * * @param string $key */ public function delete($key) { - $_SESSION[$key] = null; - unset($_SESSION[$key]); + return session_unregister($key); } - + /** * 清除会话信息 - * * @return boolean */ public function destroy() { - session_unset(); return session_destroy(); } - + /** * 检测变量是否已经被注册 - * * @param string $key * @return boolean */ - public function isRegister($key) { + public function isRegistered($key) { return session_is_registered($key); } - + /** - * 获得session的名字 - * + * 获得当前session的名字 * @return string */ - public function sessionName() { + public function getCurrentName() { return session_name(); } - - /** - * 获得sessionId - * - * @return string - */ - public function sessionId() { - return session_id(); - } - - /** - * 设置链接对象 - * - * @param AbstractWindCache $handler - */ - public function setHandler($handler) { - if ($handler instanceof AbstractWindCache) { - $this->handler = $handler; - $this->close(); - WindSessionHandler::registerHandler(); - } - } - - /** - * 获得链接对象 - * - * @return AbstractWindCache - */ - public function getHandler() { - return $this->_getHandler(); - } - - /** - * 在进程结束前执行session的write和close操作 - */ - public function close() { - session_write_close(); - } -} - -/** - * 注册session处理的方法 - * - * the last known user to change this file in the repository <$LastChangedBy$> - * @author xiaoxia.xu - * @version $Id$ - * @package - */ -final class WindSessionHandler { - - /** - * 获得句柄 - * @return AbstractWindCache - */ - static private function getHandler() { - $session = Wind::getApp()->getComponent('WindSession'); - return $session ? $session->getHandler() : null; - } - - /** - * 打开会话存储机制 - * 在session_start()执行的时候执行。 - * - * @param string $savePath - * @param string $sessionName - * @return bollean - */ - static public function open($savePath, $sessionName) { - if (null === self::getHandler()) return true; - $lifeTime = get_cfg_var("session.gc_maxlifetime"); - if (($expire = self::getHandler()->getExpire()) == '0') { - $lifeTime = get_cfg_var("session.gc_maxlifetime"); - self::getHandler()->setExpire($lifeTime ? $lifeTime : 0); - } else { - ini_set("session.gc_maxlifetime", $expire); - } - return true; - } - - /** - * 关闭会话存储存储机制 - * 在页面执行完的时候执行 - * - * @return bollean - */ - static public function close() { - return true; - } /** - * 将sessionID对应的数据写到存储 - * 在需要写入session数据的时候执行 - * + * 设置当前session的名字 * @param string $name - * @param mixed $value */ - static public function write($sessID, $sessData) { - if (null === self::getHandler()) return true; - return self::getHandler()->set($sessID, $sessData); + public function setCurrentName($name) { + return session_name($name); } /** - * 从存储中装载session数据 - * 在执行session_start的时候执行在open之后 - * - * @param mixed $sessid + * 获得sessionId + * @return string */ - static public function read($sessID) { - if (null === self::getHandler()) return true; - return self::getHandler()->get($sessID); + public function getCurrentId() { + return session_id(); } /** - * 对存储系统中的数据进行垃圾收集 - * 在执行session过期策略的时候执行,注意,session的过期并不是时时的,需要根据php.ini中的配置项: - * session.gc_probability = 1 - * session.gc_divisor = 1000 - * 执行的概率是gc_probability/gc_divisor . - * session.gc_maxlifetime = 1440 设置的session的过期时间 - * - * @param mixed $maxlifetime + * 设置当前session的Id + * @param string $id */ - static public function gc($maxlifetime) { - if (null === self::getHandler()) return true; - return self::getHandler()->clear(true); + public function setCurrentId($id) { + return session_id($id); } /** - * 破坏与指定的会话ID相关联的数据 - * 在执行session_destroy的时候执行。 - * - * @param mixed $name + * write and close */ - static public function destroy($sessID) { - if (null === self::getHandler()) return true; - return self::getHandler()->delete($sessID); + public function commit() { + return session_commit(); } - + /** - * 设置session的存储方法 - * 同时启动session + * 设置链接对象 + * @param AbstractWindCache $handler + * @param WindSessionHandler $sessionHandler */ - static public function registerHandler() { - if (null === self::getHandler()) return true; - session_set_save_handler(array('WindSessionHandler', 'open'), array('WindSessionHandler', 'close'), array('WindSessionHandler', 'read'), - array('WindSessionHandler', 'write'), array('WindSessionHandler', 'destroy'), array('WindSessionHandler', 'gc')); - Wind::getApp()->getComponent('WindSession')->start(); + public function setDataStoreHandler($dataStoreHandler, $sessionHandler) { + if (!$dataStoreHandler) return; + if ($sessionHandler === null) { + Wind::import('WIND:http.session.WindSessionHandler'); + $sessionHandler = new WindSessionHandler(); + } + $sessionHandler->registerHandler($dataStoreHandler); + $this->start(); } } -WindSessionHandler::registerHandler(); \ No newline at end of file diff --git a/wind/http/session/WindSessionHandler.php b/wind/http/session/WindSessionHandler.php new file mode 100644 index 00000000..e518ace7 --- /dev/null +++ b/wind/http/session/WindSessionHandler.php @@ -0,0 +1,141 @@ + + * @author xiaoxia.xu + * @version $Id$ + * @package + */ +class WindSessionHandler extends AbstractWindSessionHandler { + + /* (non-PHPdoc) + * @see AbstractWindSessionHandler::open($savePath, $sessionName) + */ + public function open($savePath, $sessionName) { + if ('0' == ($expire = $this->dataStore->getExpire())) { + $lifeTime = get_cfg_var("session.gc_maxlifetime"); + $this->dataStore->setExpire((int) $lifeTime); + } else + session_cache_expire($expire); + return true; + } + + /* (non-PHPdoc) + * @see AbstractWindSessionHandler::close() + */ + public function close() { + return true; + } + + /* (non-PHPdoc) + * @see AbstractWindSessionHandler::write($sessID, $sessData) + */ + public function write($sessID, $sessData) { + return $this->dataStore->set($sessID, $sessData); + } + + /* (non-PHPdoc) + * @see AbstractWindSessionHandler::read($sessID) + */ + public function read($sessID) { + return $this->dataStore->get($sessID); + } + + /* (non-PHPdoc) + * @see AbstractWindSessionHandler::gc($maxlifetime) + */ + public function gc($maxlifetime) { + return $this->dataStore->clear(); + } + + /* (non-PHPdoc) + * @see AbstractWindSessionHandler::destroy($sessID) + */ + public function destroy($sessID) { + return $this->dataStore->delete($sessID); + } +} + +/** + * the last known user to change this file in the repository <$LastChangedBy$> + * @author Qiong Wu + * @version $Id$ + * @package + */ +abstract class AbstractWindSessionHandler { + /** + * @var AbstractWindCache + */ + protected $dataStore = null; + + /** + * 打开会话存储机制 + * + * @param string $savePath + * @param string $sessionName + * @return boolean + */ + abstract public function open($savePath, $sessionName); + + /** + * 关闭会话存储存储机制 + * 在页面执行完的时候执行 + * + * @return bollean + */ + abstract public function close(); + + /** + * 将sessionID对应的数据写到存储 + * 在需要写入session数据的时候执行 + * + * @param string $name + * @param mixed $value + */ + abstract public function write($sessID, $sessData); + + /** + * 从存储中装载session数据 + * 在执行session_start的时候执行在open之后 + * + * @param mixed $sessid + */ + abstract public function read($sessID); + + /** + * 对存储系统中的数据进行垃圾收集 + * 在执行session过期策略的时候执行,注意,session的过期并不是时时的,需要根据php.ini中的配置项: + * session.gc_probability = 1 + * session.gc_divisor = 1000 + * 执行的概率是gc_probability/gc_divisor . + * session.gc_maxlifetime = 1440 设置的session的过期时间 + * + * @param mixed $maxlifetime + */ + abstract public function gc($maxlifetime); + + /** + * 破坏与指定的会话ID相关联的数据 + * 在执行session_destroy的时候执行。 + * + * @param mixed $name + */ + abstract public function destroy($sessID); + + /** + * 设置session的存储方法 + * @param AbstractWindCache $dataStore + */ + public function registerHandler($dataStore) { + if (!$dataStore instanceof AbstractWindCache) { + throw new WindException( + '[http.session.WindSessionHandler.registerHandler] register session save handler fail.', + WindException::ERROR_PARAMETER_TYPE_ERROR); + } + $this->dataStore = $dataStore; + session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), + array($this, 'write'), array($this, 'destroy'), array($this, 'gc')); + } +} \ No newline at end of file From f079121d0bb955ba8cc85002589bca90f2ed5d2d Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 06:32:24 +0000 Subject: [PATCH 0560/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2632 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/WindSession.php | 2 +- wind/http/session/{ => handler}/WindSessionHandler.php | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename wind/http/session/{ => handler}/WindSessionHandler.php (100%) diff --git a/wind/http/session/WindSession.php b/wind/http/session/WindSession.php index 207eafee..4f0d8302 100644 --- a/wind/http/session/WindSession.php +++ b/wind/http/session/WindSession.php @@ -154,7 +154,7 @@ public function commit() { public function setDataStoreHandler($dataStoreHandler, $sessionHandler) { if (!$dataStoreHandler) return; if ($sessionHandler === null) { - Wind::import('WIND:http.session.WindSessionHandler'); + Wind::import('WIND:http.session.handler.WindSessionHandler'); $sessionHandler = new WindSessionHandler(); } $sessionHandler->registerHandler($dataStoreHandler); diff --git a/wind/http/session/WindSessionHandler.php b/wind/http/session/handler/WindSessionHandler.php similarity index 100% rename from wind/http/session/WindSessionHandler.php rename to wind/http/session/handler/WindSessionHandler.php From c429d77f07f709eb9be64254b9dc2f6b027b3f75 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 06:33:14 +0000 Subject: [PATCH 0561/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2633 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/log/WindLogger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wind/log/WindLogger.php b/wind/log/WindLogger.php index d7dcf813..ddefe590 100644 --- a/wind/log/WindLogger.php +++ b/wind/log/WindLogger.php @@ -139,7 +139,7 @@ public function flush() { } if ($this->_writeType & 1) { foreach ($_logLevels as $key => $value) { - if (!$fileName = $this->_getFileName($key)) + if (!$fileName = $this->_getFileName($_map[$key])) continue; WindFile::write($fileName, join("", $value), 'a'); } From 94c216a3cee0b8aa07cc2d7397a7f0447264361d Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 06:34:06 +0000 Subject: [PATCH 0562/1065] =?UTF-8?q?bug=20fix:=20name=20=E4=B8=8D?= =?UTF-8?q?=E8=83=BD=E4=B8=BA=20=E6=95=B0=E5=AD=97=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2634 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/parser/WindXmlParser.php | 37 ++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/wind/parser/WindXmlParser.php b/wind/parser/WindXmlParser.php index 14bc8c79..a135505e 100644 --- a/wind/parser/WindXmlParser.php +++ b/wind/parser/WindXmlParser.php @@ -15,12 +15,12 @@ * @package */ class WindXmlParser { - + /** * @var string 节点名称 */ const NAME = 'name'; - + /** * @var Domdocument DOM解析器 */ @@ -59,29 +59,30 @@ public function parse($filename, $option = null) { public function getChilds($node) { if (!$node instanceof DOMElement) return array(); $childs = array(); - foreach ($node->childNodes as $node) { + foreach ($node->childNodes as $_node) { $tempChilds = $attributes = array(); - ($node->hasAttributes()) && $attributes = $this->getAttributes($node); - if (3 == $node->nodeType) { - $value = trim($node->nodeValue); - (is_numeric($value) || $value) && $childs[0] = $value;//值为0的情况 + $_node->hasAttributes() && $attributes = $this->getAttributes($_node); + if (3 == $_node->nodeType) { + $value = trim($_node->nodeValue); + (is_numeric($value) || $value) && $childs['__value'] = $value; //值为0的情况 } - if (1 !== $node->nodeType) continue; + if (1 !== $_node->nodeType) continue; - $nodeName = "" !== ($name = $node->getAttribute(self::NAME)) ? $name : $node->nodeName; - $tempChilds = $this->getChilds($node); + $tempChilds = $this->getChilds($_node); $tempChilds = array_merge($attributes, $tempChilds); - if (empty($tempChilds)) $tempChilds = ''; - $tempChilds = (isset($tempChilds[0]) && count($tempChilds) == 1) ? $tempChilds[0] : $tempChilds; - if (!isset($childs[$nodeName])) { + if (empty($tempChilds)) + $tempChilds = ''; + else + $tempChilds = (isset($tempChilds['__value']) && count($tempChilds) == 1) ? $tempChilds['__value'] : $tempChilds; + + $nodeName = "" !== ($name = $_node->getAttribute(self::NAME)) ? $name : $_node->nodeName; + if (!isset($childs[$nodeName])) $childs[$nodeName] = $tempChilds; - continue; - } else { + else { $element = $childs[$nodeName]; - $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(array( - $element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); - continue; + $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge( + array($element), array($tempChilds)) : array_merge((array) $element, array($tempChilds)); } } return $childs; From 953956519733418575de11f2d8e78859d058aa32 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 06:34:25 +0000 Subject: [PATCH 0563/1065] =?UTF-8?q?bug=20fix:=20name=20=E4=B8=8D?= =?UTF-8?q?=E8=83=BD=E4=B8=BA=20=E6=95=B0=E5=AD=97=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2635 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/components_config.php | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/wind/components_config.php b/wind/components_config.php index 16e60636..6632c05b 100644 --- a/wind/components_config.php +++ b/wind/components_config.php @@ -1,4 +1,18 @@ array( + '0' => array( + 'value' => '1', + ), + '1' => array( + 'value' => '2', + ), + '2' => array( + 'value' => '3', + ), + '3' => array( + 'value' => '4', + ), + ), 'windApplication' => array( 'path' => 'WIND:web.WindWebApplication', 'scope' => 'singleton', @@ -16,11 +30,11 @@ 'scope' => 'singleton', 'destroy' => 'flush', 'constructor-args' => array( - 'constructor-arg' => array( + '0' => array( 'value' => 'DATA:log', ), - '0' => array( - 'value' => '0', + '1' => array( + 'value' => '2', ), ), ), @@ -110,5 +124,14 @@ 'windSession' => array( 'path' => 'WIND:http.session.WindSession', 'scope' => 'singleton', + 'constructor-args' => array( + '0' => array( + 'ref' => 'windCache', + ), + ), + ), + 'sessionCache' => array( + 'path' => 'WIND:cache.strategy.WindDbCache', + 'scope' => 'singleton', ), ); \ No newline at end of file From b82168f8b5ac62eeac31e8b7a6f74ed0fbb56eda Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 06:34:36 +0000 Subject: [PATCH 0564/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2636 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/Wind.php | 443 ++++++++++++++++++++++++++------------------------ 1 file changed, 234 insertions(+), 209 deletions(-) diff --git a/wind/Wind.php b/wind/Wind.php index 37a4f58d..6354ec4d 100644 --- a/wind/Wind.php +++ b/wind/Wind.php @@ -39,18 +39,21 @@ public static function application($appName = 'default', $config = array(), $roo if (!isset(self::$_app[$appName])) { $factory = new WindFactory(@include (Wind::getRealPath(self::$_components))); if ($config) { - is_string($config) && $config = $factory->getInstance('configParser')->parse($config); + is_string($config) && $config = $factory->getInstance('configParser')->parse( + $config); $_default = isset($config['default']) ? $config['default'] : array(); $config = isset($config[$appName]) ? $config[$appName] : $config; $_default && $config = WindUtility::mergeArray($_default, $config); - isset($config['components']) && $factory->loadClassDefinitions($config['components']); + isset($config['components']) && $factory->loadClassDefinitions( + $config['components']); } $application = $factory->getInstance('windApplication', array($config, $factory)); - if (!$application instanceof IWindApplication) - throw new WindException('[Wind.application] ' . get_class($application), - WindException::ERROR_CLASS_TYPE_ERROR); - $rootPath = $rootPath ? self::getRealPath($rootPath, false, true) : (!empty($config['root-path']) ? self::getRealPath( - $config['root-path'], false, true) : dirname($_SERVER['SCRIPT_FILENAME'])); + if (!$application instanceof IWindApplication) throw new WindException( + '[Wind.application] ' . get_class($application), + WindException::ERROR_CLASS_TYPE_ERROR); + $rootPath = $rootPath ? self::getRealPath($rootPath, false, true) : (!empty( + $config['root-path']) ? self::getRealPath($config['root-path'], false, true) : dirname( + $_SERVER['SCRIPT_FILENAME'])); Wind::register($rootPath, $appName, true); self::$_app[$appName] = $application; } @@ -62,8 +65,8 @@ public static function application($appName = 'default', $config = array(), $roo * @return string */ public static function getAppName() { - if (!self::$_currentAppName) - throw new WindException('Get appName failed.', WindException::ERROR_SYSTEM_ERROR); + if (!self::$_currentAppName) throw new WindException('Get appName failed.', + WindException::ERROR_SYSTEM_ERROR); return self::$_currentAppName; //end(self::$_currentApp); } @@ -106,10 +109,8 @@ public static function resetApp() { * @return string|null */ public static function import($filePath, $recursivePackage = false) { - if (!$filePath) - return; - if (isset(self::$_imports[$filePath])) - return self::$_imports[$filePath]; + if (!$filePath) return; + if (isset(self::$_imports[$filePath])) return self::$_imports[$filePath]; if (($pos = strrpos($filePath, '.')) !== false) $fileName = substr($filePath, $pos + 1); elseif (($pos1 = strrpos($filePath, ':')) !== false) @@ -120,219 +121,243 @@ public static function import($filePath, $recursivePackage = false) { if ($isPackage) { $filePath = substr($filePath, 0, $pos); $dirPath = self::getRealPath($filePath, false); - if (!$dh = opendir($dirPath)) - throw new Exception('the file ' . $dirPath . ' open failed!'); + if (!$dh = opendir($dirPath)) throw new Exception( + 'the file ' . $dirPath . ' open failed!'); while (($file = readdir($dh)) !== false) { if (is_dir($dirPath . '/' . $file)) { - if ($recursivePackage && $file !== '.' && $file !== '..' && (strpos($file, '.') !== 0)) { - $_filePath = $filePath . '.' . $file . '.' . '*'; - self::import($_filePath, $recursivePackage); + if ($recursivePackage && $file !== '.' && $file !== '..' && + (strpos($file, '.') !== 0)) { + $_filePath = $filePath . '.' . $file . '.' . '*'; + self::import($_filePath, $recursivePackage); + } + } else { + if (($pos = strrpos($file, '.')) === false) { + $fileName = $file; + } elseif (substr($file, $pos + 1) === self::$_extensions) { + $fileName = substr($file, 0, $pos); + } else + continue; + self::_setImport($fileName, $filePath . '.' . $fileName); } - } else { - if (($pos = strrpos($file, '.')) === false) { - $fileName = $file; - } elseif (substr($file, $pos + 1) === self::$_extensions) { - $fileName = substr($file, 0, $pos); - } else - continue; - self::_setImport($fileName, $filePath . '.' . $fileName); } + closedir($dh); + } else { + self::_setImport($fileName, $filePath); } - closedir($dh); - } else { - self::_setImport($fileName, $filePath); + return $fileName; } - return $fileName; - } - /** - * 将路径信息注册到命名空间,该方法不会覆盖已经定义过的命名空间 - * @param string $path | 需要注册的路径 - * @param string $name | 路径别名 - * @param boolean $includePath | 是否同时定义includePath - * @param boolean $reset | 是否覆盖已经存在的定义,默认false - * @return - */ - public static function register($path, $alias = '', $includePath = false, $reset = false) { - if (!$path) - return; - $alias = strtolower($alias); - if (!empty($alias)) { - if (!isset(self::$_namespace[$alias]) || $reset) - self::$_namespace[$alias] = rtrim($path, '/') . '/'; - } - if ($includePath) { - if (empty(self::$_includePaths)) { - self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); - if (($pos = array_search('.', self::$_includePaths, true)) !== false) - unset(self::$_includePaths[$pos]); + /** + * 将路径信息注册到命名空间,该方法不会覆盖已经定义过的命名空间 + * @param string $path | 需要注册的路径 + * @param string $name | 路径别名 + * @param boolean $includePath | 是否同时定义includePath + * @param boolean $reset | 是否覆盖已经存在的定义,默认false + * @return + */ + public static function register($path, $alias = '', $includePath = false, $reset = false) { + if (!$path) return; + $alias = strtolower($alias); + if (!empty($alias)) { + if (!isset(self::$_namespace[$alias]) || $reset) self::$_namespace[$alias] = rtrim( + $path, '/') . '/'; + } + if ($includePath) { + if (empty(self::$_includePaths)) { + self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path())); + if (($pos = array_search('.', self::$_includePaths, true)) !== false) unset( + self::$_includePaths[$pos]); + } + array_unshift(self::$_includePaths, $path); + if (set_include_path( + '.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) {throw new Exception( + 'set include path error.');} } - array_unshift(self::$_includePaths, $path); - if (set_include_path('.' . PATH_SEPARATOR . implode(PATH_SEPARATOR, self::$_includePaths)) === false) {throw new Exception( - 'set include path error.');} } - } - /** - * 返回命名空间的路径信息 - * @param string $namespace - * @return string|Ambigous - */ - public static function getRootPath($namespace) { - $namespace = strtolower($namespace); - return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; - } + /** + * 返回命名空间的路径信息 + * @param string $namespace + * @return string|Ambigous + */ + public static function getRootPath($namespace) { + $namespace = strtolower($namespace); + return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : ''; + } - /** - * 类文件自动加载方法 callback - * @param string $className - * @param string $path - * @return null - */ - public static function autoLoad($className, $path = '') { - $path || $path = isset(self::$_classes[$className]) ? self::$_classes[$className] : $className; - include $path . '.' . self::$_extensions; - } + /** + * 类文件自动加载方法 callback + * @param string $className + * @param string $path + * @return null + */ + public static function autoLoad($className, $path = '') { + $path || + $path = isset(self::$_classes[$className]) ? self::$_classes[$className] : $className; + include $path . '.' . self::$_extensions; + } - /** - * @param string $key - * @return string|array - */ - public static function getImports($key = '') { - return $key ? self::$_imports[$key] : self::$_imports; - } + /** + * @param string $key + * @return string|array + */ + public static function getImports($key = '') { + return $key ? self::$_imports[$key] : self::$_imports; + } - /** - * 设置imports信息 - * @param array $imports - */ - public static function setImports($imports) { - self::$_imports = array_merge(self::$_imports, $imports); - } + /** + * 设置imports信息 + * @param array $imports + */ + public static function setImports($imports) { + self::$_imports = array_merge(self::$_imports, $imports); + } - /** - * 解析路径信息,并返回路径的详情 - * @param string $filePath 路径信息 - * @param boolean $suffix 是否存在文件后缀true,false,default - * @return string|array('isPackage','fileName','extension','realPath') - */ - public static function getRealPath($filePath, $suffix = '', $absolut = false) { - if (false !== strpos($filePath, DIRECTORY_SEPARATOR)) - return realpath($filePath); - if (false !== ($pos = strpos($filePath, ':'))) { - $namespace = self::getRootPath(substr($filePath, 0, $pos)); - $filePath = substr($filePath, $pos + 1); - } else - $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; - if ($suffix === '') { - $suffix = self::$_extensions; - } elseif ($suffix === true && false !== ($pos = strrpos($filePath, '.'))) { - $suffix = substr($filePath, $pos + 1); - $filePath = substr($filePath, 0, $pos); - } - $filePath = str_replace('.', '/', $filePath); - $namespace && $filePath = $namespace . $filePath; - return $suffix ? $filePath . '.' . $suffix : $filePath; - } + /** + * 解析路径信息,并返回路径的详情 + * @param string $filePath 路径信息 + * @param boolean $suffix 是否存在文件后缀true,false,default + * @return string|array('isPackage','fileName','extension','realPath') + */ + public static function getRealPath($filePath, $suffix = '', $absolut = false) { + if (false !== strpos($filePath, DIRECTORY_SEPARATOR)) return realpath($filePath); + if (false !== ($pos = strpos($filePath, ':'))) { + $namespace = self::getRootPath(substr($filePath, 0, $pos)); + $filePath = substr($filePath, $pos + 1); + } else + $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; + if ($suffix === '') { + $suffix = self::$_extensions; + } elseif ($suffix === true && false !== ($pos = strrpos($filePath, '.'))) { + $suffix = substr($filePath, $pos + 1); + $filePath = substr($filePath, 0, $pos); + } + $filePath = str_replace('.', '/', $filePath); + $namespace && $filePath = $namespace . $filePath; + return $suffix ? $filePath . '.' . $suffix : $filePath; + } - /** - * 解析路径信息,并返回路径的详情 - * @param string $filePath 路径信息 - * @param boolean $absolut 是否返回绝对路径 - * @return string|array('isPackage','fileName','extension','realPath') - */ - public static function getRealDir($dirPath, $absolut = false) { - if (false !== ($pos = strpos($dirPath, ':'))) { - $namespace = self::getRootPath(substr($dirPath, 0, $pos)); - $dirPath = substr($dirPath, $pos + 1); - } else - $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; - $namespace && $dirPath = $namespace . str_replace('.', '/', $dirPath); - return $dirPath; - } + /** + * 解析路径信息,并返回路径的详情 + * @param string $filePath 路径信息 + * @param boolean $absolut 是否返回绝对路径 + * @return string|array('isPackage','fileName','extension','realPath') + */ + public static function getRealDir($dirPath, $absolut = false) { + if (false !== ($pos = strpos($dirPath, ':'))) { + $namespace = self::getRootPath(substr($dirPath, 0, $pos)); + $dirPath = substr($dirPath, $pos + 1); + } else + $namespace = $absolut ? self::getRootPath(self::getAppName()) : ''; + $namespace && $dirPath = $namespace . str_replace('.', '/', $dirPath); + return $dirPath; + } - /** - * 初始化框架 - */ - public static function init() { - function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0'); - self::register(WIND_PATH, 'WIND', true); - - if (!self::$_isAutoLoad) - return; - if (function_exists('spl_autoload_register')) - spl_autoload_register('Wind::autoLoad'); - else - self::$_isAutoLoad = false; - self::_loadBaseLib(); - } + /** + * 初始化框架 + */ + public static function init() { + function_exists('date_default_timezone_set') && + date_default_timezone_set('Etc/GMT+0'); + self::register(WIND_PATH, 'WIND', true); + + if (!self::$_isAutoLoad) return; + if (function_exists('spl_autoload_register')) + spl_autoload_register('Wind::autoLoad'); + else + self::$_isAutoLoad = false; + self::_loadBaseLib(); + } - /** - * 清理Wind import变量信息 - * @return - */ - public static function clear() { - self::$_imports = array(); - self::$_classes = array(); - } + /** + * 清理Wind import变量信息 + * @return + */ + public static function clear() { + self::$_imports = array(); + self::$_classes = array(); + } - /** - * @return - */ - protected static function beforRun($appName, $config, $rootPath) { - if (!$appName || in_array($appName, self::$_currentApp)) - throw new WindException('Nested request', WindException::ERROR_SYSTEM_ERROR); - array_push(self::$_currentApp, $appName); - self::$_currentAppName = $appName; - } + /** + * @return + */ + protected static function beforRun($appName, $config, $rootPath) { + if (!$appName || in_array($appName, self::$_currentApp)) throw new WindException( + 'Nested request', WindException::ERROR_SYSTEM_ERROR); + array_push(self::$_currentApp, $appName); + self::$_currentAppName = $appName; + } - /** - * @param string $className - * @param string $classPath - * @return - */ - private static function _setImport($className, $classPath) { - self::$_imports[$classPath] = $className; - if (!isset(self::$_classes[$className])) { - $_classPath = self::getRealPath($classPath, false); - self::$_classes[$className] = $_classPath; - } else - $_classPath = self::$_classes[$className]; - if (!self::$_isAutoLoad) - self::autoLoad($className, $_classPath); - } + /** + * @param string $className + * @param string $classPath + * @return + */ + private static function _setImport($className, $classPath) { + self::$_imports[$classPath] = $className; + if (!isset(self::$_classes[$className])) { + $_classPath = self::getRealPath($classPath, false); + self::$_classes[$className] = $_classPath; + } else + $_classPath = self::$_classes[$className]; + if (!self::$_isAutoLoad) self::autoLoad($className, $_classPath); + } - /** - * 加载核心层库函数 - * @return - */ - private static function _loadBaseLib() { - self::$_classes = array('IWindApplication' => 'base/IWindApplication', 'IWindFactory' => 'base/IWindFactory', - 'WindActionException' => 'base/WindActionException', 'WindClassProxy' => 'base/WindClassProxy', - 'WindEnableValidateModule' => 'base/WindEnableValidateModule', 'WindErrorMessage' => 'base/WindErrorMessage', - 'WindException' => 'base/WindException', 'WindFactory' => 'base/WindFactory', - 'WindFinalException' => 'base/WindFinalException', 'WindHelper' => 'base/WindHelper', - 'WindModule' => 'base/WindModule', 'WindActionFilter' => 'filter/WindActionFilter', - 'WindFilter' => 'filter/WindFilter', 'WindFilterChain' => 'filter/WindFilterChain', - 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', - 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', - 'WindUrlFilter' => 'web/filter/WindUrlFilter', 'WindFormListener' => 'web/listener/WindFormListener', - 'WindValidateListener' => 'web/listener/WindValidateListener', 'WindController' => 'web/WindController', - 'WindDispatcher' => 'web/WindDispatcher', 'WindErrorHandler' => 'web/WindErrorHandler', - 'WindForward' => 'web/WindForward', 'WindSimpleController' => 'web/WindSimpleController', - 'WindSystemConfig' => 'web/WindSystemConfig', 'WindUrlHelper' => 'web/WindUrlHelper', - 'WindWebApplication' => 'web/WindWebApplication', 'AbstractWindRouter' => 'router/AbstractWindRouter', - 'AbstractWindRoute' => 'router/route/AbstractWindRoute', - 'WindRewriteRoute' => 'router/route/WindRewriteRoute', 'WindRoute' => 'router/route/WindRoute', - 'WindRouter' => 'router/WindRouter', 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter', - 'IWindRequest' => 'http/request/IWindRequest', 'WindHttpRequest' => 'http/request/WindHttpRequest', - 'IWindResponse' => 'http/response/IWindResponse', 'WindHttpResponse' => 'http/response/WindHttpResponse', - 'WindDate' => 'utility/date/WindDate', 'WindGeneralDate' => 'utility/date/WindGeneralDate', - 'WindDecoder' => 'utility/json/WindDecoder', 'WindEncoder' => 'utility/json/WindEncoder', - 'WindArray' => 'utility/WindArray', 'WindFile' => 'utility/WindFile', 'WindImage' => 'utility/WindImage', - 'WindPack' => 'utility/WindPack', 'WindSecurity' => 'utility/WindSecurity', - 'WindString' => 'utility/WindString', 'WindUtility' => 'utility/WindUtility', - 'WindValidator' => 'utility/WindValidator'); - } -} -Wind::init(); \ No newline at end of file + /** + * 加载核心层库函数 + * @return + */ + private static function _loadBaseLib() { + self::$_classes = array( + 'IWindApplication' => 'base/IWindApplication', + 'IWindFactory' => 'base/IWindFactory', + 'WindActionException' => 'base/WindActionException', + 'WindClassProxy' => 'base/WindClassProxy', + 'WindEnableValidateModule' => 'base/WindEnableValidateModule', + 'WindErrorMessage' => 'base/WindErrorMessage', + 'WindException' => 'base/WindException', + 'WindFactory' => 'base/WindFactory', + 'WindFinalException' => 'base/WindFinalException', + 'WindHelper' => 'base/WindHelper', + 'WindModule' => 'base/WindModule', + 'WindActionFilter' => 'filter/WindActionFilter', + 'WindFilter' => 'filter/WindFilter', + 'WindFilterChain' => 'filter/WindFilterChain', + 'WindHandlerInterceptor' => 'filter/WindHandlerInterceptor', + 'WindHandlerInterceptorChain' => 'filter/WindHandlerInterceptorChain', + 'WindUrlFilter' => 'web/filter/WindUrlFilter', + 'WindFormListener' => 'web/listener/WindFormListener', + 'WindValidateListener' => 'web/listener/WindValidateListener', + 'WindController' => 'web/WindController', + 'WindDispatcher' => 'web/WindDispatcher', + 'WindErrorHandler' => 'web/WindErrorHandler', + 'WindForward' => 'web/WindForward', + 'WindSimpleController' => 'web/WindSimpleController', + 'WindSystemConfig' => 'web/WindSystemConfig', + 'WindUrlHelper' => 'web/WindUrlHelper', + 'WindWebApplication' => 'web/WindWebApplication', + 'AbstractWindRouter' => 'router/AbstractWindRouter', + 'AbstractWindRoute' => 'router/route/AbstractWindRoute', + 'WindRewriteRoute' => 'router/route/WindRewriteRoute', + 'WindRoute' => 'router/route/WindRoute', + 'WindRouter' => 'router/WindRouter', + 'WindUrlRewriteRouter' => 'router/WindUrlRewriteRouter', + 'IWindRequest' => 'http/request/IWindRequest', + 'WindHttpRequest' => 'http/request/WindHttpRequest', + 'IWindResponse' => 'http/response/IWindResponse', + 'WindHttpResponse' => 'http/response/WindHttpResponse', + 'WindDate' => 'utility/date/WindDate', + 'WindGeneralDate' => 'utility/date/WindGeneralDate', + 'WindDecoder' => 'utility/json/WindDecoder', + 'WindEncoder' => 'utility/json/WindEncoder', + 'WindArray' => 'utility/WindArray', + 'WindFile' => 'utility/WindFile', + 'WindImage' => 'utility/WindImage', + 'WindPack' => 'utility/WindPack', + 'WindSecurity' => 'utility/WindSecurity', + 'WindString' => 'utility/WindString', + 'WindUtility' => 'utility/WindUtility', + 'WindValidator' => 'utility/WindValidator'); + } + } + Wind::init(); \ No newline at end of file From 26077e9b524799d12a30d0fb8011d761e1a52110 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 06:34:51 +0000 Subject: [PATCH 0565/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2637 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/db/WindSqlStatement.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wind/db/WindSqlStatement.php b/wind/db/WindSqlStatement.php index 73806fe4..9dd6810d 100644 --- a/wind/db/WindSqlStatement.php +++ b/wind/db/WindSqlStatement.php @@ -268,15 +268,15 @@ public function lastInsertId($name = '') { public function execute($params = array(), $rowCount = true) { try { if (WIND_DEBUG & 2) - Wind::getApp()->getComponent('windLogger')->profileBegin('SQL:execute sql statement.', 'component.db'); + Wind::getApp()->getComponent('windLogger')->profileBegin('SQL:execute sql statement.', 'db'); $this->init(); $this->bindValues($params); $this->getStatement()->execute(); $_result = $rowCount ? $this->getStatement()->rowCount() : true; if (WIND_DEBUG & 2) { - Wind::getApp()->getComponent('windLogger')->profileEnd('SQL:execute sql statement.', 'component.db'); + Wind::getApp()->getComponent('windLogger')->profileEnd('SQL:execute sql statement.', 'db'); Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindSqlStatement.execute] \r\n\tSQL:" . $this->getQueryString(), 'component.db'); + "[component.db.WindSqlStatement.execute] \r\n\tSQL:" . $this->getQueryString(), 'db'); } return $_result; } catch (PDOException $e) { @@ -329,7 +329,7 @@ public function init() { $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString()); if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info( - "[component.db.WindSqlStatement.init] Initialize statement success.", 'component.db'); + "[component.db.WindSqlStatement.init] Initialize statement success.", 'db'); } catch (PDOException $e) { throw new WindDbException("Initialization WindSqlStatement failed." . $e->getMessage()); } From 6162954c2b0d8e71420a2b9ecfb89a534924a6e1 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 06:35:19 +0000 Subject: [PATCH 0566/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2638 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/base/WindFactory.php | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/wind/base/WindFactory.php b/wind/base/WindFactory.php index 1d0b477d..0b965be7 100644 --- a/wind/base/WindFactory.php +++ b/wind/base/WindFactory.php @@ -44,14 +44,8 @@ public function getInstance($alias, $args = array()) { } else { if (!$definition) throw new WindException('[factory.WindFactory.getInstance] component \'' . $alias . '\' is not exist.'); - - if (isset($definition['constructor-arg'])) - foreach ((array) $definition['constructor-arg'] as $_var) { - if (isset($_var['value'])) { - $args[] = $_var['value']; - } elseif (isset($_var['ref'])) - $args[] = $this->getInstance($_var['ref']); - } + if (isset($definition['constructor-args']) && !$args) + $this->buildArgs($definition['constructor-args'], $args); if (!isset($definition['className'])) $definition['className'] = Wind::import(@$definition['path']); $instance = $this->createInstance($definition['className'], $args); @@ -167,6 +161,25 @@ public function executeDestroyMethod() { } } + /** + * @param $constructors + * @param args + */ + protected function buildArgs($constructors, &$args) { + foreach ((array) $constructors as $key => $_var) { + $key = intval($key); + if (isset($_var['value'])) { + $args[$key] = $_var['value']; + } elseif (isset($_var['ref'])) + $args[$key] = $this->getInstance($_var['ref']); + elseif (isset($_var['path'])) { + $_className = Wind::import($_var['path']); + $args[$key] = $this->createInstance($_className); + } + } + ksort($args); + } + /** * @param string $alias * @param string $scope From 43ff477d96fd754af2354bfa0d8a41b74a14bd99 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 08:54:36 +0000 Subject: [PATCH 0567/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2639 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/AbstractWindRouter.php | 15 ++++++++------- wind/router/WindRouter.php | 10 +++++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php index 166e0d95..f1bd52da 100644 --- a/wind/router/AbstractWindRouter.php +++ b/wind/router/AbstractWindRouter.php @@ -10,7 +10,6 @@ * @package */ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { - protected $defaultRoute = 'WIND:router.route.WindRoute'; protected $moduleKey = 'm'; protected $controllerKey = 'c'; protected $actionKey = 'a'; @@ -18,6 +17,8 @@ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $controller = 'index'; protected $action = 'run'; protected $reverse = "%s?m=%s&c=%s&a=%s&"; + + protected $currentRoute = ''; /** * 解析请求参数,并返回路由结果 @@ -44,10 +45,10 @@ public function setConfig($config) { $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey); $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey); foreach ($this->getConfig('routes', '', array()) as $routeName => $route) { - $class = isset($route['class']) ? $route['class'] : $this->defaultRoute; - $instance = $this->getSystemFactory()->createInstance(Wind::import($class)); + if (!isset($route['class'])) continue; + $instance = $this->getSystemFactory()->createInstance(Wind::import($route['class'])); $instance->setConfig($route); - $this->addRoute($routeName, $instance); + $this->addRoute($routeName, $instance, (isset($route['current']) && $route['current'] === 'true')); } } } @@ -59,8 +60,7 @@ public function setConfig($config) { protected function setParams($params) { foreach ($params as $key => $value) { $this->getRequest()->setAttribute($value, $key); - if (!$value) - continue; + if (!$value) continue; if ($this->actionKey === $key) $this->setAction($value); elseif ($this->controllerKey === $key) @@ -77,8 +77,9 @@ protected function setParams($params) { * @throws WindException * @return */ - public function addRoute($alias, $route) { + public function addRoute($alias, $route, $current = false) { $this->addInterceptors(array($alias => $route)); + if ($current) $this->currentRoute = $alias; } /** diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index e96a6f88..8b5dfd4d 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -21,17 +21,17 @@ public function route() { * @see AbstractWindRouter::assemble() */ public function assemble($action, $args = array(), $route = null) { - $route || $route = current($this->_interceptors); - if ($route) + $route || $route = $this->currentRoute; + if ($route && (null !== $route = $this->getRoute($route))) { $_url = $route->build($this, $action, $args); - else { + } else { list($_a, $_c, $_m, $args) = WindUrlHelper::resolveAction($action, $args); - $_baseUrl = $this->getRequest()->getBaseUrl(true) . '/' . $this->getRequest()->getScript(); + $_baseUrl = $this->getRequest()->getScript(); $_url = sprintf($this->reverse, $_baseUrl, ($_m ? $_m : $this->module), ($_c ? $_c : $this->controller), ($_a ? $_a : $this->action)); $_url .= WindUrlHelper::argsToUrl($args); } - return WindUrlHelper::checkUrl($_url); + return $_url; } /** From 84cfee5c7c3bc40c341caa08abc827151badb1d2 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 08:54:47 +0000 Subject: [PATCH 0568/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2640 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/http/session/WindSession.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/wind/http/session/WindSession.php b/wind/http/session/WindSession.php index 4f0d8302..37dad5e5 100644 --- a/wind/http/session/WindSession.php +++ b/wind/http/session/WindSession.php @@ -78,7 +78,6 @@ public function set($key, $value) { * @return mixed */ public function get($key) { - var_dump(session_is_registered($key)); return $this->isRegistered($key) ? $_SESSION[$key] : ''; } @@ -151,13 +150,14 @@ public function commit() { * @param AbstractWindCache $handler * @param WindSessionHandler $sessionHandler */ - public function setDataStoreHandler($dataStoreHandler, $sessionHandler) { - if (!$dataStoreHandler) return; - if ($sessionHandler === null) { - Wind::import('WIND:http.session.handler.WindSessionHandler'); - $sessionHandler = new WindSessionHandler(); + public function setDataStoreHandler($dataStoreHandler, $sessionHandler = null) { + if ($dataStoreHandler) { + if ($sessionHandler === null) { + Wind::import('WIND:http.session.handler.WindSessionHandler'); + $sessionHandler = new WindSessionHandler(); + } + $sessionHandler->registerHandler($dataStoreHandler); } - $sessionHandler->registerHandler($dataStoreHandler); $this->start(); } } From 36560119de130630f8076bda163c883548cbe6bb Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 08:54:59 +0000 Subject: [PATCH 0569/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2641 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/WindDispatcher.php | 18 +++++++++--------- wind/web/WindUrlHelper.php | 28 +++++++++++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/wind/web/WindDispatcher.php b/wind/web/WindDispatcher.php index 9e5e00b1..15f0eb7f 100644 --- a/wind/web/WindDispatcher.php +++ b/wind/web/WindDispatcher.php @@ -50,8 +50,10 @@ public function dispatch($forward, $router, $display) { * @return */ protected function dispatchWithRedirect($forward, $router) { - if (!($_url = $forward->getUrl())) + if (!($_url = $forward->getUrl())) { $_url = $router->assemble($forward->getAction(), $forward->getArgs()); + } + $_url = WindUrlHelper::checkUrl($_url, true); $this->getResponse()->sendRedirect($_url); } @@ -64,19 +66,17 @@ protected function dispatchWithRedirect($forward, $router) { * @return */ protected function dispatchWithAction($forward, $router, $display) { - if (!$action = $forward->getAction()) - throw new WindException('[web.WindDispatcher.dispatchWithAction] forward fail.', - WindException::ERROR_PARAMETER_TYPE_ERROR); + if (!$action = $forward->getAction()) throw new WindException( + '[web.WindDispatcher.dispatchWithAction] forward fail.', WindException::ERROR_PARAMETER_TYPE_ERROR); $this->display = $display; list($_a, $_c, $_m) = WindUrlHelper::resolveAction($action); - if ($_var = $forward->getVars()) - $this->getResponse()->setData($_var, 'F'); + if ($_var = $forward->getVars()) $this->getResponse()->setData($_var, 'F'); $_a && $router->setAction($_a); $_c && $router->setController($_c); $_m && $router->setModule($_m); - if ($this->checkToken($router)) - throw new WindFinalException('[web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, - WindException::ERROR_SYSTEM_ERROR); + if ($this->checkToken($router)) throw new WindFinalException( + '[web.WindDispatcher.dispatchWithRedirect] Duplicate request: ' . $this->token, + WindException::ERROR_SYSTEM_ERROR); Wind::getApp()->processRequest(); } diff --git a/wind/web/WindUrlHelper.php b/wind/web/WindUrlHelper.php index 52b5213a..aa1c8631 100644 --- a/wind/web/WindUrlHelper.php +++ b/wind/web/WindUrlHelper.php @@ -10,9 +10,18 @@ class WindUrlHelper { /** * @param string $url + * @param boolean $absolute * @return string */ - public static function checkUrl($url) { + public static function checkUrl($url, $absolute = true) { + if ($absolute) { + $_baseUrl = $absolute === true ? Wind::getApp()->getRequest()->getBaseUrl(true) : $absolute; + if (strpos($url, '://') === false) { + $url = $_baseUrl . '/' . trim($url, '/'); + } else { + $url = preg_replace('/http[s]{0,1}:\/\/[a-zA-Z0-9\.\-]+\.[a-zA-Z]{2,4}(:\d+)?/i', $_baseUrl, $url); + } + } return $url; } @@ -33,8 +42,7 @@ public static function urlToArgs($url, $decode = true, $separator = '&=') { $url = explode($_sep1, trim($url, $_sep1) . $_sep1); $args = array(); for ($i = 0; $i < count($url); $i = $i + 2) { - if (!isset($url[$i]) || !isset($url[$i + 1])) - continue; + if (!isset($url[$i]) || !isset($url[$i + 1])) continue; $_v = $decode ? urldecode($url[$i + 1]) : $url[$i + 1]; $_k = $url[$i]; if (strpos($_k, self::$_sep) === 0) { @@ -49,6 +57,8 @@ public static function urlToArgs($url, $decode = true, $separator = '&=') { /** * 将数组格式的参数列表转换为Url格式,并将url进行编码处理 * @param array $args + * @param boolean $encode + * @param string $separator * @return string */ public static function argsToUrl($args, $encode = true, $separator = '&=') { @@ -58,7 +68,7 @@ public static function argsToUrl($args, $encode = true, $separator = '&=') { !$_sep2 && $_sep2 = $_sep1; $_tmp = ''; foreach ((array) $args as $key => $value) { - if (is_array($value)) + if (is_array($value) || is_object($value)) $_tmp .= self::$_sep . "$key" . $_sep2 . urlencode(serialize($value)); else $_tmp .= "$key" . $_sep2 . urlencode($value); @@ -73,6 +83,7 @@ public static function argsToUrl($args, $encode = true, $separator = '&=') { * 返回解析后的controller信息,controller,module,app * * @param string $controllerPath + * @param array $args * @return array */ public static function resolveAction($action, $args = array()) { @@ -88,13 +99,16 @@ public static function resolveAction($action, $args = array()) { * 将根据是否开启url重写来分别构造相对应的url * @param string $action 执行的操作 * @param array $args 附带的参数 - * @param AbstractWindRoute $route + * @param string $anchor + * @param AbstractWindRoute $route + * @param boolean $absolute * @return string */ - public static function createUrl($action, $args = array(), $anchor = '', $route = null) { + public static function createUrl($action, $args = array(), $anchor = '', $route = null, $absolute = true) { /* @var $router AbstractWindRouter */ $router = Wind::getApp()->getComponent('router'); - return $router->assemble($action, $args, $route) . ($anchor ? '#' . $anchor : ''); + $url = $router->assemble($action, $args, $route) . ($anchor ? '#' . $anchor : ''); + return self::checkUrl($url, $absolute); } } ?> \ No newline at end of file From 52527fea66020332294b4763e815eaf3dfa82c10 Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 08:57:54 +0000 Subject: [PATCH 0570/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2642 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/cache/AbstractWindCache.php | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/wind/cache/AbstractWindCache.php b/wind/cache/AbstractWindCache.php index 0cab6cf4..51b494aa 100644 --- a/wind/cache/AbstractWindCache.php +++ b/wind/cache/AbstractWindCache.php @@ -79,11 +79,11 @@ protected abstract function deleteValue($key); /** * 清楚缓存,过期及所有缓存 - * + * 默认为true,只清理过期或者散落的数据 * @param boolean $expireOnly 如果为true则仅仅只删除过期的数据 * @return */ - public abstract function clear($expireOnly = false); + public abstract function clear($expireOnly = true); /** * 设置缓存,如果key不存在,设置缓存,否则,替换已有key的缓存。 @@ -93,13 +93,18 @@ public abstract function clear($expireOnly = false); * @param IWindCacheDependency $denpendency 缓存依赖 * @return boolean */ - public function set($key, $value, $expires = 0, AbstractWindCacheDependency $denpendency = null) { + public function set($key, $value, $expires = 0, AbstractWindCacheDependency $dependency = null) { try { - $data = array(self::DATA => $value, self::EXPIRE => $expires ? $expires : $this->getExpire(), self::STORETIME => time(), self::DEPENDENCY => null, self::DEPENDENCYCLASS => ''); - if (null != $denpendency) { - $denpendency->injectDependent(); - $data[self::DEPENDENCY] = serialize($denpendency); - $data[self::DEPENDENCYCLASS] = get_class($denpendency); + $data = array( + self::DATA => $value, + self::EXPIRE => $expires ? $expires : $this->getExpire(), + self::STORETIME => time(), + self::DEPENDENCY => null, + self::DEPENDENCYCLASS => ''); + if (null != $dependency) { + $dependency->injectDependent(); + $data[self::DEPENDENCY] = serialize($dependency); + $data[self::DEPENDENCYCLASS] = get_class($dependency); } return $this->setValue($this->buildSecurityKey($key), serialize($data), $data[self::EXPIRE]); } catch (Exception $e) { @@ -198,7 +203,9 @@ protected function hasChanged($key, array $data) { * @return string */ protected function buildSecurityKey($key) { - return md5($this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key . $this->getSecurityCode() : $key . $this->getSecurityCode()); + return md5( + $this->getKeyPrefix() ? $this->getKeyPrefix() . '_' . $key . $this->getSecurityCode() : $key . + $this->getSecurityCode()); } /** From 40924e749ecb656961205ad589b676ec250bbfbd Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 09:01:15 +0000 Subject: [PATCH 0571/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2643 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/router/AbstractWindRouter.php | 8 ++++---- wind/router/WindRouter.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php index f1bd52da..2b003a8f 100644 --- a/wind/router/AbstractWindRouter.php +++ b/wind/router/AbstractWindRouter.php @@ -18,7 +18,7 @@ abstract class AbstractWindRouter extends WindHandlerInterceptorChain { protected $action = 'run'; protected $reverse = "%s?m=%s&c=%s&a=%s&"; - protected $currentRoute = ''; + protected $defaultRoute = ''; /** * 解析请求参数,并返回路由结果 @@ -48,7 +48,7 @@ public function setConfig($config) { if (!isset($route['class'])) continue; $instance = $this->getSystemFactory()->createInstance(Wind::import($route['class'])); $instance->setConfig($route); - $this->addRoute($routeName, $instance, (isset($route['current']) && $route['current'] === 'true')); + $this->addRoute($routeName, $instance, (isset($route['default']) && $route['default'] === 'true')); } } } @@ -77,9 +77,9 @@ protected function setParams($params) { * @throws WindException * @return */ - public function addRoute($alias, $route, $current = false) { + public function addRoute($alias, $route, $default = false) { $this->addInterceptors(array($alias => $route)); - if ($current) $this->currentRoute = $alias; + if ($default) $this->defaultRoute = $alias; } /** diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php index 8b5dfd4d..6da6a824 100644 --- a/wind/router/WindRouter.php +++ b/wind/router/WindRouter.php @@ -21,7 +21,7 @@ public function route() { * @see AbstractWindRouter::assemble() */ public function assemble($action, $args = array(), $route = null) { - $route || $route = $this->currentRoute; + $route || $route = $this->defaultRoute; if ($route && (null !== $route = $this->getRoute($route))) { $_url = $route->build($this, $action, $args); } else { From 70a02f2552a53ba6c8fdb838e14566dfd965a63f Mon Sep 17 00:00:00 2001 From: yishuo Date: Tue, 13 Sep 2011 09:24:47 +0000 Subject: [PATCH 0572/1065] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.simba.taobao.com/svn/PW_WindFramework/laboratory/trunk@2644 18ba2127-5a84-46d4-baec-3457e417f034 --- wind/web/view/404.htm | 7 +- wind/web/view/error.htm | 10 +-- wind/web/view/erroraction.htm | 50 ++++---------- wind/web/view/style.htm | 124 ++++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 46 deletions(-) create mode 100644 wind/web/view/style.htm diff --git a/wind/web/view/404.htm b/wind/web/view/404.htm index e5626d85..47203879 100644 --- a/wind/web/view/404.htm +++ b/wind/web/view/404.htm @@ -1,7 +1,6 @@ - 404 Not Found +